Repository navigation
Load standard fonts lazily via dynamic imports so a bundled Node build can render - #3571
Open
dbartholomae wants to merge 1 commit into
Open
dbartholomae wants to merge 1 commit into
dbartholomae wants to merge 1 commit into
Conversation
pdfkit's Node build reads each standard font's metrics from a file beside its own module on first use, which a bundler cannot follow. Load the metrics through dynamic imports with static specifiers and register them with pdfkit before the font is opened, in the Node and the browser build alike. The renderer waits for Helvetica before it creates its document, because pdfkit opens Helvetica in the constructor. Registration is skipped when pdfkit does not export registerStdFonts, so this works against pdfkit 0.20.x today and starts to cover the bundled case once the pin moves to a release carrying foliojs/pdfkit#1802. Fixes diegomura#3570
馃 Changeset detectedLatest commit: 03b1c05 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@dbartholomae is attempting to deploy a commit to the diegomura Team on Vercel. A member of the Team first needs to authorize it. |
dbartholomae
marked this pull request as ready for review
September 22, 2026 16:09
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3570
What
@react-pdf/fontloads each standard font's metrics through a dynamicimport('pdfkit/standard-fonts/<Name>')the first time a document uses that face, and hands them to pdfkit throughregisterStdFontsbefore it opens the font. The static specifiers let a bundler carry the metrics along, and the dynamic import keeps them lazy in both the Node and the browser build. The browser build no longer registers all fourteen fonts at import.@react-pdf/rendererawaits the font store's Helvetica load before it creates itsPDFDocument, because pdfkit opens Helvetica in the document constructor, before any layout has loaded a font.Why
pdfkit's Node build reads standard font metrics from a file beside its own module on first use. Bundled into another file it looks next to that file and finds nothing, and the
Cannot find module '#standard-fonts/Helvetica'in #3570 is the result. The fix in the issue was to keep pdfkit external, which works but is a workaround for a package that otherwise bundles fine.Depends on
pdfkit's Node build only exports
registerStdFontsfrom the release that carries foliojs/pdfkit#1802 on. The code reads the export from the module namespace and does nothing when it is missing, so this is mergeable against pdfkit 0.20.x now: unbundled, pdfkit's own file loaders keep working as before, and the bundled case starts working once the pin moves to a pdfkit release that has the export. #3550 bumps the pin to 0.20.2, which does not yet have it.Note for consumers:
Font.getFont()for a standard font now returnsdata: nulluntilFont.load()for that face has resolved, the same as for a registered font file.Checked
packages/font,packages/layoutandpackages/renderertests, the font package typecheck and build, eslint and prettier pass.packages/font/tests/standard-font.test.tscovers registering a face on first use, not registering unused faces, and registering a face once over repeated loads.@react-pdf/rendererfrom this branch against a pdfkit build that carries Let the Node build be bundled: exportregisterStdFonts, resolve standard fonts and the ICC profile on first use聽foliojs/pdfkit#1802 renders a document with text and a document without text, in ESM and CommonJS output. The same bundle against published pdfkit fails with the error from Node build can't render once bundled: pdfkit reads its standard fonts from disk next to its own module聽#3570, as expected.Written with Claude Code, an AI assistant; the change was designed and verified in our own bundles as described above.