GoogleChrome/rendertron

Name: rendertron

Owner: GoogleChrome

Description: A dockerized, headless Chrome rendering solution

Created: 2017-03-23 22:28:37.0

Updated: 2018-01-17 20:35:39.0

Pushed: 2018-01-08 21:25:33.0

Homepage: https://render-tron.appspot.com/

Size: 13784

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Rendertron Build status NPM rendertron package

Rendertron is a dockerized, headless Chrome rendering solution designed to render & serialise web pages on the fly.

Rendertron is designed to enable your Progressive Web App (PWA) to serve the correct content to any bot that doesn't render or execute JavaScript. Rendertron runs as a standalone HTTP server. Rendertron renders requested pages using Headless Chrome, auto-detecting when your PWA has completed loading and serializes the response back to the original request. To use Rendertron, your application configures middleware to determine whether to proxy a request to Rendertron. Rendertron is compatible with all client side technologies, including web components.

Demo endpoint

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.

Contents
Middleware

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:

Rendertron is also compatible with prerender.io middleware. Note: the user agent lists differ there.

API
Render
der/<url>

The render endpoint will render your page and serialize your page. Available options:

Screenshot
eenshot/<url>

The screenshot endpoint can be used to verify that your page is rendering correctly. Available options:

FAQ
Query parameters

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 page=home:

s://render-tron.appspot.com/render/http://my.domain/%3Fpage%3Dhome
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:

ipt>
ndow.renderComplete = false;
ript>

When rendering is complete, set the flag to true:

ndow.renderComplete = true;
Web components

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 dom=shady when directing requests to the Rendertron service.

If you are using web components v1 and either webcomponents-lite.js or webcomponents-loader.js, 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

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.

a name="render:status_code" content="404" />
Running locally

To install Rendertron and run it locally, first install Rendertron:

install -g rendertron

With Chrome installed on your machine run the Rendertron CLI:

ertron
Installing & deploying
Dependencies

This project requires Node 7+ and Docker (installation instructions). For deployment this project uses the Google Cloud Platform SDK.

Building from source

Clone and install dependencies:

clone https://github.com/GoogleChrome/rendertron.git
endertron
install
Running locally

With a local instance of Chrome installed, you can start the server locally:

run start
Using the Docker image

After installing docker, build and run the docker image

er build -t rendertron . --no-cache=true
er run -it -p 8080:8080 --name rendertron-container rendertron

Load the homepage in any browser:

://localhost:8080/

Stop the container:

er kill rendertron-container

Clear containers:

er 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:

  1. [Recommended] - Use Jessie Frazelle' seccomp profile and -security-opt flag
  2. Utilize the --cap-add SYS_ADMIN flag

[Recommended] Start a container with the built image using Jessie Frazelle' seccomp profile for Chrome:

 https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -O ~/chrome.json
er 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:

er run -it -p 8080:8080 --cap-add SYS_ADMIN --name rendertron-container rendertron

To check if your kernel is compatible with Docker, follow Docker's instructions. For CentOS 7, which doesn't have user namespaces enabled, you will need to enable them.

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.

er 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
ud app deploy app.yaml --project <your-project-id>
Config

When deploying the service, set configuration variables by including a config.json in the root. Available configuration options:


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.