-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Describe the bug
Version 4.3.1 introduced a regression bug that specifically breaks fontWeight: 700 for Noto Sans fonts. When registering Noto Sans with weight 700, the library throws "Unknown font format" errors during PDF rendering, even though:
- The TTF file is structurally valid (verified with fonttools/ttx)
- The TrueType magic bytes are correct (
00 01 00 00) - All other Noto Sans weights (100-600, 800-900) work perfectly in the same setup
- The exact same code and font files work fine in v4.3.0
Note: We have only tested this with Noto Sans fonts from two sources (see below). Other font families have not been tested, so the issue may be specific to Noto Sans weight 700, or it may affect other fonts as well.
To Reproduce
Steps to reproduce the behavior:
- Install @react-pdf/renderer v4.3.1:
npm install @react-pdf/[email protected]-
Download Noto Sans weight 700 TTF file (either source reproduces the issue):
-
Place the font file in your project (e.g.,
public/fonts/noto-sans-700.ttf) -
Register the Noto Sans font family including weight 700:
import { Font } from '@react-pdf/renderer';
import path from 'path';
const fontDir = path.join(process.cwd(), 'public', 'fonts');
Font.register({
family: 'Noto Sans',
fonts: [
{
src: path.join(fontDir, 'noto-sans-regular.ttf'),
fontWeight: 400,
},
{
src: path.join(fontDir, 'noto-sans-600.ttf'),
fontWeight: 600,
},
{
src: path.join(fontDir, 'noto-sans-700.ttf'),
fontWeight: 700, // This triggers the error in v4.3.1
},
],
});- Use the font in a PDF component:
import { Document, Page, Text, StyleSheet } from '@react-pdf/renderer';
const styles = StyleSheet.create({
page: { padding: 40, fontFamily: 'Noto Sans' },
title: { fontSize: 24, fontWeight: 700 },
});
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<Text style={styles.title}>Bold Title</Text>
</Page>
</Document>
);- Render the PDF in a Node.js environment (e.g., Next.js API route):
import { renderToStream } from '@react-pdf/renderer';
const pdfStream = await renderToStream(<MyDocument />);- Error occurs:
Error: Unknown font format
Expected behavior
The Noto Sans font with weight 700 should load and render correctly, just like weights 400, 500, 600, 800, and 900 do. There should be no "Unknown font format" error.
In v4.3.0 and v4.2.0, this exact code works perfectly with Noto Sans weight 700.
Version Comparison
We systematically tested v4.2.0, v4.3.0, and v4.3.1 with identical code and Noto Sans font files:
| Version | Weight 400 | Weight 500 | Weight 600 | Weight 700 | Weight 800 | Weight 900 |
|---|---|---|---|---|---|---|
| v4.2.0 | ✅ Works | ✅ Works | ✅ Works | ✅ Works | ✅ Works | ✅ Works |
| v4.3.0 | ✅ Works | ✅ Works | ✅ Works | ✅ Works | ✅ Works | ✅ Works |
| v4.3.1 | ✅ Works | ✅ Works | ✅ Works | ❌ FAILS | ✅ Works | ✅ Works |
Validation performed on the Noto Sans weight 700 TTF files:
-
Magic bytes verified (
00 01 00 00- valid TrueType signature):Format-Hex noto-sans-700.ttf -Count 4 # Output: 00 01 00 00
-
Font structure validated with fonttools (all tables valid, correct checksums):
python -m fontTools.ttx -l noto-sans-700.ttf # Output: All tables present and valid, no errors -
File size is appropriate (~28KB for GWfH subset, ~285KB for full Google Fonts binary)
-
Tested with multiple Noto Sans weight 700 sources:
- GWfH (google-webfonts-helper) latin subset:
noto-sans-v42-latin-700.ttf(~28KB) - Official Google Fonts repository:
NotoSans-Bold.ttf(~285KB, full character set) - Different filenames (to eliminate caching:
noto-sans-700-test.ttf) - All Noto Sans 700 sources produce identical "Unknown font format" error in v4.3.1
- All Noto Sans 700 sources work perfectly in v4.3.0
- GWfH (google-webfonts-helper) latin subset:
Environment
- OS: Windows 11
- Node.js: 22.x
- React: 19.2.0
- Next.js: 16.0.1
- @react-pdf/renderer versions tested:
- v4.2.0: Noto Sans weight 700 ✅ Works
- v4.3.0: Noto Sans weight 700 ✅ Works
- v4.3.1: Noto Sans weight 700 ❌ Fails
- Runtime: Node.js (Next.js API route with
export const runtime = 'nodejs') - Font tested: Noto Sans only (Google Fonts, various weights)
Additional Context
This regression is blocking our production deployment for generating invoices in a China-facing application where offline fonts are required.
Scope of our testing:
- Font family: Noto Sans only (we have not tested other font families like Roboto, Open Sans, etc.)
- Weights tested: 100, 200, 300, 400, 500, 600, 700, 800, 900
- Result: Only weight 700 of Noto Sans fails in v4.3.1; all other weights work
- Sources: Tested two independent sources of Noto Sans Bold - both exhibit the same behavior
- Other fonts: Unknown - we only tested Noto Sans
Workaround
We've locked to v4.3.0 which works perfectly with Noto Sans weight 700. Teams can work around this by:
- Using v4.3.0 instead of v4.3.1:
npm install @react-pdf/[email protected] - OR using Noto Sans weight 600 or 800 as alternatives to 700
Impact
For applications using Noto Sans, this is a critical regression because weight 700 (bold) is:
- The CSS standard for bold text
- Used universally in design systems
- Expected by designers and developers
- Breaking existing code that worked in v4.3.0
Request for maintainers:
We've thoroughly tested this with Noto Sans from multiple sources. If you need us to:
- Test with other font families (Roboto, Open Sans, etc.) to determine if it's Noto Sans-specific
- Provide our exact Noto Sans TTF files for reproduction
- Test additional scenarios or configurations
- Provide more debugging information
Please let us know! We're happy to help narrow down the root cause.
Thank you for maintaining this excellent library!