Deployment Overview
Relevant source files
The following files were used as context for generating this wiki page:Rendertron is a standalone HTTP server that uses headless Chrome via Puppeteer to render and serialize web pages on the fly. Its primary purpose is to enable Progressive Web Apps (PWAs) and other JavaScript-heavy sites to serve fully-rendered content to bots that do not execute JavaScript, thereby improving SEO. The service is designed to be integrated into an existing application stack using middleware, which selectively proxies requests from bots to the Rendertron instance.
This document provides an overview of the various methods for deploying and running the Rendertron service, its core architecture, and configuration options. It covers local execution, cloud deployment, and integration with application middleware.
Sources: README.md:7-16, src/rendertron.ts:11-14
Architecture
The Rendertron deployment architecture consists of two main parts: the Rendertron server itself and an optional middleware component in your application. When a request comes to your web application, the middleware inspects the User-Agent header. If the user agent is identified as a bot, the middleware proxies the request to the Rendertron server. Rendertron then fetches the URL, renders it using a headless Chrome instance managed by Puppeteer, and returns the serialized HTML content to the bot.
This diagram illustrates the request flow when using Rendertron with middleware.
Sources: README.md:12-16, middleware/README.md:8-12
Installation and Execution
There are several ways to install and run the Rendertron service, depending on the environment (local development, production, etc.).
Building from Source
To run the service from a cloned repository, you must first install dependencies and build the TypeScript source.
- Clone the repository:
git clone https://github.com/GoogleChrome/rendertron.git - Install dependencies:
npm install - Build the project:
npm run build
After building, the compiled JavaScript files will be in the build/ directory.
Sources: package.json:13-14, README.md:88-93
Running Locally
For local development or testing, Rendertron can be started with a simple command, which will launch the Koa server. This requires a local installation of Google Chrome.
npm run start
This command executes node build/rendertron.js, starting the server on the configured port (defaulting to 3000).
Sources: package.json:15, README.md:95-98, README.md:106
Alternatively, for quick use without cloning the repository, Rendertron can be installed globally via npm.
npm install -g rendertron
rendertron
Sources: README.md:80-84
Deployment Methods
Deploying to Render
The recommended cloud deployment method is using Render. The documentation provides a specific guide for deploying a Puppeteer-based Node.js application like Rendertron.
See https://render.com/docs/deploy-puppeteer-node/ for detailed instructions.
Sources: README.md:100-101
Deploying with Docker
The project no longer includes a Dockerfile. For container-based deployments, users should refer to the official Puppeteer documentation for guidance on running headless Chrome within a Docker container. This typically involves ensuring all necessary system dependencies for Chrome are installed in the container image.
Sources: README.md:103-106
Configuration
Rendertron can be configured by placing a config.json file in the project root. The server will load this file on startup to override default settings.
| Option | Type | Default | Description |
|---|---|---|---|
datastoreCache | boolean | false | If true, enables caching of rendered pages using Google Cloud Datastore. |
timeout | number | 10000 | The timeout in milliseconds for rendering a target page. |
port | number | 3000 | The port for the Rendertron HTTP server. Overridden by the PORT environment variable if set. |
width | number | 1000 | The default viewport width in pixels for rendering. |
height | number | 1000 | The default viewport height in pixels for rendering. |
Sources: README.md:108-115, src/rendertron.ts:16,21
The Rendertron class in src/rendertron.ts initializes these configuration values and launches a Puppeteer instance.
// src/rendertron.ts:19-24
export class Rendertron {
// ...
private config: Config = ConfigManager.config;
// ...
async initialize() {
// Load config
this.config = await ConfigManager.getConfiguration();
// ...
const browser = await puppeteer.launch({args: ['--no-sandbox']});
this.renderer = new Renderer(browser, this.config);
// ...
}
}
Sources: src/rendertron.ts:19-24
Middleware Integration
To use Rendertron, your application needs a differential serving layer. The provided rendertron-middleware for Express.js is one such solution. It identifies bot user agents and proxies their requests to your Rendertron instance.
Middleware Logic Flow
This diagram shows the decision-making process within the middleware.
This flow ensures that only requests from bots to non-static resources are pre-rendered.
Sources: middleware/README.md:10-12, middleware/src/test/middleware-test.ts:98-101,133-136
Middleware Configuration
The middleware is configured with the URL of the Rendertron service and other options.
| Property | Default | Description |
|---|---|---|
proxyUrl | Required | Base URL of the running Rendertron service. |
userAgentPattern | RegExp for known bots | A regular expression to match bot user agents. |
excludeUrlPattern | RegExp for static file extensions | A regular expression to exclude URLs (e.g., for images, CSS). |
injectShadyDom | false | Adds ?wc-inject-shadydom=true to the render URL for web components. |
timeout | 11000 | Timeout in milliseconds for the proxy request to Rendertron. |
Sources: middleware/README.md:28-36
Caching
Rendertron supports optional caching with Google Cloud Datastore to reduce rendering load and improve response times for frequently accessed pages.
To enable it, set datastoreCache to true in your config.json. When enabled, the DatastoreCache middleware is added to the Koa application stack. It intercepts requests and checks if a valid cached version exists in Datastore. If a cache hit occurs, it serves the stored response directly. Otherwise, it allows the request to proceed to the renderer and caches the new result.
Cached responses include an x-rendertron-cached header with the timestamp of when the content was cached.
Sources: src/rendertron.ts:43-46, src/test/datastore-cache-test.ts:41-43, README.md:109