October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
custom fonts

How to Use Font Weight with Custom Fonts in jsPDF

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

Register a real font face for each weight, give the faces one family name, and select the face with setFont. For example, register an Acme TTF as normal and an Acme Bold TTF as bold, then switch between them before writing text. CSS-like font-weight declarations do not load a font into jsPDF or manufacture a bold face.

This approach also solves a second common problem: jsPDF’s built-in PDF fonts cover only a limited ASCII code page. A registered TrueType font (TTF) with the needed glyphs is required for reliable Unicode output.

The reliable pattern: one family, multiple registered faces

jsPDF separates three jobs:

  • addFileToVFS stores font data in the document’s virtual file system.
  • addFont maps that file to a family and style.
  • setFont chooses the registered family and style for subsequent text.

For regular and bold text, use the same family name in both registrations and different styles. The files must contain the actual outlines you want rendered; registering only the regular file and requesting bold does not reliably create a heavier design.

Complete browser example

const doc = new jsPDF();

// regularTtf and boldTtf are binary-string contents of the TTF files.
doc.addFileToVFS("Acme-Regular.ttf", regularTtf);
doc.addFont("Acme-Regular.ttf", "Acme", "normal");

doc.addFileToVFS("Acme-Bold.ttf", boldTtf);
doc.addFont("Acme-Bold.ttf", "Acme", "bold");

doc.setFont("Acme", "normal");
doc.setFontSize(12);
doc.text("Regular text", 20, 20);

doc.setFont("Acme", "bold");
doc.text("Bold text", 20, 30);

doc.save("font-weight-example.pdf");

The registration order matters: load the binary data first, register each filename, then select the family/style. The family string is your own consistent label; it does not have to match the filename.

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

Getting the TTF data into your application

Use jsPDF’s font converter

The project documents a converter that turns TTF data into a JavaScript file containing the font data and registration code. This is convenient when the font is a fixed application asset: generate the module during setup, import it with your bundle, and call the generated registration code before setFont. Check the generated file and your bundler’s import rules; the important result is still a binary string passed through addFileToVFS and addFont.

Load a binary string directly

If your build already provides the font bytes, pass their binary-string representation directly:

import { jsPDF } from "jspdf";

const doc = new jsPDF();
doc.addFileToVFS("Acme-Regular.ttf", regularTtfBinaryString);
doc.addFont("Acme-Regular.ttf", "Acme", "normal");
doc.setFont("Acme", "normal");
doc.text("Unicode text: café — Привет — 你好", 20, 20);

Use a font whose glyph set includes every character you plan to write. A successful registration does not guarantee that a particular symbol exists in the file.

Choosing a weight

Preferred method: registered style variants

For predictable output, register each supplied face explicitly: normal, bold, and any other styles or weights for which you have real files. Then select them:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
doc.setFont("Acme", "normal");
doc.text("400-style copy", 20, 20);

doc.setFont("Acme", "bold");
doc.text("700-style copy", 20, 30);

This makes the family/style mapping visible in code and avoids assuming that jsPDF can synthesize or locate an unregistered weight.

Using the current weight argument

Current jsPDF API syntax also accepts a third argument:

doc.setFont(fontName, fontStyle, fontWeight);

For example:

doc.setFont("Acme", "normal", 700);

The current implementation normalizes combinations and treats 700 or bold with a normal style as bold in applicable cases. It also rejects certain conflicting combinations. Numeric-weight behavior is release-dependent, and the available documentation does not provide a complete compatibility matrix for every value or older version. If the exact appearance matters, install and verify the jsPDF version used by your project and prefer explicit registered faces.

Inspecting what jsPDF knows about your fonts

Call getFontList() after registration:

console.table(doc.getFontList());

Look for the family and style variants you expect. If Acme appears only with normal, a later setFont("Acme", "bold") call cannot select a bold file that was never registered. Put this check in a development-only diagnostic path, not in production output generation.

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

Why a custom font still does not look bold

The bold file was never registered

