Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To create PDFs with Microsoft Playwright in Azure Functions Linux, package a Chromium browser and its Linux libraries with the same runtime that executes your Function, then launch Chromium, load the page, choose print or screen media, call page.pdf(), and return or store the resulting bytes. A deployment that works on a developer laptop is not sufficient: the Azure image must contain the browser executable and every required shared library.

The deployment pattern that works

An HTTP-triggered Function can render a PDF in five stages:

  1. Choose one Functions language and worker model.
  2. Install a pinned Playwright package and Chromium for Linux.
  3. Make the browser binary and operating-system libraries available in the deployed image.
  4. Navigate to a controlled URL or HTML document, wait for the required content, and call page.pdf().
  5. Return the PDF bytes for a small response, or write them to durable storage for a longer workflow.

The critical distinction is between application dependencies and browser dependencies. Installing the npm package alone does not guarantee that Chromium or its Linux shared libraries exist in Azure.

Choose the Functions runtime and hosting route

Keep language, worker, package and image aligned

Azure Functions supports several languages on Linux. This example uses Node.js with Playwright, but Python and .NET isolated use different dependency manifests, startup settings and deployment procedures. Check the currently supported language and Functions versions before creating the app; lifecycle guidance changes over time. Microsoft’s supported-language documentation is the authority for availability.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Epson EcoTank ET-2800 Wireless Color All-in-One Supertank Printer - Black
  • INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
  • COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
  • ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
  • HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs
Decision Managed Functions build/runtime Custom Linux container
Browser dependencies Possible when the build and runtime image can install or carry Chromium and its libraries. Useful when the managed image or remote build cannot provide required operating-system packages or local binaries.
Operational work Less image maintenance, but you must verify what the selected image actually contains. You control the browser layer, but must maintain the image and follow the plan’s container requirements.
Best fit A supported language/plan with a reproducible Linux build. A workload with strict native-library requirements or a managed environment that cannot launch Chromium.

Microsoft identifies missing OS packages and local binaries as reasons to use a custom container in its Python Functions deployment guidance. That recommendation is not universal for every language or plan: confirm the rules for your selected runtime.

Linux plan and lifecycle checks

For a .NET isolated Linux Function App, Microsoft documents FUNCTIONS_WORKER_RUNTIME=dotnet-isolated and a Linux base-image value such as DOTNET-ISOLATED|8.0. Containerized Function Apps on Premium or Dedicated plans require the documented image configuration and, for that scenario, WEBSITES_ENABLE_APP_SERVICE_STORAGE=false. Do not copy those settings into a Node.js or Python managed app without checking the matching guide.

Microsoft’s Python reference says Linux Consumption retirement is scheduled for 30 September 2028 and that Linux Consumption apps still running Functions runtime v3 stop after 30 September 2026. These are platform lifecycle dates, not performance guarantees; verify the current dates and supported versions when you deploy.

Prepare a Node.js Playwright Function

Install the application package

Create an HTTP-triggered Node.js Function using the Functions programming model supported by your chosen app. Install the Functions SDK and Playwright, and pin versions in your normal dependency manifest so a browser upgrade is deliberate rather than accidental:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install @azure/functions playwright

In a Linux build environment with package-manager access, Playwright documents both npx playwright install-deps chromium for operating-system dependencies and npx playwright install --with-deps chromium for the browser plus those dependencies. Use the command appropriate to your build image, then confirm that the resulting browser layer is included in the artifact deployed to Azure. The official browser guidance is at https://playwright.dev/docs/browsers.

Rank #2
Sale
Epson EcoTank Photo ET-8550 Wireless Wide-Format All-in-One Tank Printer
  • CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
  • INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
  • PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
  • ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴

Running the install command on a workstation does not install anything in Azure. Remote build settings, ignored files, deployment slots and container stages can all produce an image different from the one you tested locally.

HTTP-trigger implementation

The following Node.js handler launches the Chromium installed by Playwright, waits for the document to be usable, and returns a PDF. Adapt the registration syntax to the Functions programming model and Node.js version selected for your app.

const { app } = require('@azure/functions');
const { chromium } = require('playwright');

