Skip to content

Explore Vite transform for next/font/google imports (eliminate generated font catalog) #200

@southpolesteve

Description

@southpolesteve

Context

PR #57 solved the immediate problem of missing named exports by code-generating all ~1,923 Google Font exports from the Google Fonts API. This works and tree-shakes correctly, but it requires maintaining a generated file that needs periodic re-runs as Google adds new fonts.

How Next.js Does It

Next.js handles next/font/google entirely at compile time via an SWC transform:

  1. SWC detects import { Inter } from 'next/font/google'
  2. Rewrites const inter = Inter({...}) into a CSS import with query params
  3. A webpack loader downloads fonts and generates @font-face CSS at build time

The next/font/google module in Next.js only contains declare function type stubs. There's zero runtime JavaScript. The font system is a compile-time illusion.

Proposed Approach

We could implement a similar pattern using a Vite transform hook:

  1. Detect import { X } from 'next/font/google' in the importing file
  2. Rewrite it to import { createFontLoader } from 'vinext/shims/font-google-base'; const X = createFontLoader("X Name");
  3. The transform derives the font family name from the export name (same logic the Proxy already uses)

Benefits

  • No generated file to maintain (no need to re-run a script when Google adds fonts)
  • Works for any font automatically, including ones Google hasn't added yet
  • Zero bundle overhead (only fonts actually used get createFontLoader calls)
  • Closer to how Next.js handles it architecturally

Considerations

  • Need to handle edge cases: re-exports, dynamic imports, barrel files
  • IDE autocomplete would still need the .d.ts declarations file (could keep generating that separately)
  • Must work correctly in all three Vite environments (RSC, SSR, client)

Current State

The generated catalog from PR #57 works well and is the right solution for now. This issue tracks exploring the transform approach as a future improvement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions