Skip to content

Custom fonts

Browser Run uses a managed Chromium environment that includes a standard set of pre-installed fonts. When you generate a screenshot or PDF, text is rendered using the fonts available in this environment. If your page specifies a font that is not pre-installed, Chromium will automatically fall back to a similar supported font.

If you need a specific font that is not pre-installed, you can inject it into the page at render time. You can load fonts from an external URL or embed them directly as a Base64 string.

How you add a custom font depends on how you are using Browser Run:

Browser sessions

Use addStyleTag to inject a @font-face rule into the page before capturing your screenshot or PDF. You can load the font file from a CDN URL or embed it as a Base64-encoded string.

The examples below use Puppeteer with Workers Bindings. If you are connecting via CDP, the only difference is how you connect to the browser. Once connected, page.addStyleTag() works the same way. Refer to CDP connection example for details.

From a CDN URL

Example with Puppeteer and a CDN source:

JavaScript
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.addStyleTag({
content: `
@font-face {
font-family: 'CustomFont';
src: url('https://your-cdn.com/fonts/MyFont.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
body {
font-family: 'CustomFont', sans-serif;
}
`,
});

Base64-encoded

The following examples use Playwright, but this method works the same way with Puppeteer.

Example with a Base64-encoded data source:

JavaScript
const browser = await playwright.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.addStyleTag({
content: `
@font-face {
font-family: 'CustomFont';
src: url('data:font/woff2;base64,<BASE64_STRING>') format('woff2');
font-weight: normal;
font-style: normal;
}
body {
font-family: 'CustomFont', sans-serif;
}
`,
});

CDP connection example

When connecting via CDP, you connect to the browser using a WebSocket endpoint instead of a Workers Binding. Once connected, you use page.addStyleTag() the same way as the examples above.

JavaScript
import puppeteer from "puppeteer-core";
const ACCOUNT_ID = "your-account-id";
const API_TOKEN = "your-api-token";
// Create a browser session via CDP
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/browser-rendering/devtools/browser`,
{
method: "POST",
headers: { Authorization: `Bearer ${API_TOKEN}` },
},
);
const { webSocketDebuggerUrl } = await response.json();
// Connect Puppeteer to the session
const browser = await puppeteer.connect({
browserWSEndpoint: webSocketDebuggerUrl,
headers: { Authorization: `Bearer ${API_TOKEN}` },
});
const page = await browser.newPage();
// Add a custom font — same as with Workers Bindings
await page.addStyleTag({
content: `
@font-face {
font-family: 'CustomFont';
src: url('https://your-cdn.com/fonts/MyFont.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
body {
font-family: 'CustomFont', sans-serif;
}
`,
});
// Take a screenshot, generate a PDF, etc.
await page.goto("https://example.com");
browser.disconnect();

Quick Actions

When using Quick Actions, you can load custom fonts by including the addStyleTag parameter in your request body. This works with both the screenshot and PDF endpoints.

From a CDN URL

Terminal window
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"addStyleTag": [
{
"content": "@font-face { font-family: '\''CustomFont'\''; src: url('\''https://your-cdn.com/fonts/MyFont.woff2'\'') format('\''woff2'\''); font-weight: normal; font-style: normal; } body { font-family: '\''CustomFont'\'', sans-serif; }"
}
]
}' \
--output "screenshot.png"

Base64-encoded

Terminal window
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"addStyleTag": [
{
"content": "@font-face { font-family: '\''CustomFont'\''; src: url('\''data:font/woff2;base64,<BASE64_STRING>'\'') format('\''woff2'\''); font-weight: normal; font-style: normal; } body { font-family: '\''CustomFont'\'', sans-serif; }"
}
]
}' \
--output "screenshot.png"

For more details on using addStyleTag with Quick Actions, refer to Customize CSS and embed custom JavaScript.