astro-font is an Astro integration designed to automatically optimize fonts within your Astro projects. Inspired by the font optimization techniques used in Next.js.
It handles custom fonts, local font files, fonts served via Content Delivery Networks (CDNs), and Google Fonts to improve your website’s performance. This tool draws
Features
⚙️ Automatic Optimization: Optimizes Google Fonts, local fonts, custom fonts, and fonts from CDNs.
🎨 CSS font-display Control: Allows configuration of the font-display property (e.g., swap, block).
🎯 Targeted Application: Apply fonts globally or to specific elements using CSS selectors (selector).
💾 Fallback Fonts: Automatically generates fallback font configurations.
☁️ Cloudflare Workers Support: Compatible with deployments to Cloudflare Workers with specific setup.
🔌 Multiple Font Sources: Handles various font types and sources within the same configuration.
🚀 Preloading: Supports font preloading for critical font files.
🔧 CSS Variables: Assign font families to CSS variables (cssVariable) for flexible usage.
🏷️ Custom Fallback Names: Define custom names for generated fallback font families (fallbackName).
📥 Dynamic Fetching: Option to fetch remote fonts during build time and serve them locally (fetch: true).
Use Cases
- Edge Function Deployments: Use optimized fonts in Astro projects deployed to edge environments like Cloudflare Workers, following the provided compatibility steps.
- Performance Improvement: Integrate
astro-fontto optimize font loading, reducing Cumulative Layout Shift (CLS) and improving Largest Contentful Paint (LCP) in Astro websites. - Self-Hosting Google Fonts: Easily download Google Fonts during the build process and self-host them for better performance or compliance requirements.
- Local Font Management: Simplify the integration of custom local font files (
.ttf,.woff2, etc.) stored within your project, complete with automatic@font-facegeneration and fallbacks. - Flexible Font Styling: Apply different fonts or font styles to various sections of your website using CSS selectors or CSS variables for precise typographic control.
Installation
# npm
npm install astro-font
# yarn
yarn add astro-font
# pnpm
pnpm add astro-fontUsage
Integrate astro-font into your Astro project by adding the AstroFont component to the <head> section of your layout or page.
Google Fonts (Direct URL)
Configure astro-font to use a Google Fonts URL directly.
---
// src/layouts/Layout.astro
import { AstroFont } from "astro-font";
---
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>My Astro Site</title>
<AstroFont
config={[
{
name: "Poppins",
src: [], // Source array is empty when using googleFontsURL
googleFontsURL: 'https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap',
preload: true,
display: "swap", // Overrides display property in Google Fonts URL if needed
selector: "body", // Apply font to the body tag
fallback: "sans-serif",
},
]}
/>
</head>
<body>
<slot />
</body>Local Fonts
Reference font files stored locally within your project’s public directory or another accessible path.
---
// src/layouts/Layout.astro
import { join } from "node:path";
import { AstroFont } from "astro-font";
const isProd = import.meta.env.PROD;
// Adjust path based on environment (dev vs build) if needed, especially for SSR adapters
const fontBasePath = isProd ? '/' : join(process.cwd(), "public");
---
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>My Astro Site</title>
<AstroFont
config={[
{
name: "MyLocalFont",
src: [
{
style: 'normal',
weight: '400',
// Use join for robust path construction
path: join(fontBasePath, 'fonts', 'MyLocalFont-Regular.woff2')
},
{
style: 'bold',
weight: '700',
path: join(fontBasePath, 'fonts', 'MyLocalFont-Bold.woff2')
},
],
preload: true,
display: "swap",
selector: ".content", // Apply font to elements with class 'content'
fallback: "arial, sans-serif",
},
]}
/>
</head>
<body>
<main class="content">
<slot />
</main>
</body>Multiple Fonts & Configuration
Define multiple font configurations within the config array. You can mix Google Fonts and local fonts. Use selector for applying via CSS class/selector or cssVariable for usage with CSS variables.
---
// src/layouts/Layout.astro
import { join } from "node:path";
import { AstroFont } from "astro-font";
---
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>My Astro Site</title>
<AstroFont
config={[
{
name: "Poppins",
src: [],
googleFontsURL: 'https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap',
preload: true,
display: "swap",
selector: "body", // Apply Poppins to body
fallback: "sans-serif",
},
{
name: "Inter",
src: [
{
weight: '400',
style: 'normal',
path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf')
}
],
preload: false,
display: "swap",
fallback: "verdana, sans-serif",
cssVariable: "font-inter", // Define CSS variable --font-inter
fallbackName: "Inter Fallback Custom" // Custom name for fallback font stack
},
]}
/>
<style>
h1 {
/* Example usage of the CSS variable */
font-family: var(--font-inter);
}
</style>
</head>
<body>
<h1>Heading uses Inter via CSS Variable</h1>
<p>Body text uses Poppins via selector.</p>
<slot />
</body>Dynamic Fetching
To automatically fetch remote fonts (like Google Fonts) during the build and serve them locally, set fetch: true in the font configuration and add the astroFont integration to your astro.config.mjs.
// Example config in Layout.astro
<AstroFont
config={[
{
src: [],
name: 'Roboto',
googleFontsURL: 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap',
preload: true,
display: 'swap',
fallback: 'sans-serif',
fetch: true, // Enable fetching
// Optional: cacheDir: '.font-cache' // Specify cache directory
},
]}
/>// astro.config.mjs
import { defineConfig } from 'astro/config';
import { astroFont } from 'astro-font/integration';
export default defineConfig({
// ... other config
integrations: [
astroFont() // Add the integration
]
});This setup downloads the fonts specified in googleFontsURL into a local directory (default .fonts or specified by cacheDir) and includes them in your build output, modifying the CSS to point to these local copies.
Related Resources
- Astro Documentation: https://docs.astro.build/en/getting-started/ – Official documentation for the Astro framework.
- Google Fonts: https://fonts.google.com/ – A library of free, open-source fonts you can use with
astro-font. - Next.js Font Optimization: https://nextjs.org/docs/pages/building-your-application/optimizing/fonts – Documentation for the feature that inspired
astro-font.
FAQs
Q: How does astro-font improve website performance?
A: astro-font helps performance by automatically generating efficient @font-face rules, enabling font preloading, providing control over font-display to reduce layout shifts, and facilitating self-hosting which can improve load times compared to external font providers.
Q: Can I use astro-font with custom fonts not hosted on Google Fonts?
A: Yes, you can use astro-font with local font files (like .ttf, .otf, .woff, .woff2) stored in your project or fonts hosted on any CDN by providing the correct path or URL in the src configuration.
Q: Does astro-font work with Astro’s SSR mode on Cloudflare?
A: Yes, astro-font can work with Astro SSR on Cloudflare Pages. You need to enable the nodejs_compat flag in your Cloudflare settings and configure Vite to externalize Node.js built-ins as detailed in the astro-font documentation. For local fonts in this setup, ensure paths correctly reference the CDN URL in production builds.
Q: What is the difference between using selector and cssVariable?
A: The selector option directly applies the font family (including fallbacks) to elements matching the CSS selector you provide. The cssVariable option defines a CSS custom property (variable) containing the font family stack, which you can then apply manually using font-family: var(--your-variable-name); in your CSS.
Q: How does the fetch: true option work?
A: When fetch: true is set for a font configuration (typically used with googleFontsURL), the astro-font integration automatically downloads the specified font files during the build process. It saves them locally and updates the CSS to reference these self-hosted files instead of the original remote URLs.






