React PDF generation guide

Generate and Download PDFs from React Securely

Add PDF downloads to a React application without exposing your conversion API key, using a trusted backend endpoint and Blob handling.

Updated

Key outcomes

Do not expose the PixelToPdf key in React

Environment variables embedded by a frontend build are visible to every visitor. Obfuscation does not protect them. A React SPA must call an endpoint owned by your application, and that backend calls PixelToPdf with the private key.

The backend should identify the user, validate which document they can export, build or retrieve the authorized HTML, and return only the resulting PDF bytes.

Give the frontend a narrow endpoint

Prefer a route such as POST /api/reports/:id/pdf over a generic endpoint that accepts arbitrary URLs. A narrow route is easier to authorize and prevents the browser from turning your account into an open conversion proxy.

  • Accept a document ID and approved presentation options.
  • Authenticate and authorize before generating HTML.
  • Set Content-Type to application/pdf and a safe attachment filename.
  • Map upstream failures to a clear 4xx or 5xx response.

Download the PDF from a React button

This component calls your own backend, reads the binary response as a Blob, and always revokes the temporary object URL.

DownloadReportButton.tsxReact
'use client';

import { useState } from 'react';

export function DownloadReportButton({ reportId }: { reportId: string }) {
  const [loading, setLoading] = useState(false);

  async function download() {
    setLoading(true);
    try {
      const response = await fetch(`/api/reports/${reportId}/pdf`, { method: 'POST' });
      if (!response.ok) throw new Error('The PDF could not be generated');

      const url = URL.createObjectURL(await response.blob());
      const link = document.createElement('a');
      link.href = url;
      link.download = `report-${reportId}.pdf`;
      link.click();
      URL.revokeObjectURL(url);
    } finally {
      setLoading(false);
    }
  }

  return <button onClick={download} disabled={loading}>{loading ? 'Generating…' : 'Download PDF'}</button>;
}

Handle large files and failures well

Disable duplicate clicks while a request is running and show an actionable error if generation fails. For a simple GET download, use an anchor instead of Blob handling so the browser owns the navigation and streaming behavior.

Abort a request when the user leaves only if canceling the browser request also cancels useful server work. Otherwise, let the backend finish and make the result available through your normal application workflow.

Frequently asked questions

Why can I not store the API key in a React environment variable?

Frontend environment variables are compiled into browser assets and can be inspected by users. Keep the key in a backend or server-side framework environment.

Do I need a PDF library in React?

No. React only requests and downloads the binary file. PixelToPdf performs the Chromium rendering through your backend.

Can I generate a PDF from the current React DOM?

For reliable output, create a dedicated server-rendered HTML document or a public export URL. Sending the current DOM would require additional serialization and may include interactive state or private data.

Continue building

Build your first conversion

Start with 75 free credits each month. No credit card required.