Skip to content

Astro Fonts — Managing Typography and Font Optimization

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Astro Fonts. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Astro font management: add Google Fonts, self-host fonts, optimize font loading, and implement font-display strategies for better performance.

In this lesson, you'll add custom fonts to your Astro project, self-host font files, configure font-display for optimal loading, and avoid layout shift.

What You'll Learn

How to add Google Fonts, self-host font files, use font-display to prevent layout shift, and optimize font loading with preload.

Why It Matters

Fonts affect perceived performance and layout stability. Poor font loading causes flash of invisible text (FOIT) and cumulative layout shift (CLS), hurting both user experience and SEO.

Real-World Use

DodaTech uses self-hosted fonts with font-display: swap to ensure text is immediately readable while fonts load in the background.

flowchart LR
    A[Choose Font] --> B[Self-Host or CDN]
    B --> C[font-display: swap]
    C --> D[Preload Key Fonts]
    D --> E[Stable Layout]
    style B fill:#ff5a03,color:#fff

Google Fonts

Add Google Fonts via a <link> tag in your layout:

---
const title = "My Site";
---
<html>
<head>
  <title>{title}</title>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" />
</head>
<body>
  <slot />
</body>
</html>

Output: The Inter font loads from Google's CDN with font-display: swap, so text renders immediately in a fallback font until Inter downloads.

Self-Hosting Fonts

Place font files in public/fonts/ or src/:

---
// Import from src/ (recommended — Astro processes it)
import interRegular from "../fonts/Inter-Regular.woff2";
import interBold from "../fonts/Inter-Bold.woff2";
---
<style>
  @font-face {
    font-family: 'Inter';
    src: url({interRegular}) format('woff2');
    font-weight: 400;
    font-display: swap;
  }
  @font-face {
    font-family: 'Inter';
    src: url({interBold}) format('woff2');
    font-weight: 700;
    font-display: swap;
  }
  body { font-family: 'Inter', sans-serif; }
</style>

Output: Fonts are self-hosted with cache-busting hashes. No external requests needed. font-display: swap ensures text is visible immediately.

Preloading Key Fonts

Add <link rel="preload"> for critical fonts:

---
import interRegular from "../fonts/Inter-Regular.woff2";
---
<html>
<head>
  <link rel="preload" href={interRegular} as="font" type="font/woff2" crossorigin />
  <style>
    @font-face { /* same as above */ }
  </style>
</head>
<body>
  <slot />
</body>
</html>

Output: The browser starts downloading the font immediately, before it encounters the @font-face rule in the CSS.

Font Display Strategies

Value Behavior Use Case
swap Show fallback, swap when font loads Most sites
block Hide text briefly (3s), then swap Brand-critical fonts
optional Use font only if already cached Performance-critical
fallback Short block (100ms), then swap Balance between

Subsetting Fonts

Reduce font file size by including only needed characters:

/* Include only Latin characters */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC;
  font-display: swap;
}

Common Mistakes

  1. Not using font-display: Without it, browsers use auto (typically block), causing invisible text while fonts load.
  2. Preloading too many fonts: Preload only your primary font. Preloading 3+ font files wastes bandwidth and delays other critical resources.
  3. Serving unused weights and styles: Each weight adds a separate file. Only include the weights you actually use in your design.
  4. Not subsetting fonts for non-Latin scripts: Full CJK (Chinese-Japanese-Korean) fonts can be 10+ MB. Subset to only needed characters.
  5. Using Google Fonts without preconnect: The preconnect hints reduce DNS lookup and connection negotiation time for the font CDN.

Practice Questions

  1. What does font-display: swap do? Answer: It renders text in a fallback font immediately and swaps to the custom font when it loads, preventing invisible text.

  2. How do you preload a font? Answer: Add <link rel="preload" href={fontPath} as="font" type="font/woff2" crossorigin /> in the <head>.

  3. What is font subsetting? Answer: Including only the specific characters (e.g., Latin, numbers) needed for your content, reducing file size.

  4. Why should you self-host fonts? Answer: Self-hosted fonts eliminate external DNS lookups and connection overhead, and give you full control over Caching.

Challenge

Set up a site with two self-hosted fonts: one for headings (bold weight only) and one for body text (regular + bold). Preload the body font and use font-display: swap for both.

Mini Project

Create a typography system for a blog: self-host Inter for body text (regular, bold) and Playfair Display for headings (regular only). Include preconnect hints, font preloading, and proper font-display values.

FAQ

Can I use variable fonts in Astro?

: Yes. Variable fonts combine multiple weights in a single file. Import one .woff2 file and use font-weight: 400-700 in CSS.

What formats should I use?

: WOFF2 is supported by all modern browsers. Include WOFF as fallback for very old browsers if needed.

How do I optimize Google Fonts loading?

: Add preconnect hints, use display=swap in the URL, and consider self-hosting for the best performance.

Can I use CSS `@import` for fonts?

: Avoid @import. It blocks rendering. Use <link> tags instead.

What's Next

Learn about Astro Styling for CSS strategies, scoped styles, and global styling approaches.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro