How to Connect Chrome to RStudio Pagedown for PDF Rendering
Connect Chrome to RStudio Pagedown, fix browser discovery, render PDFs locally or in CI, and troubleshoot server and container failures.
Short answer: RStudio Pagedown renders PDF files by asking a Chromium-based browser (Chrome, Edge, or Chromium) to print the generated paged HTML. Install the browser where R runs, then use pagedown::chrome_print() or set knit: pagedown::chrome_print in your R Markdown YAML. If discovery fails, set PAGEDOWN_CHROME to the browser executable path.
Pagedown is an HTML-and-browser workflow, not a LaTeX PDF engine. The official package documentation describes chrome_print() as the bridge from paged HTML to PDF: Pagedown documentation.
1. Install the browser and Pagedown
Install one supported browser on the same machine that executes R:
- Google Chrome
- Microsoft Edge
- Chromium
Then install Pagedown in R:
install.packages("pagedown")
Restart RStudio after installation so its R session sees the updated package and environment.
2. Create a paged R Markdown document
A minimal document uses pagedown::html_paged to create paginated HTML. The browser prints that HTML to PDF in the next step.
---
title: "Quarterly report"
author: "Analytics team"
output:
pagedown::html_paged:
self_contained: true
---
# Summary
This section becomes part of the paginated HTML output.
```{r}
plot(cars)
```
Click Knit in RStudio. This first creates an HTML file. Open it in the RStudio Viewer to check page breaks, running headers, figures, fonts and tables before printing.
3. Convert the rendered HTML with chrome_print()
For a one-off conversion, render the HTML and then call:
pagedown::chrome_print(
input = "report.html",
output = "report.pdf"
)
You can also provide browser arguments and a timeout when needed:
pagedown::chrome_print(
input = "report.html",
output = "report.pdf",
extra_args = c("--disable-dev-shm-usage"),
timeout = 120
)
Use --disable-dev-shm-usage when Chrome crashes in a small Linux container whose shared-memory mount is too small. Keep the browser current; old Chrome versions can produce WebSocket message-size errors.
4. Make the Knit button create the PDF
To connect the Knit button directly to Chrome printing, put this hook in the YAML header:
---
title: "Quarterly report"
knit: pagedown::chrome_print
output:
pagedown::html_paged:
self_contained: true
---
With this configuration, knitting renders the paged HTML and then invokes Chrome to write the PDF. If you need a particular HTML template or pagedown option, keep the output configuration in the YAML and use the hook for the final print step. The chrome_print reference documents the function arguments.
5. Tell Pagedown where Chrome is installed
Pagedown normally discovers Chrome, Edge or Chromium automatically. When that fails, set PAGEDOWN_CHROME to the full executable path in the R process environment.
Temporary setting in R
Sys.setenv(PAGEDOWN_CHROME = "/usr/bin/google-chrome")
pagedown::chrome_print("report.html", output = "report.pdf")
Persistent setting in .Renviron
Add a line to the .Renviron file used by the account running RStudio:
PAGEDOWN_CHROME=/usr/bin/google-chrome
On Windows, use the executable path and forward slashes, for example:
PAGEDOWN_CHROME=C:/Program Files/Google/Chrome/Application/chrome.exe
Restart RStudio after changing .Renviron. Verify the value:
Sys.getenv("PAGEDOWN_CHROME")
6. Browser Print versus automated printing
| Method | Best for | Trade-offs |
|---|---|---|
| Browser Print | Quick manual checks and interactive layout work | Depends on a person, browser profile and print dialog settings |
chrome_print() |
Repeatable scripts, reports and scheduled jobs | Needs a discoverable browser executable and a stable runtime |
knit: pagedown::chrome_print |
One-click RStudio PDF generation | Browser errors appear during knitting, so diagnose the R session environment |
Automated printing is easier to reproduce because the input HTML, output path and browser command are explicit. For visual checks, inspect the generated file at the intended browser zoom: browser zoom can change the apparent paged layout.
7. What happens inside the workflow
- R Markdown runs code chunks and produces HTML.
pagedown::html_pagedadds paged-media behavior using paged.js.- RStudio’s local web server lets paged.js run correctly in the Viewer.
chrome_print()starts or connects to a Chromium-compatible browser.- The browser loads the HTML and uses its print engine to write a PDF.
If you open generated paged HTML directly from a file:// path in a normal browser, behavior can differ because paged.js expects a web-serving context. Use the RStudio Viewer or serve the directory over HTTP while inspecting output. See the Pagedown overview for the browser-based rendering model.
8. RStudio Server and remote hosts
On RStudio Server, installing Chrome on your laptop is not sufficient. Install Chrome or Chromium on the server that runs the R session. The executable must be on that host’s PATH or specified with PAGEDOWN_CHROME.
Also ensure 127.0.0.1 is included in no_proxy. A proxy setting that routes localhost through an external proxy can prevent the R session from connecting to the browser.
Sys.setenv(no_proxy = paste(
Sys.getenv("no_proxy"),
"127.0.0.1",
sep = if (nzchar(Sys.getenv("no_proxy"))) "," else ""
))
Use the same Unix account, environment variables and working directory in RStudio that you use when diagnosing from a shell. A browser installed only for another user may be invisible to the R session.
9. CI and Docker
A reliable container needs four things:
- A recent Chrome or Chromium executable.
- The R
pagedownpackage, commonly installed withinstall2.r pagedown. - Enough shared memory for the browser.
- A sandbox configuration appropriate for the container.
The Pagedown documentation provides a Rocker-based Docker approach that installs Google Chrome and Pagedown. In some Travis or GitLab container environments, Chrome may require --no-sandbox; this creates a major security risk for untrusted pages. Prefer a Docker seccomp profile that permits the browser sandbox when your deployment supports it.
pagedown::chrome_print(
"report.html",
output = "report.pdf",
extra_args = c("--disable-dev-shm-usage")
)
For CI, pin the browser image or package version when reproducibility matters, cache R packages where appropriate, and archive the generated HTML alongside the PDF so a failed print can be reproduced.
10. Options and configuration checklist
| Setting | Purpose | Typical action |
|---|---|---|
input |
Rendered paged HTML file | Pass report.html |
output |
Destination PDF path | Pass report.pdf |
knit |
Connect the Knit button to printing | Use pagedown::chrome_print |
PAGEDOWN_CHROME |
Explicit browser executable | Set an absolute path |
extra_args |
Chromium command-line flags | Use --disable-dev-shm-usage for constrained containers |
timeout |
Maximum time allowed for printing | Increase for large reports or slow pages |
self_contained |
Embed resources in HTML | Use when the print host cannot access asset files |
11. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Chrome not found | Browser is absent, not on PATH, or installed for another user |
Install it on the execution host, check Sys.which("google-chrome"), or set PAGEDOWN_CHROME to the full path. |
chrome_print() cannot connect on RStudio Server |
Localhost is routed through a proxy | Add 127.0.0.1 to no_proxy and restart the R session. |
| Chrome crashes on a large PDF in a small Linux container | Insufficient shared memory | Increase container shared memory or try extra_args = c("--disable-dev-shm-usage"). |
| WebSocket message-too-large error | Old Chrome | Update Chrome or Chromium in the runtime image. |
| Fonts, page breaks or widths differ | Different fonts, browser zoom or browser version | Install required fonts, use the intended zoom, and keep browser versions consistent. |
| Images or CSS disappear | Relative assets are unavailable to the print process | Use self-contained HTML or serve the project directory from a local web server. |
| Knitting succeeds but PDF is missing | Output path is relative to a different working directory | Print the working directory with getwd() and pass an absolute output path. |
| Page content is cut off | Content relies on viewport behavior or unsupported CSS | Inspect the paged HTML, simplify fixed-height containers and confirm page rules before printing. |
| Print hangs on a remote page | Network request, script or asset never finishes | Make assets local or reachable, increase timeout, and inspect the HTML separately. |
12. Performance, reliability and cost
Performance
- Render once and reuse the HTML when iterating on browser-print settings.
- Reduce oversized images and unnecessary JavaScript in reports.
- Use a warm, preinstalled browser in CI rather than downloading it for every job.
- Give containers adequate CPU and shared memory for large tables and figures.
Reliability
- Pin browser and R package versions for repeatable output.
- Keep the generated HTML as an artifact for diagnosis.
- Run a small smoke report before processing a large batch.
- Use the browser sandbox whenever possible; treat
--no-sandboxas a constrained-environment workaround only.
Cost
Local Chrome and Pagedown do not add a per-page service charge, but CI and hosted RStudio usage consume compute, storage and build time. If you move capture to a hosted screenshot API, compare billing rules, failed-load handling and the options you need.
13. Or skip the browser setup
If you need a screenshot or PDF from a URL rather than a knitted R Markdown report, ScreenshotNeo provides a single-call website capture API. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before capture, and lets each cleanup step be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; the response identifies the result with X-Page-Verdict and X-Billed headers.
See the ScreenshotNeo API documentation for all options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also includes PDF capture, full-page lazy-image loading, CSS-selector element capture, custom CSS and JavaScript, waits, blocking rules, headers, cookies, user agents, authorization, timezone and geolocation controls, caching with a chosen TTL, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, an OpenAPI specification and an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. Every feature is on every plan. The Free plan includes 1,000 shots each month with no card; paid plans start at $5 for 3,000 shots.
Create a free ScreenshotNeo account and use the 1,000 monthly shots without adding a card.
14. FAQ
Does Pagedown require LaTeX?
No. Its PDF route uses a Chrome-compatible browser to print paged HTML.
Can Edge replace Chrome?
Yes. Pagedown supports Chromium-based browsers such as Chrome, Edge and Chromium. Set PAGEDOWN_CHROME when automatic discovery does not select the intended executable.
Why does the RStudio Viewer look right but the PDF does not?
The Viewer and print process can use different browser versions, fonts, zoom and asset URLs. Compare those conditions and inspect the generated HTML.
Should I use chrome_print() for a batch?
Yes, when each report can be rendered to HTML and printed in a controlled runtime. Keep browser versions, fonts and container resources consistent.
When is a hosted capture API a better fit?
Use one when you need URL-based screenshots or PDFs without maintaining browser installation, sandboxing, proxy settings and container resources. ScreenshotNeo adds consent cleanup, verdict-based billing and an MCP server for AI agents.


