Tips and pitfalls
What makes renders complete, sharp and fast, and the mistakes that cost the most time.
Pages built with JavaScript
Symptom: a spinner, an empty layout or missing charts in the result.
- For screenshots, use
wait_until=networkidle, or better,wait_for_selectorwith an element that appears when the page is ready. - For PDFs, expose a function such as
window.reportReady = () => document.body.dataset.ready === '1'and send"wait_for": "reportReady". - A fixed
delayworks but wastes time on fast pages and is too short on slow ones. Use it as a last resort.
Lazy-loaded images
Symptom: grey boxes lower on the page in a full_page screenshot. Images with loading="lazy" load only when scrolled into view. In your own HTML, remove loading="lazy". For other sites, add a short delay or inject a small script with javascript that scrolls the page.
Units of delay
The PDF endpoint counts delay in milliseconds (as PDFShift does); the screenshot endpoint in seconds (as ScreenshotOne does). "delay": 2 on the PDF endpoint waits two milliseconds.
Page breaks
.no-split { break-inside: avoid; } /* keep a block on one page */
.new-page { break-before: page; } /* start a new page */
h2 { break-after: avoid; } /* keep a heading with its text */
Page size comes from the format parameter; a @page { size: ... } rule in your CSS is ignored. Margins from margin apply to every page.
Backgrounds and colours
Backgrounds are printed by default. If colours look washed out, check for @media print rules in your CSS; they apply only with use_print: true. Use -webkit-print-color-adjust: exact on elements whose colour must stay exact.
Sharp screenshots
device_scale_factor=2 doubles the resolution for high-density screens and for zooming in. Use jpeg or webp with image_quality 75 to 85 for photos and long pages; png for text, charts and transparency.
Smaller, faster requests
- Block what you do not need:
block_ads,block_trackersandblock_chatsoften cut several seconds from a page. - Link large images by URL instead of embedding them as base64; the request body is limited to 10 MB.
- Reuse one HTTP connection for many requests (keep-alive is on by default in the clients shown in the examples).
- Send batches a few at a time, not hundreds at once; see concurrency.
Things that fail silently
- Relative links in an HTML source have nothing to resolve against. Use absolute URLs or a
<base href>tag. - Links to
localhostor internal addresses are blocked for security. Make the resource public, or embed it. - Fonts from a slow CDN delay every render; install-free options are listed in Arabic documents.
- Saving an error as a file: check the status code first; errors are JSON.
Keep your own copy
Sahifa does not store results, so it cannot send a file again later. If you need the document afterwards (an invoice, a KYB record), store it on your side when the response arrives, together with the time and the request parameters.