quarto-dev / quarto-dev/quarto-cli
Typst: `_brand.yml` Google fonts download a Latin-only subset for CJK families
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 458
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
I have:
- searched the issue tracker for similar issues
- installed the latest version of Quarto CLI
- formatted my issue following the Bug Reports guide
Bug description
When a font is declared in _brand.yml with source: google and the document is rendered to typst, Quarto downloads the font from the v1 Google Fonts CSS API (https://fonts.googleapis.com/css). For CJK families that endpoint serves a Latin-only subset: for Noto Serif JP it returns a 48 KB TTF whose cmap has 218 codepoints and zero kanji and zero kana.
The result is that every Japanese character in the Typst output falls back to a system font, or renders as tofu (□) on a machine that has no Japanese font installed.
The v2 endpoint (https://fonts.googleapis.com/css2), which Quarto already uses for the HTML/SCSS path, returns the complete 7.5 MB font for the same family. So HTML output is unaffected and only Typst is broken.
This is easy to miss on a developer machine: if the same family also happens to be installed as a system font (common on macOS), Typst silently uses the system copy and the output looks correct. The failure only shows up on a clean machine.
| file size | cmap entries |
kanji | kana | internal name | |
|---|---|---|---|---|---|
v1 /css (what Quarto downloads) |
48,176 B | 218 | 0 | 0 | Noto Serif JP ExtraLight Regular |
v2 /css2 |
7,477,960 B | 16,726 | 12,744 | 189 | Noto Serif JP Regular |
Steps to reproduce
_brand.yml:
typography:
fonts:
- family: Noto Serif JP
source: google
base:
family: Noto Serif JP
report.qmd:
---
title: "Noto Serif JP from _brand.yml"
format:
typst:
keep-typ: true
---
吾輩は猫である。名前はまだ無い。
Latin text renders fine.
quarto render report.qmd
# What Quarto downloaded (48 KB -- the whole font is 7.5 MB):
find .quarto/typst/fonts -name '*.ttf' -exec ls -l {} \;
# Compile the kept .typ the way a machine without Japanese system fonts sees it:
quarto typst compile --font-path .quarto/typst/fonts --ignore-system-fonts report.typ actual.png
--ignore-system-fonts is only used to make the bug visible on a machine that happens to have a Japanese font installed; on a clean Linux runner a plain quarto render produces the same tofu.
The two URLs can be compared directly:
# v1 -- what Quarto requests for Typst: 48 KB, no CJK
curl -s -G https://fonts.googleapis.com/css --data-urlencode 'family=Noto Serif JP' | grep -o 'url([^)]*)'
# https://fonts.gstatic.com/s/notoserifjp/v33/xn71YHs72GKoTvER4Gn3b5eMRtWGkp6o7MjQ2bwxOtbHKrc.ttf
# v2 -- 7.5 MB, complete
curl -s 'https://fonts.googleapis.com/css2?family=Noto+Serif+JP' | grep -o 'url([^)]*)'
# https://fonts.gstatic.com/s/notoserifjp/v33/xn71YHs72GKoTvER4Gn3b5eMRtWGkp6o7MjQ2bwxOubA.ttf
Actual behavior
Every Japanese glyph is missing from the downloaded font, so the output is tofu:
Expected behavior
Your environment
- IDE: VS Code 1.132.0
- OS: macOS 26.5.2 (Apple silicon)
Quarto check output
Quarto 1.10.18
[✓] Checking environment information...
Quarto cache location: /Users/kazuharu/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.10.0: OK
Dart Sass version 1.101.0: OK
Deno version 2.7.14: OK
Typst version 0.15.1: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 1.10.18
Path: /Applications/quarto/bin
[✓] Checking tools....................OK
TinyTeX: v2026.03.02
Chromium (deprecated): 869685
(Run "quarto install chrome-headless-shell" to replace)
Chrome Headless Shell: (not installed)
VeraPDF: (not installed)
[✓] Checking LaTeX....................OK
Using: TinyTex
Path: /Users/kazuharu/Library/TinyTeX/bin/universal-darwin
Version: 2026
[✓] Checking Chrome Headless....................OK
Using: Chrome found on system
Path: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Source: MacOS known location
[✓] Checking basic markdown render....OK
[✓] Checking R installation...........OK
Version: 4.6.0
Path: /Library/Frameworks/R.framework/Versions/4.6/Resources
LibPaths:
- /Users/kazuharu/github/workshop-graduate-2026/rv/library/4.6/arm64
- /Library/Frameworks/R.framework/Versions/4.6/Resources/library
knitr: 1.51
rmarkdown: 2.31
[✓] Checking Knitr engine render......OK
[✓] Checking Python 3 installation....OK
Version: 3.14.6
Path: /opt/homebrew/Cellar/jupyterlab/4.6.2/libexec/bin/python
Jupyter: 5.9.1
Kernels: julia-1.11, julia-1.10, julia-1.12, nbstata
NOTE: No Jupyter kernel for Python found
[✓] Checking Julia installation...
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Typst rendering path that handles Google fonts declared in _brand.yml, and compare its v1 CSS request with the v2 endpoint already used by the HTML/SCSS path. Reproduce with report.qmd and quarto render, then inspect the downloaded files under .quarto/typst/fonts; done means a clean machine renders the Japanese text without tofu and the complete CJK font is downloaded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100