Most often, code registers one TTF and then asks for a bold style. Add the actual bold TTF with the same family name and style bold. Verify the filename passed to addFont exactly matches the one passed to addFileToVFS.

The family names differ

Acme-Regular.ttf registered as family Acme and Acme-Bold.ttf registered as family Acme Bold are two unrelated families. Use one family label for all variants you intend to switch between.

The requested style is overwritten or selected too early

setFont affects text written after the call. Set the desired face immediately before each logical run, especially after helper functions that may change the active font.

The font itself has a subtle heavy face

“Bold” is a design property of the supplied outlines, not a guarantee of a particular visual thickness. Compare the TTF files outside jsPDF and confirm that the bold file really contains the intended face.

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

Unicode, glyph coverage, and encoding checks

Built-in PDF fonts are limited to an ASCII code page. For accented Latin, non-Latin scripts, symbols, or emoji-like characters, register a custom TTF that contains the required glyphs. Missing glyphs can appear as blank boxes, incorrect characters, or garbled output. Test representative text from every language your application emits, including punctuation such as em dashes and smart quotes.

Font registration is not a translation or fallback system. If one family lacks a glyph, jsPDF will not necessarily find a suitable second family automatically. Select another registered font for that run or choose a file with broader coverage.

Two packaging routes compared

Route Best fit What you manage
Font converter-generated JavaScript A fixed set of fonts shipped with the application Generated module files, imports, and your bundler’s handling of the embedded data
Direct binary-string registration Applications that already obtain font data dynamically or expose it through another asset pipeline Reliable delivery of the binary string and the registration calls at runtime

The documented material establishes both workflows but does not establish a speed or bundle-size winner. Choose based on how your build packages assets and whether fonts are static or dynamic.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting checklist

“Font does not exist” or fallback text

  • Confirm addFileToVFS ran before addFont.
  • Confirm the filename strings match exactly, including capitalization and extension.
  • Call getFontList() and check the family/style pair.
  • Call setFont with the registered family, not the TTF filename.

Bold request produces regular text

  • Register the bold TTF under the same family with style bold.
  • Use setFont("Family", "bold") before writing the text.
  • Check that a helper function did not reset the font afterward.
  • If using the third weight argument, verify the installed jsPDF release and avoid undocumented combinations.

Characters are missing or corrupted

  • Confirm the selected TTF contains those glyphs.
  • Test a minimal PDF with one problematic character.
  • Use the custom-font path rather than a built-in PDF font for Unicode output.
  • Ensure the font data was not converted to an incompatible text encoding before registration.

Output differs between environments

Lock the jsPDF version in your application, keep the same font files in every build, and test the generated PDF in more than one viewer. Do not infer compatibility from an old example that uses deprecated style-setting methods; prioritize the current setFont API.

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

Performance and reliability considerations

Embedding several TTF faces increases the document’s font data and therefore the amount of work and output data involved. Register only the families and weights the document needs, and avoid repeatedly registering the same files for every page or document instance. Registration belongs in the document setup path; selecting a face with setFont belongs next to the text that uses it.

For repeatable PDFs, keep font files under version control or another immutable asset process, record the jsPDF version, and include tests for regular, bold, and representative Unicode strings. The official documentation does not provide a universal performance benchmark, so measure your own browser, document size, and font set if generation time or bundle size is a constraint.

Or skip the browser setup

If your actual goal is to capture a web page as an image or PDF rather than generate a PDF with jsPDF, ScreenshotNeo provides a single screenshot API call. It handles cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status.

cURL

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)
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}`);

See the ScreenshotNeo documentation for request options. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Frequently Asked Questions

Can jsPDF make a bold custom font from only a regular TTF?

For dependable results, no. Supply and register the real bold face, then select its registered style.

How can I tell whether my bold face was registered?

Call getFontList() and inspect the family/style entries after registration.

Which font file format does this workflow document?

The documented custom-font workflow uses TrueType Font (.ttf) data.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.