feat: implement next/font/google and next/font/local with build-time metrics#158
Open
feat: implement next/font/google and next/font/local with build-time metrics#158
Conversation
…metrics Reimplement both font modules with deterministic hashing, CSS sanitization, fallback font metrics via @capsizecss/metrics, and local font parsing via fontkitten. Build mode generates self-hosted @font-face CSS with size-adjust fallbacks matching Next.js behavior. - Extract shared font-utils.ts (sanitization, hashing, SSR injection helpers) - Extract font-metrics.ts (capsize math, Google/local metrics, fallback gen) - Rewrite google-fonts plugin: balanced-brace regex, import rename handling - Rewrite local-fonts plugin: build-time metrics injection, woff2 preloads - Add 752 tests across 6 test files (font-utils, font-metrics, font-google, font-local-transform, shims, check) - Zero `as any` or non-null assertions in test files
commit: |
|
Member
Author
|
/bonk review and fix. |
Collaborator
|
rebase onto latest main to fix your failing lint CI |
Contributor
|
@elithrar Bonk workflow failed. Check the logs for details. View workflow run · To retry, trigger Bonk again. |
Collaborator
|
/bigbonk run an extensive review over this change, fix any issues, and then re-review your fixes. Look at tests to ensure they are high quality and relevant. |
Contributor
|
PROMPT_TOO_LARGE: The prompt exceeds the model's context limit. |
southpolesteve
added a commit
that referenced
this pull request
Feb 27, 2026
…#158) Co-authored-by: ask-bonk[bot] <ask-bonk[bot]@users.noreply.github.com> Co-authored-by: southpolesteve <southpolesteve@users.noreply.github.com> Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>
blitss
added a commit
to streamloop/vinext
that referenced
this pull request
Apr 2, 2026
…parity)
- Fix import regex: [^;\n] prevents cross-line matching
- Add destructure detection for default import pattern (const { Font } = googleFonts)
- Remove isBuild gate — self-hosting runs in dev and build
- Build manual Google Fonts URL to avoid URLSearchParams encoding issues
- Copy woff2 to public/fonts/ for web serving
- Generate hashed font-family names (__FontName_hash)
- Generate fallback @font-face with size-adjust metrics via @capsizecss/metrics
- Inject _hashedFamily, _fallbackCSS, _fallbackFamily into font loader calls
- Runtime: handle hashed families with fallback in font-google-base.ts
- Add font-metrics.ts from PR cloudflare#158 for capsize metric calculation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
next/font/googleandnext/font/localparity with Next.js, including deterministic hashing, CSS sanitization, and build-time fallback font metrics via@capsizecss/metricsandfontkittenfont-utils.ts(sanitization, hashing, SSR injection) andfont-metrics.ts(capsize math, metrics lookup, fallback generation)Details
New files
packages/vinext/src/font-metrics.ts— Build-time module: capsize math, Google/local font metrics lookup, hashed font-family names, fallback @font-face generation (async, uses dynamic imports for@capsizecss/metricsandfontkitten)packages/vinext/src/shims/font-utils.ts— Shared runtime module: CSS sanitization helpers (escapeCSSString,sanitizeCSSVarName,sanitizeFallback, etc.), deterministic djb2 hashing,FontSSRStatecontainer, CSS injection helpers with dedup, shared:rootvariable dedup across font modulestests/font-utils.test.ts— 45 unit tests for all font-utils functionstests/font-metrics.test.ts— 55 tests including local font file parsing with real Inter woff2 fixturePlugin changes
index.ts): Balanced-brace matching replaces fragile[^}]*regex;localToOriginalmap handlesimport { Inter as MyFont }renames; build mode fetches CSS + woff2 files, rewrites font-family, generates fallback metricsindex.ts): Build mode reads font files viafontkitten, generates self-hosted CSS with hashed families and size-adjust fallbacksfont-utils.ts, eliminating ~400 lines of duplicationType safety
as anyor!non-null assertions in test filesGoogleFontsTestPlugin,GoogleFontProxy,Record<string, unknown>)Test coverage
unitsPerEm=0edge case, multiplelocalFont()calls per file, import renames, balanced-brace parsing, SSR injection dedupKnown limitations (pre-existing, not introduced here)
_selfHostedCSScontains absolute filesystem paths — production on Workers needs web-relative paths (requires separate rearchitecting)(this as any)._isBuildin plugins — pre-existing Vite ecosystem pattern