app.http('renderPdf', {
  methods: ['GET', 'POST'],
  authLevel: 'function',
  handler: async (request, context) => {
    const targetUrl = request.query.get('url');
    if (!targetUrl || !targetUrl.startsWith('https://')) {
      return { status: 400, jsonBody: { error: 'Provide an HTTPS url.' } };
    }

    const browser = await chromium.launch();
    try {
      const contextOptions = {};
      const browserContext = await browser.newContext(contextOptions);
      const page = await browserContext.newPage();
      await page.goto(targetUrl, {
        waitUntil: 'domcontentloaded',
        timeout: 45000
      });
      await page.waitForLoadState('networkidle', { timeout: 15000 }).catch(() => {});

      // page.pdf() uses print CSS by default. Enable this only when
      // the PDF should match the screen stylesheet.
      // await page.emulateMedia({ media: 'screen' });

      const pdf = await page.pdf({
        format: 'A4',
        printBackground: true,
        margin: { top: '16mm', right: '14mm', bottom: '16mm', left: '14mm' }
      });

      await browserContext.close();
      return {
        status: 200,
        headers: {
          'Content-Type': 'application/pdf',
          'Content-Disposition': 'inline; filename="page.pdf"'
        },
        body: pdf
      };
    } finally {
      await browser.close();
    }
  }
});

Validate and authorize the URL in production rather than accepting arbitrary destinations. An unrestricted renderer can be used to probe private network addresses, consume excessive memory, or fetch content your service is not allowed to access.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Control PDF layout and readiness

Print media is the default

The Playwright Page API states that “page.pdf() generates a pdf of the page with print css media.” It also returns the PDF buffer. See the Page API reference. If the screen stylesheet is the desired design, call await page.emulateMedia({ media: 'screen' }) before page.pdf().

Use print-specific CSS for intentional pagination:

@media print {
  .page-break { break-before: page; }
  .avoid-break { break-inside: avoid; }
}

The API accepts physical units for dimensions and margins, paper formats such as A4, landscape output, page ranges and background printing. Colors are modified for printing by default; when exact color appearance matters, use CSS such as -webkit-print-color-adjust: exact and test the result in the deployed environment.

Rank #3
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
  • SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
  • INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
  • KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
  • PREMIUM SUPPORT - Strong technical expertise to solve issues faster
  • THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.

Wait for the content that matters

Choose a readiness condition based on the page, not a universal recipe. A site that continuously polls may never become genuinely idle, while a page that inserts charts after navigation can appear complete too early. Prefer a specific selector, an application-ready flag or a bounded delay for known client-side work. A navigation timeout should produce a controlled error and close the browser in the finally block.

Return bytes or persist them

For a small synchronous response, send the buffer with Content-Type: application/pdf and a sensible disposition. For large documents, queued jobs or requests that may outlive the HTTP invocation, write the bytes to durable object storage and return a status or download reference. Azure’s infrastructure guidance lists a Storage account as required for a Function App and Application Insights as recommended. Your design should also set authorization, an allow-list, navigation and total execution timeouts, an output-size limit and cleanup rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Deploy Chromium and its Linux libraries

Managed build

Use a Linux build environment compatible with the Functions runtime and run the Playwright browser installation there. Pin the Playwright package, install Chromium with the matching command, and inspect the deployment artifact or startup logs to verify that the executable and shared libraries are present. Rebuild this layer whenever you upgrade Playwright or change the base image.

Custom container

Choose a custom Linux container when the managed image cannot supply the required libraries or browser binary. Start from the official Azure Functions base image for your language and plan, install the pinned Playwright package and Chromium dependencies during the image build, and follow the containerized Function App settings documented for that plan. Premium and Dedicated container deployments have different requirements from managed Consumption deployments; do not treat one Dockerfile or app-setting set as portable across all plans.

Architecture and filesystem

Build for the same Linux architecture and runtime family that executes the Function. A browser compiled or installed for a different architecture, or a browser written only to a transient build path, can fail even though the JavaScript code is correct. Keep temporary files in the writable location exposed by the Functions environment and remove them after the response or upload completes.

Rank #4
NDYIN Portable Printers Wireless for Travel, N80 Bluetooth Thermal Printer
  • Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
  • No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
  • Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
  • Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
  • The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Reliability, performance and security

Browser lifetime

