Embed custom fonts in our JavaScript PDF viewer
PDF files should render consistently across different PDF viewers. This consistency is possible because a PDF file can embed the fonts required for rendering.
However, in some cases — due to file size or other considerations — PDFs don’t embed fonts. When this happens, the PDF viewer relies on system fonts, which may cause rendering issues if the required fonts are unavailable.
Embedding fonts in PDFs is the best way to ensure accurate rendering, but this isn’t always possible, especially when working with third-party PDFs. Custom font path support addresses this issue.
Standalone Mode
You can specify an array of PSPDFKit.Font
instances when initializing PSPDFKit for Web under the PSPDFKit.Configuration#customFonts
property:
const fetcher = (fontFileName) => fetch(`https://example.com/${fontFileName}`).then((r) => { if (r.status === 200) { return r.blob(); } else { throw new Error(); } }); const customFonts = ["arial.ttf", "helvetica.ttf", "tahoma.ttf"].map( (font) => new PSPDFKit.Font({ name: font, callback: fetcher }) ); PSPDFKit.load({ customFonts // ...your additional options });
Consider that the array specified must remain constant between different instances of PSPDFKit for Web. So instead of specifying PSPDFKit.Configuration#customFonts
as a literal array expression, we recommend passing an identifier you can reuse between PSPDFKit instances, as shown in the previous example. This is because we check during runtime that the same array of fonts is being specified when loading instances by using referential equality for the comparison. If a different array is specified between loading attempts, the instance won’t load.
When constructing PSPDFKit.Font
instances, you need to identify a name
property with the file name and extension of the font asset, and a callback
that receives the same name as an argument where you can define the logic to use for retrieving the font. The callback must return a Promise
that resolves to a Blob
.
For optimizing subsequent loads of the fonts, you can make use of different caching strategies. For example, you can rely on HTTP caching headers returned from the server the font is fetched from, use a service worker in combination with the Cache API, use IndexedDB to store the font blobs on the client side, or use any kind of strategy that better suits your use case.
If the callback rejects or returns a different value than the expected blob, PSPDFKit will continue rendering the document using its built-in fallback fonts, and an error will be logged into the browser console.
PSPDFKit will invoke the specified callbacks before beginning to render your document, which is why it’s important to consider a good strategy to prevent an impact on user experience. Custom fonts are also going to be retrieved if PSPDFKit.preloadWorker
is used. As a result, once you reach the point of creating an instance, both the fonts and WebAssembly artifacts might already be available upfront.
Server-Backed Mode
You can expose a directory of fonts from the host machine to the Docker container by adding the following to your docker-compose.yml
file:
pspdfkit: volumes: - /font-directory-path-on-the-host:/custom-fonts
The font directory can be any directory that is accessible to your app, and all .ttf
, .ttc
, and .otf
files will be added to the font list of PSPDFKit.
Microsoft core fonts
Microsoft core fonts are widely used on the web and in PDFs. Adding them as custom fonts improves document conversion and rendering accuracy. Nutrient doesn’t include these fonts because Microsoft no longer provides them directly, and redistribution is prohibited by license. To use these fonts, download them from SourceForge and add them as custom fonts.
Using Emojis
To use emojis in your project, import the Windows-compatible Noto Color Emoji font. Currently, this is the only supported font for displaying emojis.