How to Turn a Webpage into a PDF with Cloudinary
Cloudinary does not directly render arbitrary webpages as PDFs. Learn what it can convert, how to create image-based PDFs, and when to use a browser renderer.
Short answer: Cloudinary’s documented PDF workflows do not directly render arbitrary webpage HTML into a PDF. To preserve a webpage’s layout, first use a browser renderer to print the page to PDF; then use Cloudinary for supported storage and delivery. Cloudinary can also create a PDF from one or more images, but that produces pages from static images rather than rendering HTML. See its PDF documentation and image-to-PDF guidance.
1. Choose the workflow that matches your input
| Starting point | What Cloudinary documents | What it means for a webpage |
|---|---|---|
| HTML page or URL | No direct arbitrary webpage-to-PDF rendering path is established by the documented workflows. | Render the page with a browser first. Upload or deliver the resulting PDF through Cloudinary if you want Cloudinary to host it. |
| One image | Deliver the image in PDF format, optionally applying image transformations. | The PDF is based on the image; it does not contain the original webpage layout or selectable page content. |
| Several images | Use the Upload API multi method with a shared tag and PDF format. Each image becomes a page. |
Useful if you already captured each desired page as an image. Ordering is alphabetical by public ID. |
| Office document | Upload a raw Office file and use the Aspose add-on via raw_convert. |
This is a document conversion workflow, not webpage rendering. It requires registering for the add-on and processes asynchronously. |
| Remote PDF | Fetch a remote PDF and transform a selected page into an image preview. | This makes a preview from an existing PDF; it does not convert a webpage into a PDF. |
The architecture for an actual webpage PDF therefore has two stages: a browser or HTML renderer creates the PDF, and Cloudinary handles supported downstream storage and delivery. This is an inference from the documented inputs and workflows, not a Cloudinary-prescribed or tested integration.
2. Render the webpage in a browser, then upload its PDF
Use a browser printing engine when the output must reflect HTML, CSS, fonts, and page breaks. For example, this Python script uses Playwright’s Chromium browser to load a URL and save a PDF locally. Install Playwright and its browser first; the script is a general browser-rendering example, not a Cloudinary integration.
python -m pip install playwright
python -m playwright install chromium
# save as webpage_to_pdf.py
import asyncio
import sys
from pathlib import Path
from playwright.async_api import async_playwright
async def main():
if len(sys.argv) != 2:
raise SystemExit("Usage: python webpage_to_pdf.py https://example.com")
url = sys.argv[1]
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
response = await page.goto(url, wait_until="networkidle", timeout=60000)
if response and response.status >= 400:
raise RuntimeError(f"Page returned HTTP {response.status}")
await page.pdf(
path="page.pdf",
format="A4",
print_background=True,
prefer_css_page_size=True,
margin={"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
)
await browser.close()
asyncio.run(main())
Run python webpage_to_pdf.py https://example.com. The output is page.pdf. Once you have a PDF, upload it to Cloudinary using your account’s upload workflow and use the resulting delivery URL. Cloudinary’s documentation covers PDF delivery and notes that PDF delivery is blocked by default on Free accounts for security reasons; check the Console Security setting for PDF and ZIP delivery if a valid asset URL is blocked.
Browser-rendering choices that affect the result
- Wait condition:
networkidlewaits for network activity to settle, but pages with persistent polling may never become idle. In that case wait for a meaningful selector or a known delay instead. - Print styles: Browser PDF generation generally follows print styles. Check the page’s print CSS for hidden navigation, page breaks, or colors that differ from its screen presentation.
- Backgrounds: Enable background printing when colored sections or background images matter.
- Page size and margins: Select a paper size and margins that suit the content. If the site defines print page sizing, prefer its CSS page size where appropriate.
- Authentication: A browser session may need cookies or a logged-in state to render gated pages. Avoid placing credentials in a public script or committed source file.
- Dynamic and lazy content: Scroll or wait for the relevant content to load before printing when a page defers images or sections until they enter the viewport.
3. Create a PDF from images with Cloudinary
If the input is already one image, Cloudinary documents delivering it as a PDF by changing the delivery format to PDF. This creates a PDF from the image asset; it does not reconstruct the webpage. The official documentation states, “You can create a PDF file from images stored in your Cloudinary storage.” Cloudinary: Create PDF files from images.
For multiple captured pages, use the Upload API multi method with the same tag on the selected images and PDF output format. Each image becomes one page. Cloudinary documents a limit of 100 images for synchronous processing and 500 for asynchronous processing. Public IDs determine alphabetical page order, so assign sortable IDs such as page-001, page-002, and page-010 if sequence matters. Check your resulting file against the account’s maximum file size; the documented workflow can fail when the output exceeds that limit, and Cloudinary recommends reducing source image sizes.
Do not treat Cloudinary Fetch as an HTML renderer. Its documented remote-media example turns a selected page of a remote PDF into an image preview. A fetched remote asset is cached, and changing the source does not automatically refresh the cached copy; follow Cloudinary’s documented refresh behavior and account-specific checking rules when freshness matters. Cloudinary: Fetch remote images.
4. cURL, Python, and Node.js for the supported image workflow
Cloudinary’s image-to-PDF workflow applies to stored images. These examples demonstrate the general delivery URL shape: replace the placeholders with your Cloudinary cloud name and image public ID, and use the delivery URL generated for your asset. They do not submit HTML for rendering.
cURL: download a delivered PDF asset
curl -L "https://res.cloudinary.com/YOUR_CLOUD_NAME/image/upload/fl_pdf,YOUR_PUBLIC_ID.pdf" -o image-based.pdf
Python: download a delivered PDF asset
import requests
url = "https://res.cloudinary.com/YOUR_CLOUD_NAME/image/upload/fl_pdf,YOUR_PUBLIC_ID.pdf"
response = requests.get(url, timeout=60)
response.raise_for_status()
with open("image-based.pdf", "wb") as output:
output.write(response.content)
Node.js: download a delivered PDF asset
const url = 'https://res.cloudinary.com/YOUR_CLOUD_NAME/image/upload/fl_pdf,YOUR_PUBLIC_ID.pdf';
const response = await fetch(url);
if (!response.ok) throw new Error(`Cloudinary returned ${response.status}`);
const bytes = new Uint8Array(await response.arrayBuffer());
await (await import('node:fs/promises')).writeFile('image-based.pdf', bytes);
Use Cloudinary’s generated URL and transformation syntax for your actual asset, especially if it is private, authenticated, or uses a different delivery type. Do not put API secrets in client-side code.
5. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| A URL does not produce a webpage PDF | The documented Cloudinary PDF workflows do not render arbitrary HTML. | Render the URL with a browser first, then upload the PDF; use Cloudinary image-to-PDF only when your inputs are images. |
| PDF delivery is denied on a Free account | PDF and ZIP delivery is blocked by default for security reasons. | Review and enable PDF and ZIP delivery in Console Security settings, then retry. |
| The PDF is missing content or looks different from the browser | Content had not loaded, print styles changed the layout, or the page uses lazy loading. | Wait for the relevant content, inspect print CSS, and verify the output at the intended paper size. |
| Multi-image PDF pages appear in the wrong order | Cloudinary orders pages alphabetically by public ID. | Use consistently zero-padded, sortable public IDs. |
| Multi-image PDF creation fails | The input count exceeds the synchronous or asynchronous limit, or the output exceeds the plan’s maximum file size. | Stay within 100 images synchronously or 500 asynchronously, and reduce source image sizes if the output is too large. |
| A remote preview still shows old content | The fetched source is cached; source changes do not automatically refresh the copy. | Use the documented refresh behavior and account-specific refresh schedule. |
| Office conversion has not completed | The Aspose conversion workflow is asynchronous. | Check for the resulting PDF resource after processing; ensure the add-on is registered and the Office file was uploaded as a raw file. |
6. Performance, reliability, and cost considerations
- Rendering time: Browser work is separate from Cloudinary. Slow scripts, fonts, third-party resources, and pages that continuously poll can delay or prevent a chosen wait condition from completing.
- Repeatability: A webpage can change between captures. Record the source URL and capture time in your own workflow if you need to trace which version produced a PDF.
- PDF size: Image-based pages can produce large files. Reduce source image dimensions or quality as appropriate, while retaining enough detail for the intended use.
- Cloudinary limits: The multi-image method documents up to 100 images synchronously and 500 asynchronously, and output size remains subject to the plan’s maximum file size.
- Freshness: Remote fetched assets are cached. Plan for the documented refresh behavior when upstream content changes.
- Account configuration: Free-account PDF delivery defaults may block delivery until enabled. Office conversion also depends on the Aspose add-on.
- Cost: This workflow can involve browser compute plus Cloudinary storage, transformations, delivery, or add-on costs under the applicable account terms. The research sources do not establish current prices, so check Cloudinary’s account and plan details before estimating a production workload.
7. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can return a PDF directly from a URL. If your goal is a clean webpage capture as a PDF, use a single request; see the ScreenshotNeo API documentation for PDF options and request configuration.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=pdf \
-o page.pdf
Cookie banners, newsletter popups, and chat widgets are removed before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up free and capture your first 1,000 screenshots a month without a card.
FAQ
Can Cloudinary turn any public webpage URL directly into a PDF?
The documented workflows reviewed here do not describe arbitrary HTML rendering from a URL to PDF. Use a browser renderer for that first step.
Does a PDF made from a screenshot preserve selectable webpage text?
An image-based PDF contains image pages, so its text is not inherently selectable as webpage text.
Can I use Cloudinary Fetch to make a screenshot of a webpage?
The documented Fetch example handles remote media such as a PDF page preview; it does not establish webpage rendering.
When does Cloudinary make sense in this workflow?
Use it for the documented image-to-PDF process, supported Office conversion, or storage and delivery of a PDF produced by a separate renderer.


