Astro has first-party support for loading fonts in a performant way. Until recently, we often reached for the community Astro Font package which is still fine for existing sites, but new projects should prefer the built-in fonts configuration in astro.config so providers and variants stay aligned with Astro releases.
The old flow was an integration-style workflow, whereas the first-party API declares local files or providers in one place, creates CSS variables, and avoids an extra dependency for the same performance.
Using a custom font
You can load a local font or from a provider with a quick update to the 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
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [ { provider: fontProviders.fontsource(), name: "Roboto", cssVariable: "--font-roboto", }, ],});Using the font
Now that we have the font configured we can add this to our site for use. A great way to do this is in our layout component’s head section.
---import { Font } from "astro:assets";---
<html> <head> <Font cssVariable="--font-sweet-candy" /> </head> <body> <slot /> </body></html>Once that’s in place, any page that uses that head will be able to grab the css variable and apply it wherever 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>Optimization
It’s sometimes necessary to have a font preloaded, especially if that font is largely above the fold. The one caveat here is that it can slow the rendering of the page since it’s a blocking request so it’s best to use it only if needed. In this case, we can add the preload attribute to the Font loading in the head.
<Font cssVariable="--font-sweet-candy" preload />Tailwind
I’m currently using Tailwind v4 on this site and it can use the variable as well.
@theme inline { --font-family-fira-code: var(--font-fira-code); --font-family-fira-sans: var(--font-fira-sans);}