Skip to content

feat: add self-hosted Inter font via Astro Fonts API#32

Open
mzngo wants to merge 1 commit into
masterfrom
feat/font-loading
Open

feat: add self-hosted Inter font via Astro Fonts API#32
mzngo wants to merge 1 commit into
masterfrom
feat/font-loading

Conversation

@mzngo
Copy link
Copy Markdown
Collaborator

@mzngo mzngo commented Apr 10, 2026

Problem

The starter ships with no font configuration, so typography falls back to the browser's default system-UI stack. This varies significantly across operating systems (San Francisco on macOS, Roboto on Android, Segoe UI on Windows) making the starter look inconsistent when demoed or forked.

What Changed

astro.config.mjs

  • Imports fontProviders from astro/config
  • Adds a fonts array configuring Inter (a neutral, highly legible variable font) via the Google provider
  • Sets cssVariable: '--font-inter' and weights: ['100 900'] to load the full variable weight range in a single file

src/layouts/Layout.astro

  • Imports and renders the <Font cssVariable="--font-inter" preload /> component in <head>
  • This injects: the @font-face declaration, the --font-inter CSS variable on :root, an auto-generated fallback font with size/ascent adjustments to prevent layout shift, and a <link rel="preload"> for the woff2 file

src/styles/global.css

  • Adds a @theme block that sets --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif
  • Tailwind's font-sans utility now resolves to Inter across all components without touching a single component file

How It Works (Astro Fonts API)

Astro's built-in Fonts API (stable since Astro 5.7) downloads font files from the provider at build time and copies them into the output directory alongside other static assets. At runtime, there is no request to Google's servers — fonts are served from the same origin. This means:

  • No cross-origin font request → no CORS or privacy concern
  • No render-blocking CDN dependency
  • Full font-display: swap applied automatically
  • Fallback font metrics adjusted automatically to prevent CLS

Benefits

  • Consistent typography — Inter renders identically across all browsers and OS
  • Zero runtime CDN cost — font files served self-hosted from /_astro/fonts/
  • No layout shift — preload link + fallback size-adjust eliminates FOUT flash
  • Config-driven — changing the font family in astro.config.mjs is one line; the CSS variable propagates everywhere automatically
  • Roadmap alignment — directly completes Phase 1.6 from the plan

Validation

  • astro check → 0 errors, 0 warnings
  • biome ci → 0 errors
  • astro build → builds cleanly; [assets] Copying fonts (1 file)... confirms font was downloaded and bundled
  • Verified @font-face, --font-inter CSS variable, preload link, and fallback font all present in generated HTML

@mzngo mzngo added the enhancement New feature or request label Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant