feat(xl-pdf-exporter): add custom font and fontFamily options for CJK support - #2945
feat(xl-pdf-exporter): add custom font and fontFamily options for CJK support#2945nperez0111 wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthrough
ChangesPDF font configuration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/mantine
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
commit: |
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx (1)
266-271: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd regression tests for custom registration and page styling.
Existing tests can pass while either new contract is broken. Add coverage that supplies a local font registration, verifies the custom
Font.register()call, and verifies that the generatedPagereceives the configuredfontFamily. Add a local CJK fixture if feasible; do not depend on a remote font URL in the test.Also applies to: 295-301
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx` around lines 266 - 271, Add regression coverage for the PDF exporter’s custom font and page styling behavior: provide a local font fixture through the exporter options, verify Font.register receives that registration, and verify the generated Page receives the configured fontFamily. Keep the test independent of remote font URLs and include a local CJK fixture if feasible, covering both the registration block and the Page styling path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx`:
- Around line 266-271: Update the custom font registration logic in the PDF
exporter constructor around this.options.fonts and Font.register so
registrations cannot resolve to fonts from other exporters. Ensure overlapping
family names are rejected, deduplicated using a stable key, or isolated through
namespacing, while preserving deterministic registration behavior; alternatively
enforce and document that custom font family names must be globally unique.
---
Nitpick comments:
In `@packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx`:
- Around line 266-271: Add regression coverage for the PDF exporter’s custom
font and page styling behavior: provide a local font fixture through the
exporter options, verify Font.register receives that registration, and verify
the generated Page receives the configured fontFamily. Keep the test independent
of remote font URLs and include a local CJK fixture if feasible, covering both
the registration block and the Page styling path.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6ec575ce-9ee3-46c8-a309-6f8d9d58c01c
📒 Files selected for processing (2)
packages/xl-pdf-exporter/src/pdf/index.tspackages/xl-pdf-exporter/src/pdf/pdfExporter.tsx
| if (this.options.fonts) { | ||
| for (const f of this.options.fonts) { | ||
| Font.register(f); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
pnpm list `@react-pdf/renderer` `@react-pdf/font` --depth 4
files="$(fd -t f 'index.js' . 2>/dev/null | rg 'node_modules/@react-pdf/(font|renderer)/' || true)"
if [ -z "$files" ]; then
echo "Installed react-pdf sources were not found." >&2
exit 1
fi
printf '%s\n' "$files" | xargs -r rg -n -C 4 \
'FontStore|fontFamilies|sources\.push|exactFit|register ='Repository: TypeCellOS/BlockNote
Length of output: 2121
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Tracked pdfExporter file:\n'
git ls-files 'packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx' 'packages/xl-pdf-exporter/package.json' || true
printf '\nFont-related usages in tracked repository files:\n'
rg -n 'Font\.register|registerFont|fontsRegistered|fonts:' packages/xl-pdf-exporter -S || true
printf '\nPackage dependency versions:\n'
cat packages/xl-pdf-exporter/package.json | sed -n '1,220p'Repository: TypeCellOS/BlockNote
Length of output: 3938
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Inspect installed `@react-pdf/font` package manifests:\n'
find node_modules -path '*`@react-pdf/font`*' -maxdepth 8 -type f \( -name package.json \) -print | sort | sed -n '1,40p'
printf '\nInspect FontStore/register implementation candidates:\n'
find node_modules -path '*`@react-pdf/font`*' -maxdepth 9 -type f \( -name index.js -o -name *.js -o -name fontStore.js -o -name fontStore.d.ts -o -name FontStore.js \) -print | sort | sed -n '1,80p' | while read -r file; do
echo "--- $file"
rg -n -C 8 'FontStore|register|fontFamilies|sources\.push|sources =|fontSources|resolveFont' "$file" || true
doneRepository: TypeCellOS/BlockNote
Length of output: 16111
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Search for FontStore default export and imports in `@react-pdf/font`:\n'
find node_modules .pnpm -path '*`@react-pdf`+font@*' -type f \( -name index.js -o -name index.browser.js -o -name index.native.js -o -name index.umd.js \) -print | sort | while read -r file; do
echo "--- $file"
rg -n -C 8 'default export FontStore|new FontStore|FontStore|export const Font|export default|Font\.register' "$file" || true
done
printf '\nSearch for PDFExporter usage across repo:\n'
rg -n 'new PDFExporter|PDFExporter\(|from .*xl-pdf-exporter|xl-pdf-exporter|fonts:\s*\[' packages examples docs -S || trueRepository: TypeCellOS/BlockNote
Length of output: 3671
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'FontStore exported bindings across `@react-pdf/font` packages:\n'
find node_modules -path '*`@react-pdf/font`*' -maxdepth 9 -type f \( -name index.js -o -name index.browser.js -o -name index.native.js -o -name index.umd.js -o -name index.esm.js \) -print | sort | while read -r file; do
echo "--- $file"
sed -n '1,40p' "$file"
rg -n 'export( .*)?(default| {\s*\{| {\s*[A-Za-z])|new FontStore|Font.register' "$file" | sed -n '1,20p'
done
printf '\nRelevant PdfExporter registration section:\n'
sed -n '200,280p' packages/xl-pdf-exporter/src/pdf/pdfExporter.tsxRepository: TypeCellOS/BlockNote
Length of output: 1270
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'FontStore exported bindings across `@react-pdf/font` packages:\n'
find node_modules -path '*`@react-pdf/font`*' -maxdepth 9 -type f \( -name index.js -o -name index.browser.js -o -name index.native.js -o -name index.umd.js -o -name index.esm.js \) -print | sort | while read -r file; do
echo "--- $file"
sed -n '1,100p' "$file"
rg -n "export .*Font|new FontStore|Font\.register|fontStore" "$file" | sed -n '1,40p'
done
printf '\nRelevant PdfExporter registration section:\n'
sed -n '200,280p' packages/xl-pdf-exporter/src/pdf/pdfExporter.tsxRepository: TypeCellOS/BlockNote
Length of output: 7804
Keep custom font registrations isolated from the shared Font registry.
Font.register() uses one FontStore, appends sources to the same family, and resolve() can return a source registered by another exporter. If users pass overlapping families, reject duplicates, deduplicate with a stable key, namespace the family, or document that custom fonts family names must be globally unique.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx` around lines 266 - 271,
Update the custom font registration logic in the PDF exporter constructor around
this.options.fonts and Font.register so registrations cannot resolve to fonts
from other exporters. Ensure overlapping family names are rejected, deduplicated
using a stable key, or isolated through namespacing, while preserving
deterministic registration behavior; alternatively enforce and document that
custom font family names must be globally unique.
Summary
Adds
fontsandfontFamilyoptions toPDFExporterso users can register custom fonts and override the default font family, enabling support for non-Latin scripts like CJK (Chinese, Japanese, Korean) characters.Rationale
The PDF exporter only registers Inter and GeistMono fonts, neither of which contain CJK glyphs. When users export documents containing Mandarin or other CJK characters, the output is corrupted/unrecognizable. There was no way for users to register additional fonts or change the default font family.
Fixes #2037
Changes
fontsoption toPDFExporterconstructor — accepts an array of font registrations passed directly to react-pdf'sFont.register()fontFamilyoption to override the default"Inter"page font familyregisterFonts()after the built-in defaultsfontFamilyis applied to the page style intoReactPDFDocument()Fontfrom@react-pdf/rendererso users can register fonts without adding react-pdf as a direct dependencyImpact
Fully backward compatible — both new options are optional and default to the existing behavior. No changes to the default PDF output.
Testing
All 7 existing PDF exporter tests pass. Lint passes with no new warnings.
Checklist
Summary by CodeRabbit