Skip to content

Tailwind CSS Custom Fonts — Adding Google Fonts and Web Fonts

DodaTech Updated 2026-06-28 5 min read

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

Tailwind CSS custom fonts are added by importing web fonts (Google Fonts, Adobe Fonts, or self-hosted), then registering them in the fontFamily theme configuration for utility class use.

What You'll Learn

You will learn how to import Google Fonts, self-host web fonts, configure custom font families in the config, apply them with font-* utilities, and manage font loading.

Why It Matters

Typography defines brand identity. DodaTech uses custom fonts across all products -- Inter for UI, Source Sans Pro for documentation -- configured once in Tailwind and used globally.

Real-World Use

Doda Browser uses Inter (sans-serif) for UI elements and JetBrains Mono for code snippets, both configured in tailwind.config.js as font-body and font-mono families.

flowchart LR
    A[Dark Mode] --> B[Custom Fonts]
    B --> C[Google Fonts]
    B --> D[Self-Hosted]
    B --> E[Config]
    B --> F[Loading]
    style B fill:#38bdf8,stroke:#0284c7,color:#fff
    style C fill:#22c55e,stroke:#16a34a,color:#fff

Google Fonts Setup

<!-- Step 1: Add to HTML head -->
<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;500;600;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
// Step 2: Configure in tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        display: ['Playfair Display', 'serif'],
      },
    },
  },
}
<!-- Step 3: Use in HTML -->
<p class="font-sans text-base text-gray-700">
  Body text using Inter (sans-serif).
</p>
<h1 class="font-display text-4xl text-gray-900">
  Heading using Playfair Display.
</h1>

Expected output: Body text renders in Inter, headings in Playfair Display. Both fonts load from Google Fonts with swap display Strategy.

Self-Hosted Fonts

/* Step 1: Add to your main CSS file */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-font.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-font-bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
// Step 2: Configure in tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        custom: ['CustomFont', 'sans-serif'],
      },
    },
  },
}
<!-- Step 3: Use the font -->
<p class="font-custom text-lg font-bold">
  Text in self-hosted custom font.
</p>

Expected output: Text renders in the self-hosted font with fallback to sans-serif. The woff2 format provides modern browser compression.

Multiple Font Families

module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        serif: ['Merriweather', 'Georgia', 'serif'],
        mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
        display: ['Playfair Display', 'serif'],
        body: ['Source Sans Pro', 'sans-serif'],
      },
    },
  },
}
<div class="space-y-4 p-4">
  <p class="font-sans text-lg">font-sans: Inter (system-ui fallback)</p>
  <p class="font-serif text-lg">font-serif: Merriweather (Georgia fallback)</p>
  <p class="font-mono text-lg">font-mono: JetBrains Mono (Fira Code fallback)</p>
  <p class="font-display text-lg">font-display: Playfair Display</p>
  <p class="font-body text-lg">font-body: Source Sans Pro</p>
</div>

Expected output: Five different font families applied via utility classes, each with appropriate fallbacks.

Font Loading Strategy

<!-- Preloading critical fonts -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>

<!-- Using font-display: swap -->
<style>
  @font-face {
    font-family: 'Inter';
    src: url('/fonts/inter-var.woff2') format('woff2');
    font-display: swap; /* Shows fallback immediately, swaps when loaded */
  }
</style>

<!-- FOUT (Flash of Unstyled Text) management -->
<div class="text-gray-900">
  <p class="invisible font-loaded:visible">
    Text hidden until font loads (prevents FOUT).
  </p>
</div>

Expected output: With font-display: swap, text is visible in fallback font immediately and swaps to the custom font when loaded, preventing invisible text.

Custom Font with Weights

module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
      },
      fontWeight: {
        thin: '100',
        extralight: '200',
        light: '300',
        normal: '400',
        medium: '500',
        semibold: '600',
        bold: '700',
        extrabold: '800',
        black: '900',
      },
    },
  },
}
<div class="font-sans space-y-1">
  <p class="font-thin">font-thin (100) - requires Thin weight</p>
  <p class="font-light">font-light (300) - requires Light weight</p>
  <p class="font-normal">font-normal (400) - Regular</p>
  <p class="font-medium">font-medium (500) - Medium</p>
  <p class="font-semibold">font-semibold (600) - Semibold</p>
  <p class="font-bold">font-bold (700) - Bold</p>
</div>

Expected output: Different font weights applied. Ensure the font file includes all requested weights; missing weights fall back to the closest available.

Common Mistakes

1. Not Preconnecting to Google Fonts

Without preconnect links, the browser delays connecting to Google's servers, increasing perceived load time.

2. Using Too Many Font Weights

Each weight adds 100-300KB. Only include the weights you actually use. Too many weights bloat the page.

3. Not Setting Fallback Fonts

Without fallbacks, custom font failure leaves unstyled text. Always include system fallbacks like sans-serif, serif, or monospace.

4. Forgetting font-display: swap

Without swap, the browser may hide text for up to 3 seconds while the font loads, causing invisible text.

5. Importing Fonts in CSS Instead of HTML

CSS @import blocks rendering. Use HTML link tags with preconnect for faster font loading.

Practice Questions

  1. Where do you register custom font families? In tailwind.config.js under theme.extend.fontFamily.

  2. How do you prevent invisible text while fonts load? Use font-display: swap in @font-face or the Google Fonts &display=swap parameter.

  3. What is the benefit of preconnect? It establishes an early connection to the font server, reducing font loading latency.

  4. How many font families can you configure? As many as needed. Each key becomes a font-{name} utility class.

  5. What format is recommended for self-hosted fonts? WOFF2 for best compression. Fall back to WOFF for older browser support.

Challenge

Set up a project with 3 custom fonts: Inter for body text (400, 500, 600, 700), Playfair Display for headings (700), and JetBrains Mono for code (400, 700). Configure all in the Tailwind config and use them.

FAQ

Can I use variable fonts with Tailwind?

Yes. Variable fonts support all weights along a range. Load the variable font file and all weight utilities work.

How do I use Adobe Fonts with Tailwind?

Add the Adobe Fonts embed script to your HTML head, then register the font family name in the config.

Can I use local fonts without a build step?

Yes. Add @font-face in your CSS, register in the config, and build. The font files must be in your static directory.

What happens if a font weight is not loaded?

The browser falls back to the closest available weight. For example, font-extrabold falls back to bold (700) if 800 is not loaded.

How do I optimize font loading?

Preload the font, use font-display: swap, subset the font file, and serve woff2 format for modern browsers.

Mini Project

Build a typography showcase page with 3 font families: a display font for hero headings, a sans-serif for body text, and a monospace font for code snippets. Include responsive text sizes and proper font loading optimization.

What's Next

Now master Custom Colors for brand-specific color palettes. Combine custom fonts and colors for a complete brand identity system.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro