PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteRegister 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:
addFileToVFSstores font data in the document’s virtual file system.addFontmaps that file to a family and style.setFontchooses 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.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute#1 Best Overall
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:
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.
Rank #2
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.
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.
Rank #3
- hole punched
- high quality card stock
- 4 pages
- made in USA
- keyboard shortcuts
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.
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.
Rank #4
Troubleshooting checklist
“Font does not exist” or fallback text
- Confirm
addFileToVFSran beforeaddFont. - Confirm the filename strings match exactly, including capitalization and extension.
- Call
getFontList()and check the family/style pair. - Call
setFontwith 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.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →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.
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.
Quick Recap
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.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →




