Before
Inter loaded from Google’s CDN via a CSS What is reflow? The browser recalculating layout: the size and position of elements on the page. Swapping a fallback font for the real one at a different size triggers one. What is a render-blocking request? A request the browser must finish before it can paint the page. The page stays blank until it resolves.@import, plus hand-written @font-face blocks for a
couple of other weights, plus a hand-tuned fallback font to limit @import is a
Config
Astro 6’s Fonts API replaces all of that with one
array in astro.config.ts:
import { defineConfig, fontProviders } from 'astro/config';
export default defineConfig({
fonts: [
{
provider: fontProviders.google(),
name: 'Inter',
cssVariable: '--font-inter',
weights: [400, 500, 600, 700],
styles: ['normal'],
fallbacks: ['sans-serif'],
},
],
});
<Font cssVariable="--font-inter" preload />
fontProviders.google() names where the font comes from during the build only. Astro downloads it
once at build time, generates the fallback, hashes the file, and outputs it as a static asset
served from your own domain, same as any other file in dist/. No request to Google at page load.
Why this matters
Everything needed to render a page already sits on disk after a static build. The old @import
broke that: the page could go down because fonts.googleapis.com was down, not because of
anything in this repo. Fetching at build time removes that dependency.
Dropping the hand-tuned fallbacks and switching to build-time downloads took font payload on this site from ~280KB to ~126KB.
What broke on the upgrade
Astro 6 ships on What is rolldown-vite? Vite’s bundler swapped for Rolldown, a Rust rewrite. Same Vite API on the surface, but plugins like Tailwind’s don’t always hook into the pipeline the same way.
@tailwindcss/vitestopped resolving CSS correctly under rolldown-vite. Fix: run Tailwind through PostCSS instead (postcss.config.mjs+@tailwindcss/postcss).@fontsourcewoff2 files stopped being emitted. A font on a@fontsource-variableimport silently dropped its files from the build: no build error, just a 404 in production. Fix: move it into the Fonts API via thefontsourceprovider instead, which fetches and emits its own files rather than depending on the npm package’s output.
Adding a new font later
Updated 08 July 2026: two more gotchas, both silent (no build error, fonts just fall back to system defaults):
- A config entry alone emits nothing. The
@font-faceonly lands on a page once a<Font cssVariable="--font-x" />actually renders somewhere, same as thepreloadtags inLayout.astro. - A font token needs a matching Tailwind utility class to survive inside
@theme {}. A token only ever used asvar(--font-x), never as a class, gets dropped from the compiled CSS.
The way to catch either: check the built page’s actual @font-face rules, not just the config.
Closing thoughts
The upgrade took about an hour, most of it spent on the two rolldown-vite bugs, not the fonts. Nine
@font-face blocks and a hand-tuned fallback are gone, replaced by one array, and the site no
longer depends on Google’s servers.