Rendertron is a dockerized, headless Chrome rendering solution designed to render & serialise web pages on the fly.
A demo Rendertron service is available at https://render-tron.appspot.com/. It is not designed to be used as a production endpoint. You can use it, but there are no uptime guarantees.
- Installing & deploying
Once you have the service up and running, you'll need to implement the differential serving layer. This checks the user agent to determine whether prerendering is required.
This is a list of middleware available to use with the Rendertron service:
- Express.js middleware
- Firebase functions (Community maintained)
- ASP.net core middleware (Community maintained)
Rendertron is also compatible with prerender.io middleware. Note: the user agent lists differ there.
render endpoint will render your page and serialize your page. Available options:
false- used to correctly render Web Components v1. See Using with web components for more information.
screenshot endpoint can be used to verify that your page is rendering correctly.
1000- used to set the viewport width (max 2000)
1000- used to set the viewport height (max 2000)
When setting query parameters as part of your URL, ensure they are encoded correctly. In JS,
this would be
encodeURIComponent(myURLWithParams). For example to specify
Auto detecting loading function
The service detects when a page has loaded by looking at the page load event, ensuring there are no outstanding network requests and that the page has had ample time to render.
Rendering budget timeout
There is a hard limit of 10 seconds for rendering. Ensure you don't hit this budget by ensuring your application is rendered well before the budget expires.
Explicit rendering flag
In some cases, the auto loading function may be insufficient, for example if there is content
being streamed on the page. To explicitly signal when the page is visually complete, set the
window.renderComplete flag. Add this script in your initial response:
<script> window.renderComplete = false; </script>
When rendering is complete, set the flag to
window.renderComplete = true;
Headless Chrome supports web components but shadow DOM is difficult to serialize effectively. As such, shady DOM (a lightweight shim for Shadow DOM) is required for web components.
If you are using web components v0 (deprecated), you will need to enable Shady DOM to
render correctly. In Polymer 1.x, which uses web components v0, Shady DOM is enabled by default.
If you are using Shadow DOM, override this by setting the query parameter
directing requests to the Rendertron service.
If you are using web components v1 and either
set the query parameter
wc-inject-shadydom=true when directing requests to the Rendertron
service. This renderer service will force the necessary polyfills to be loaded and enabled.
Status codes from the initial requested URL are preserved. If this is a 200, or 304, you can set the HTTP status returned by the rendering service by adding a meta tag.
<meta name="render:status_code" content="404" />
To install Rendertron and run it locally, first install Rendertron:
npm install -g rendertron
With Chrome installed on your machine run the Rendertron CLI:
Installing & deploying
Building from source
Clone and install dependencies:
git clone https://github.com/GoogleChrome/rendertron.git cd rendertron npm install
With a local instance of Chrome installed, you can start the server locally:
npm run start
Using the Docker image
After installing docker, build and run the docker image
docker build -t rendertron . --no-cache=true docker run -it -p 8080:8080 --name rendertron-container rendertron
Load the homepage in any browser:
Stop the container:
docker kill rendertron-container
docker rm -f $(docker ps -a -q)
Connection error (ECONNREFUSED)
In the case where your kernel lacks user namespace support or are receiving a
ECONNREFUSED error when trying to access the service in the container (as noted in issues 2 and 3), the two recommended methods below should solve this:
- [Recommended] - Use Jessie Frazelle' seccomp profile and
- Utilize the
[Recommended] Start a container with the built image using Jessie Frazelle' seccomp profile for Chrome:
wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -O ~/chrome.json docker run -it -p 8080:8080 --security-opt seccomp=$HOME/chrome.json --name rendertron-container rendertron
Start a container with the built image using SYS_ADMIN:
docker run -it -p 8080:8080 --cap-add SYS_ADMIN --name rendertron-container rendertron
Chrome crashes due to low shared memory
By default the size of /dev/shm in Docker is 64mb, which may result in Chrome crashes. To increase the size of /dev/shm you can specify the size to Docker when running the image.
docker run ... --shm-size=256m
In the future, it will be possible to using /tmp instead of /dev/shm. See the Chromium bug for more detail.
Deploying to Google Cloud Platform
gcloud app deploy app.yaml --project <your-project-id>
When deploying the service, set configuration variables by including a
config.json in the
root. Available configuration options:
""- set to a Google Analytics property tracking id to send Rendertron rendering events to analytics.
false- set to
trueto enable caching on Google Cloud using datastore
false- set to
trueto log requested renders & pipe console messages from within the rendered pages.
renderOnly- restrict the endpoint to only service requests for certain domains. Specified as an array of strings. eg.
['http://render.only.this.domain']. This is a strict prefix match, so ensure you specify the exact protocols that will be used (eg. http, https).