Launching a browser for each invocation is simple and isolates crashes, but startup work is repeated. Reusing a process can reduce startup overhead, yet Functions workers can be recycled and concurrent pages increase memory pressure. If you reuse a browser, detect a crashed process, cap concurrent pages, close contexts in every path and recreate the browser after failure. There is no universal memory or concurrency limit for this workload in the cited documentation, so measure your own pages instead of adopting an arbitrary number.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Network and content controls

  • Allow only approved schemes and hosts; reject private-address targets if the service is internet-facing.
  • Supply authentication headers or cookies through a controlled server-side mechanism, never from untrusted query strings.
  • Set navigation, selector-wait and overall function timeouts.
  • Limit generated page count, output size and concurrent renders.
  • Log the target host, elapsed stages and failure category without logging secrets or full document contents.

Validate the deployed result

  1. Invoke the deployed Function with a small, deterministic HTTPS page.
  2. Check that the response has application/pdf and begins with the PDF signature when saved to disk.
  3. Open the file and inspect fonts, images, page breaks, backgrounds and screen-versus-print styling.
  4. Review Application Insights or Function logs for missing-library errors, browser launch failures, navigation timeouts and memory pressure.
  5. Repeat after a slot swap, package upgrade or base-image change; local success does not prove that Azure has the same libraries.

Troubleshooting common failures

Symptom Likely cause Fix
Executable doesn't exist or Chromium cannot launch The browser was not installed in the deployed artifact, or the path belongs to a developer machine. Run the Playwright install command in the Linux build/container stage and verify the resulting path at runtime.
Error naming a missing .so library Chromium’s Linux system dependencies are absent. Install dependencies with npx playwright install-deps chromium or --with-deps in a compatible image; use a custom container when the managed image cannot provide them.
Works locally, fails only in Azure Different architecture, base image, filesystem, environment variables or deployment output. Build on the same Linux family, inspect deployed files and logs, and avoid relying on workstation-global browser installations.
Blank or incomplete PDF Client-side content was not ready when capture began, or the page required credentials/resources unavailable to the browser. Wait for a specific selector or application signal, configure authorized context data, and capture a deterministic test page.
Navigation timeout The target keeps connections open, is blocked, or exceeds the configured limit. Use a bounded readiness strategy rather than unconditional networkidle, increase the timeout only when justified, and report a controlled failure.
Function becomes unstable under load Too many Chromium processes or pages consume worker memory. Limit concurrency, close contexts, cap output size and consider queue-based rendering or a plan/container sized for the workload.
PDF looks different from the browser page.pdf() selected print media and print color adjustments. Use emulateMedia({ media: 'screen' }) when appropriate, add print CSS, and set print color adjustment explicitly.

What Azure Playwright is—and is not

Microsoft describes Azure Playwright as a managed service for running Playwright tests at scale with reporting. The documentation used here does not position it as a PDF-rendering endpoint. A Function that creates a document still needs a browser process and its Linux dependencies in the Function’s own execution environment; do not substitute the service name for that deployment work.

Or skip the browser setup

If your input is a public web URL and you need a screenshot or PDF rather than a custom Azure rendering workflow, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP or PDF. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and each response identifies the result with X-Page-Verdict and X-Billed headers.

cURL (see the ScreenshotNeo API documentation):

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)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
require('fs').writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-element capture, dark mode, device presets and custom viewports, retina scale, PDF paper settings and page ranges, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

The Free plan includes 1,000 shots each month with no card. Paid plans are Starter $5 for 3,000 shots, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000 and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan. Start with the free ScreenshotNeo account (1,000 screenshots a month, no card).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does Playwright create PDF/A or tagged accessible PDFs automatically?

The cited Page API documents PDF generation and its rendering options, but do not establish PDF/A conformance or tagged-PDF accessibility output. Treat those as separate document-production requirements and verify them with a PDF validator if your workflow needs them.

Can I use an HTML string instead of a public URL?

Yes. Navigate to a controlled document or set page content in your Function, wait for its fonts and assets, then call the same page.pdf() sequence. Keep external asset access and document size bounded.

Where should a long-running render run?

A synchronous HTTP invocation is appropriate only when its execution time and output size fit your selected Functions plan. For work that may outlive a request, enqueue the job, render in a worker, store the bytes durably and expose a status or download reference.

Quick Recap

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.