Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
Rendertron is a standalone HTTP service built with Koa.js that uses Puppeteer to render web pages in a headless Chrome instance. Its primary purpose is to provide server-side rendering on-the-fly for Progressive Web Apps (PWAs) and single-page applications (SPAs). This allows search engine crawlers and social media bots, which may not execute JavaScript, to see the fully rendered content, improving SEO and link sharing previews.
The system is composed of a core rendering service and optional middleware for easy integration into existing web applications. The core service exposes API endpoints to render a URL and return its serialized HTML content, or to capture a screenshot of the page. The architecture is designed to be deployed as a microservice, which client applications can proxy requests to based on the user-agent.
Sources: README.md, src/rendertron.ts, middleware/src/middleware.ts
Core Components
The Rendertron service is built around two main classes: Rendertron and Renderer.
Sources: src/rendertron.ts, src/renderer.ts
Rendertron Class
The Rendertron class is the entry point of the application. It sets up and manages the Koa.js web server, initializes middleware, defines API routes, and instantiates the Renderer.
Key responsibilities:
- Initialization: Launches a Puppeteer browser instance and creates a
Rendererobject. - Server Setup: Configures a Koa application with middleware for logging (
koa-logger), compression (koa-compress), and body parsing (koa-bodyparser). - Routing: Defines the API endpoints (
/render,/screenshot,/_ah/health) and links them to handler methods. - Request Handling: The handler methods (
handleRenderRequest,handleScreenshotRequest) perform URL validation and delegate the core rendering task to theRendererinstance.
Sources: src/rendertron.ts:15-143
Renderer Class
The Renderer class encapsulates all interactions with Puppeteer and the headless Chrome browser. It is responsible for the actual rendering, serialization, and screenshotting of web pages.
Key responsibilities:
- Page Serialization: The
serializemethod navigates to a given URL, waits for the page to be idle (networkidle0), and then serializes the DOM to an HTML string. It includes logic to strip script tags and inject a<base>tag. - Screenshotting: The
screenshotmethod navigates to a URL and captures a screenshot, returning it as a buffer. - Web Component Support: It injects polyfills for Shady DOM and Custom Elements to ensure web components are rendered correctly.
- Status Code Handling: It preserves the HTTP status code from the target URL and allows it to be overridden via a
<meta name="render:status_code">tag in the page's HTML.
This diagram shows the relationship between the Rendertron server and the Renderer.
Sources: src/rendertron.ts:15-29, src/renderer.ts:19-32
System Architecture Flow
A typical request flow involves a user/bot, the client's web application (with middleware), the Rendertron service, and the target website to be rendered.
This diagram illustrates the high-level data flow.
API Endpoints
The Rendertron service exposes two primary API endpoints. All endpoints perform a security check to ensure the requested URL uses the http or https protocol.
Sources: src/rendertron.ts:81-89, src/test/app-test.ts
| Method | Endpoint | Description |
|---|---|---|
GET | /render/<url> | Renders the specified <url> and returns the serialized HTML content. Supports a ?mobile query parameter. |
GET, POST | /screenshot/<url> | Captures a screenshot of the <url>. Viewport dimensions can be set with width and height query parameters. POST requests can include a JSON body with additional Puppeteer screenshot options. |
GET | /_ah/health | A health check endpoint that returns 200 OK. |
Sources: src/rendertron.ts:55-71, README.md:52-72
Render Request Sequence
The following diagram shows the sequence of operations for a /render request.
This sequence demonstrates how the Renderer class uses Puppeteer to control a headless browser to fetch, process, and serialize the page content before returning it.
Sources: src/rendertron.ts:91-104, src/renderer.ts:34-152
Status Code Handling
Rendertron forwards the status code from the initial response of the target URL. If the original status is 200, it can be overridden by including a meta tag in the target page's HTML.
<meta name="render:status_code" content="404" />
A status code of 304 Not Modified is treated as 200 OK.
Sources: src/renderer.ts:127-143, test-resources/http-meta-status-code.html:14
Express Middleware
For easier integration, an Express middleware is provided. This middleware inspects the User-Agent header of incoming requests. If the user agent matches a known bot, it proxies the request to a configured Rendertron service instance. Otherwise, it passes the request to the next middleware, serving the standard application.
Sources: middleware/src/middleware.ts, middleware/README.md
Middleware Configuration
The makeMiddleware function accepts a configuration object.
| Property | Default | Description |
|---|---|---|
proxyUrl | Required | Base URL of the running Rendertron service. |
userAgentPattern | RegExp of known bots | RegExp for matching requests by User-Agent header. |
excludeUrlPattern | RegExp of static file extensions | RegExp for excluding requests by URL path (e.g., .png, .css). |
injectShadyDom | false | If true, adds ?wc-inject-shadydom=true to the proxied URL to force web component polyfills. |
timeout | 11000 | Timeout in milliseconds for the proxy request to Rendertron. |
Sources: middleware/README.md:30-39, middleware/src/middleware.ts:25-34
Configuration
The core Rendertron service can be configured via a config.json file in the project root.
| Option | Default | Description |
|---|---|---|
datastoreCache | false | Enables caching responses in Google Cloud Datastore. |
timeout | 10000 | Timeout in milliseconds for rendering a page. |
port | 3000 | Port for the Rendertron service to listen on. Overridden by process.env.PORT. |
width | 1000 | Default viewport width for rendering. |
height | 1000 | Default viewport height for rendering. |
Sources: README.md:120-127, src/rendertron.ts:16,22