Screenshot API (/screenshot)
Relevant source files
The following files were used as context for generating this wiki page:The Screenshot API provides a way to generate a JPEG image of any public URL using a headless Chrome instance managed by Puppeteer. It is designed to help verify that a page is rendering correctly. The API supports both GET and POST requests, allowing for simple captures as well as more complex screenshots with custom options like clipping.
This service is exposed through the /screenshot/<url> endpoint. It handles setting the viewport, navigating to the page, waiting for network activity to cease, and capturing the final rendered output as an image.
Sources: README.md, src/rendertron.ts:18-23, src/test/app-test.ts:130-149
API Endpoints
The API is available via two methods on the same route pattern.
GET /screenshot/<url>: Takes a screenshot of the given URL with options specified as query parameters.POST /screenshot/<url>: Takes a screenshot with basic options from query parameters and advanced options from a JSON request body.
Sources: README.md:50-53, src/rendertron.ts:63-66
Query Parameters
The following query parameters are available for both GET and POST requests.
| Parameter | Type | Description | Default |
|---|---|---|---|
width | Number | The viewport width in pixels. | 1000 (from config) |
height | Number | The viewport height in pixels. | 1000 (from config) |
mobile | Boolean | If present, sets a mobile user-agent and enables mobile-specific viewport settings. Defaults to false. | false |
Sources: README.md:55-60, src/rendertron.ts:121-125, src/renderer.ts:178-180
POST Body Options
For POST requests, a JSON body can be sent to specify advanced screenshot options, which are passed directly to Puppeteer's page.screenshot method.
The example below shows a test case where clip options are sent in the POST body.
// src/test/app-test.ts:141-146
test('screenshot accepts options', async (t) => {
const res =
await server.post(`/screenshot/${testBase}basic-script.html`).send({
clip: {x: 100, y: 100, width: 100, height: 100},
path: 'test.jpeg'
});
Note: The type (hardcoded to jpeg) and encoding (hardcoded to binary) parameters cannot be overridden.
Sources: README.md:62-66, src/renderer.ts:200-201, src/test/app-test.ts:141-149
Request Handling Flow
The following diagram illustrates the sequence of operations when a request hits the /screenshot endpoint.
This diagram shows the flow from the initial client request through the Koa server, into the Renderer class which orchestrates Puppeteer to capture the screenshot, and finally back to the client.
Sources: src/rendertron.ts:109-136, src/renderer.ts:172-205
Core Screenshot Logic
The core functionality resides in the Renderer class, which encapsulates the interaction with Puppeteer.
Sources: src/renderer.ts
Class Diagram
This diagram shows the structure of the Renderer class and its custom ScreenshotError.
Execution Steps
- Create Page: A new Puppeteer
Pageinstance is created.
Sources: src/renderer.ts:173 - Set Viewport: The page's viewport is configured using the
width,height, andisMobileparameters. IfisMobileis true, a specific mobile user-agent is also set.
Sources: src/renderer.ts:177-182// src/renderer.ts:177-182 await page.setViewport( {width: dimensions.width, height: dimensions.height, isMobile}); if (isMobile) { page.setUserAgent(MOBILE_USERAGENT); } - Navigate: The browser navigates to the target URL. The function waits until the
networkidle0event fires, which means there have been no new network connections for at least 500 ms. The navigation has a hardcoded timeout of 10,000 ms.
Sources: src/renderer.ts:189-190 - Security Check: After navigation, it checks if the response contains the
metadata-flavor: Googleheader to prevent access to Google Cloud metadata services. If found, it throws aForbiddenerror.
Sources: src/renderer.ts:196-198 - Take Screenshot: The
page.screenshot()method is called. It merges any user-providedoptionsfrom a POST request with hardcoded options{type: 'jpeg', encoding: 'binary'}. The result is aBuffercontaining the image data.
Sources: src/renderer.ts:200-204
Security and Error Handling
The API includes checks to prevent misuse and provides clear error responses.
URL Restriction
Before processing any request, the restricted function in Rendertron class validates the URL.
This flow chart shows the validation logic.
The restricted function ensures the URL protocol is either http or https. Requests for other protocols like file:// are rejected with a 403 Forbidden status.
Sources: src/rendertron.ts:81-91, 114-117, src/test/app-test.ts:166-173
Error Responses
The renderer.screenshot method can throw a ScreenshotError for specific failure cases, which is then handled in handleScreenshotRequest to set the appropriate HTTP status code.
| Error Type | Condition | HTTP Status |
|---|---|---|
Forbidden | Response includes metadata-flavor: Google header. | 403 |
NoResponse | Puppeteer fails to get a response from page.goto. | 500 |
Other Error | Any other exception during the process. | 500 |
Sources: src/renderer.ts:196-198, 209-219, src/rendertron.ts:129-134
Conclusion
The Screenshot API is a core utility within Rendertron for visually inspecting web pages as seen by a headless browser. It provides a straightforward interface via GET and POST requests, with flexible options for controlling the output. By integrating directly with Puppeteer, it delivers accurate, high-fidelity image captures while incorporating essential security checks to ensure safe operation.