Astro has first-party support for loading fonts in a performant way: declare your fonts in astro.config.mjs, render them with the <Font /> component, and use the CSS variable it creates. This post covers that setup, when to preload, using the fonts with Tailwind, and how it compares to the community astro-font package I used before it existed.
Why font loading matters
- Performance: fonts are often some of the largest render-critical requests on a page. Loading only what you use, from the right place, keeps pages fast.
- Layout shift: a fallback font swapping to the real font can shift the page. Good fallbacks and
font-displaysettings reduce Cumulative Layout Shift (CLS). - SEO: page speed and Core Web Vitals feed into search rankings and user experience.
Add a custom font in astro.config
You can load a font from a local file or from a provider with a quick update to astro.config.mjs.
From a local file
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [ { provider: fontProviders.local(), name: "SweetCandy", cssVariable: "--font-sweet-candy", options: { variants: [ { src: ["./src/assets/fonts/SweetCandy.woff2"], weight: "normal", style: "normal", }, ], }, }, ],});From a provider (Google Fonts, Fontsource)
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [ { provider: fontProviders.fontsource(), name: "Roboto", cssVariable: "--font-roboto", }, ],});This site uses fontProviders.google() the same way for Fira Sans and Fira Code.
Use the font in a layout
Add the <Font /> component to your layout’s head.
---import { Font } from "astro:assets";---
<html> <head> <Font cssVariable="--font-sweet-candy" /> </head> <body> <slot /> </body></html>Any page that uses that layout can then use the CSS variable wherever it’s needed.
---import Layout from "../layouts/Layout.astro";---<Layout> <h1>In a world...</h1>
<p>The great Candy Queen has given the people a new...</p>
<style> h1 { font-family: var(--font-sweet-candy); } </style></Layout>Preload fonts in Astro
Preloading makes a font available as soon as the page starts loading, which helps when the font is used above the fold. The trade-off is that a preload competes with other critical requests, so only preload the fonts you need right away. Add the preload attribute to the <Font /> component:
<Font cssVariable="--font-sweet-candy" preload />Use Astro fonts with Tailwind v4
Tailwind v4 can use the same CSS variables in its theme.
@theme inline { --font-family-fira-code: var(--font-fira-code); --font-family-fira-sans: var(--font-fira-sans);}Before the built-in API: astro-font
When I relaunched this site with Astro in 2024, there was no built-in font API. Rishi Raj Jain sent a pull request that added his astro-font package, which is inspired by Next.js font optimization. Here is the diff of that pull request.
astro-font handles:
- Preloading fonts so styled text appears sooner.
- Font display strategy (
swap,block,fallback,optional) to control what shows while fonts load. - The initial CSS for font loading, so you don’t write it by hand.
- Fallback fonts so text stays readable, and layout stays stable, while the real font loads.
It still works for existing sites. For new projects, prefer the built-in fonts config so font providers and variants stay in step with Astro releases, and you have one less dependency. Big thank you to Rishi for the PR that got this site’s fonts in shape.
The Astro Discord is full of optimization nuggets if you want to go further.