Developer Guide
Relevant source files
The following files were used as context for generating this wiki page:
Rendertron is a headless Chrome rendering solution designed to render and serialize web pages on the fly. Built with Puppeteer, it runs as a standalone Koa HTTP server, making it a powerful tool for serving pre-rendered content to bots and crawlers that do not execute JavaScript. This improves SEO for Progressive Web Apps (PWAs) and other modern web applications.
This guide provides a technical overview of the Rendertron architecture, setup, configuration, and API. It is intended for developers who want to contribute to the project, or run and maintain their own instance of the service. The system is designed to be extensible, with support for middleware to integrate with various backend frameworks like Express.js.
Sources: README.md, src/rendertron.ts, middleware/README.md
Architecture Overview
Rendertron's architecture consists of a Koa.js server that exposes rendering and screenshotting endpoints. These endpoints are handled by the Rendertron class, which orchestrates requests. The core rendering logic is encapsulated within the Renderer class, which uses Puppeteer to control a headless Chrome instance. The service can also be configured to use Google Datastore for caching rendered responses.
Sources: src/rendertron.ts:15-21, src/renderer.ts:18-24
The following diagram illustrates the high-level component architecture of the Rendertron service.
Sources: src/rendertron.ts, src/renderer.ts
Project Setup and Scripts
The project is managed with npm and written in TypeScript. Key dependencies include puppeteer, koa, and typescript.
Sources: package.json:30-46
Installation and Building
To get started, clone the repository and install the dependencies. The project is then built by compiling the TypeScript source code into JavaScript.
- Clone repository:
git clone https://github.com/GoogleChrome/rendertron.git - Install dependencies:
npm install - Build the project:
npm run build
Sources: README.md:112-116
Key NPM Scripts
The package.json file defines several scripts for common development tasks.
| Script | Description |
|---|---|
build | Compiles TypeScript source files to the build/ directory. |
start | Starts the Rendertron server from the compiled build files. |
monitor | Runs the server using nodemon for automatic restarts on file changes during development. |
lint | Lints the TypeScript code using tslint. |
test | Runs the application test suite (app-test.js) using ava. |
test-cache | Runs the Datastore cache tests. Requires Google Cloud emulators. |
Sources: package.json:12-22
Configuration
Rendertron can be configured via a config.json file in the project root. If this file is not present, default values are used. The ConfigManager class is responsible for loading this configuration.
Sources: src/config.ts, README.md:126-134
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
datastoreCache | boolean | false | Set to true to enable caching with Google Cloud Datastore. |
timeout | number | 10000 | Timeout in milliseconds for rendering a page. |
port | string | '3000' | Port for the Rendertron service. Overridden by the PORT environment variable. |
width | number | 1000 | Default viewport width for rendering. |
height | number | 1000 | Default viewport height for rendering. |
Sources: src/config.ts:28-34, README.md:128-133
Example config.json
{
"datastoreCache": true,
"timeout": 15000,
"port": "8080",
"width": 1280,
"height": 1024
}
Core Components
Rendertron Class
This is the main class that initializes and runs the Koa server.
Sources: [src/rendertron.ts]
- Initialization: The
initialize()method launches the Puppeteer browser instance, creates theRenderer, sets up Koa middleware (logger, compression, body-parser), and defines the API routes. It also optionally enables the Datastore cache. - Routing: It uses
koa-routeto define endpoints for rendering, screenshots, and health checks. - URL Restriction: A key security feature is the
restricted()method, which validates URLs to prevent requests to local file systems (file://) or other non-HTTP/HTTPS protocols. If a URL is restricted, the server responds with a403 Forbiddenstatus.
Sources: src/rendertron.ts:23-53, 76-86
Renderer Class
This class is a wrapper around Puppeteer's API, providing high-level functions for rendering pages and taking screenshots.
Sources: [src/renderer.ts]
serialize(url, isMobile): This is the core rendering function.- Creates a new Puppeteer page.
- Sets the viewport and a mobile user agent if
isMobileis true. - Injects polyfills for Web Components (
ShadyDOM,ShadyCSS) to ensure they are serializable. - Navigates to the URL and waits for the network to be idle (
networkidle0). - Determines the final status code, respecting the original response and any
<meta name="render:status_code">tags. - Executes client-side scripts to strip
<script>and<link rel="import">tags (except forapplication/ld+json) and inject a<base>tag. - Returns the serialized
outerHTMLof the document.
screenshot(url, isMobile, dimensions, options): This function generates a screenshot of the given URL. It sets the viewport and captures the page as a JPEG image buffer.
Sources: src/renderer.ts:26-150, 152-188
API Endpoints
The service exposes two main endpoints for interacting with the renderer.
Sources: README.md:52-74, src/rendertron.ts:55-63
Render API
- Endpoint:
GET /render/:url(.*) - Description: Renders the specified URL and returns the serialized HTML content.
| Parameter | Type | Location | Description |
|---|---|---|---|
url | string | path | The full, URL-encoded URL of the page to render. |
mobile | flag | query | If present, renders the page with a mobile viewport and user-agent. |
Sources: README.md:56-61, src/rendertron.ts:98-100
The following diagram shows the sequence of a render request.
Screenshot API
- Endpoint:
GET /screenshot/:url(.*)orPOST /screenshot/:url(.*) - Description: Captures a screenshot of the specified URL and returns it as a JPEG image.
| Parameter | Type | Location | Description |
|---|---|---|---|
url | string | path | The full, URL-encoded URL of the page to screenshot. |
width | number | query | Viewport width. Defaults to 1000. |
height | number | query | Viewport height. Defaults to 1000. |
mobile | flag | query | If present, uses a mobile viewport and user-agent. |
options | object | body | A JSON object with additional Puppeteer screenshot options (POST only). |
Sources: README.md:66-80, src/rendertron.ts:105-129
Middleware
Rendertron is designed to be used with a middleware layer in your application that decides when to proxy requests to the rendering service. An official Express.js middleware is provided.
Sources: middleware/README.md
The middleware inspects the User-Agent header of an incoming request. If it matches a known bot, the request is forwarded to the Rendertron service. Otherwise, the request is handled normally by the application.
Middleware Configuration
| Property | Description |
|---|---|
proxyUrl | Required. The base URL of your Rendertron instance. |
userAgentPattern | A RegExp to match bot user agents. |
excludeUrlPattern | A RegExp to exclude paths (e.g., for static assets like .js, .css). |
injectShadyDom | A boolean to force injection of Web Components polyfills. |
timeout | A timeout for the request to the Rendertron service. |
Sources: middleware/README.md
Testing
The project uses the ava test runner and supertest for making HTTP requests to the Koa server during tests. The main test file, src/test/app-test.ts, covers all major functionalities:
- Health check endpoint (
/_ah/health). - Rendering pages with and without JavaScript.
- Rendering pages with Shadow DOM and polyfills.
- Stripping of
<script>tags while preserving JSON-LD scripts. - Forwarding of HTTP status codes from the target page.
- Overriding status codes with
<meta name="render:status_code">. - Screenshot functionality.
- Validation of restricted URLs (e.g.,
file://).
Sources: src/test/app-test.ts, package.json:19