Skip to content

Renderer ​

Renders JavaScript-heavy pages to static HTML using a single, reused headless Chromium instance.

ts
import { Renderer } from "headless-prerender";

Constructor ​

ts
new Renderer(options?: RendererOptions)

Creates a renderer. The browser is not launched yet - it starts lazily on the first render() call and is then reused for every subsequent call.

See Options for the full RendererOptions shape.

ts
const renderer = new Renderer({
  timeout: 30_000,
  waitUntil: "networkidle0",
  extraWaitMs: 300,
  allowedOrigins: ["https://www.example.com"],
});

render(url) ​

ts
render(url: string): Promise<RenderResult>

Renders a single URL and resolves with the fully-rendered HTML.

Parameters ​

NameTypeDescription
urlstringAbsolute http(s) URL to render

Returns RenderResult ​

FieldTypeDescription
htmlstringThe final, fully-rendered HTML document
statusnumberHTTP status of the top-level navigation (0 if unknown)
urlstringThe URL after any redirects
durationMsnumberWall-clock render time in milliseconds

Throws ​

MessageCause
Invalid URL: ...The string is not a valid URL
Unsupported protocol: ...Not http: or https:
Origin not allowed: ...allowedOrigins is set and does not include this origin
Puppeteer navigation errorsTimeout, DNS failure, connection refused, etc.

Example ​

ts
const { html, status, url, durationMs } = await renderer.render(
  "https://www.example.com/products/42",
);

if (status >= 400) {
  console.warn(`Upstream returned ${status}`);
}

close() ​

ts
close(): Promise<void>

Closes the underlying browser. Safe to call more than once, and safe to call before any render(). After closing, the next render() launches a fresh browser.

Always call this when you are done, or the Node process will not exit:

ts
const renderer = new Renderer();
try {
  await renderer.render("https://www.example.com");
} finally {
  await renderer.close();
}

Concurrency ​

Each render() opens its own browser page (tab) in the shared browser, so concurrent calls are supported:

ts
const renderer = new Renderer();
const [a, b] = await Promise.all([
  renderer.render("https://www.example.com/a"),
  renderer.render("https://www.example.com/b"),
]);
await renderer.close();

Each open page costs memory. For high concurrency, cap the number of in-flight render() calls yourself (a queue or a semaphore) and monitor memory.

Released under the MIT License.