Skip to content

Allow configuring the PDFium worker as an external asset URL (CSP-friendly, no blob:) #628

Description

@IBRAHIMDANS

Problem

usePdfiumEngine({ worker: true }) instantiates the PDFium worker via:

new Worker(URL.createObjectURL(new Blob([/* inlined worker source */])), { type: 'module' })

(see dist/lib/pdfium/web/worker-engine.js)

This forces the worker to be created from a blob: URL. Apps with a strict
Content Security Policy must therefore allow:

worker-src 'self' blob:

For projects that aim for a tight CSP (no blob: in worker-src / child-src),
this is a blocker. There is currently no way to configure the worker location 
only wasmUrl is configurable.

Repro

1. Serve any app embedding <EmbedPDF> behind a CSP without blob: in
worker-src (or child-src fallback).
2. Open a PDF.
3. Console error:
Refused to create a worker from 'blob:...' because it violates the
following Content Security Policy directive: "child-src 'self'".

Proposal

Expose an option workerUrl (mirroring the existing wasmUrl) on
usePdfiumEngine / PdfiumEngine / createWebWorkerEngine:

usePdfiumEngine({
  wasmUrl: '/assets/pdfium.wasm',
  workerUrl: '/assets/embedpdf-worker.js', // <-- new
  worker: true,
});

When provided, the engine should do:

new Worker(workerUrl, { type: 'module' });

instead of the blob: URL path. When omitted, fall back to current behavior
(blob inlined) to preserve backward compatibility.

Bonus: ship the worker entry as a separate published file in the package
(e.g. @embedpdf/engines/worker) so bundlers (Vite/Webpack) can resolve it via
new Worker(new URL('@embedpdf/engines/worker', import.meta.url), { type: 'module' })
and bundle it as a static asset under the app origin.

Why this matters

- Strict CSP is a security best practice; blob: workers force a relaxation
that some compliance frameworks flag (banking, defense, healthcare).
- pdf.js, monaco-editor, and other workerized libs already expose the worker
as a configurable URL  EmbedPDF is currently the odd one out.
- No breaking change: opt-in via new option, default behavior preserved.

Alternative considered

Patch consumers to override worker-src 'self' blob: in CSP  works but
weakens the security posture for every page, not just PDF previews.

Environment

- @embedpdf/engines version: 2.14.2
- Bundler: Vite
- Browser: Chrome

Happy to open a PR if the maintainers agree on the API shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions