1

I'm trying to use a custom font (RetroGaming.ttf) in my React project using Vite and Tailwind CSS v4, but the font isn't applying. The @font-face rule seems ignored, and the generated Tailwind class doesn't include the custom font in its font-family property.

Tech Stack

  • Framework: React (^19.0.0)
  • Build Tool: Vite (^6.2.0)
  • Styling: Tailwind CSS (^4.1.3)
  • CSS Processing: PostCSS (^8.5.3) with autoprefixer and @tailwindcss/postcss
  • Font File: [RetroGaming.ttf]

Goal

Define RetroGamingFont via @font-face and apply it using a Tailwind utility class font-custom-retro.

Problem

  1. The custom font doesn't render; elements use the fallback font.
  2. The production CSS bundle (dist/assets/) lacks the @font-face rule.
  3. The generated .font-custom-retro class only includes the fallback font (sans-serif), not RetroGamingFont.
  4. Browser dev tools show no 404 error for [/fonts/RetroGaming.ttf]
  5. The issue persists whether @font-face is in src/index.css or directly in index.html.

Configuration

tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      fontFamily: {
        'custom-retro': ['RetroGamingFont', 'sans-serif'], // Font definition with fallback
      },
    },
  },
  plugins: [],
}

postcss.config.js

export default {
  plugins: {
    '@tailwindcss/postcss': {}, // Required for v4
    autoprefixer: {},
  },
}

src/index.css (Currently empty regarding @font-face)

@import "tailwindcss"; /* Tailwind v4 import, placed first */
    
/* @font-face moved to index.html for testing */

index.html (Current state)

<!-- Inside <head> -->
<style>
  @font-face {
    font-family: 'RetroGamingFont';
    src: url('/fonts/RetroGaming.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
  }
</style>

Usage in CompatibilityForm.jsx

<h2 className="text-2xl font-custom-retro text-pink-400">...</h2>
<label className="font-custom-retro text-indigo-200">...</label>

What I've Tried

Correct Tailwind v4 Setup:

  • Using @import "tailwindcss"; in src/index.css
  • Using @tailwindcss/postcss plugin, no @tailwindcss/vite plugin.

@font-face Placement:

  • Tried in src/index.css (after @import) and directly in index.html <style> tag.

Neither worked.

File Path Verification:

  • Confirmed public/fonts/RetroGaming.ttf exists and /fonts/RetroGaming.ttf path is correct for public assets.

Font Name:

  • Simplified to RetroGamingFont (no spaces).

Dev Tools Inspection:

  • Verified .font-custom-retro class is applied, but computed font-family uses the fallback.
  • No network errors for the font file.

Question

Why isn't Tailwind CSS v4 / PostCSS / Vite correctly processing or recognizing the @font-face rule, preventing the custom font from being included in the font-family definition of the utility class? Is there a specific configuration step for custom fonts with Tailwind v4 and Vite that I'm missing?

1
  • Just an extra note: although you mentioned that you didn't use the new @tailwindcss/vite plugin, I'll still leave a guide here on how you can use TailwindCSS directly in Vite without PostCSS: How to install TailwindCSS v4 & Vite without PostCSS Commented Apr 15 at 17:19

2 Answers 2

1

CSS-first configuration (recommended)

Starting with TailwindCSS v4, the use of tailwind.config.js has been discontinued. Instead, a CSS-first configuration approach has been introduced. In the CSS-first configuration, you can customize your settings using the @theme directive. Various namespaces are available for this purpose.

Note: In this case, the tailwind.config.js file can be deleted.

With the --font-* namespace, you can declare fonts.

/* Still, I'll show an example using a font that's available online. */
@import url('https://fonts.cdnfonts.com/css/playground');

/* Note: The font won't work here due to the absence of an online TTF file. */
@font-face {
  font-family: 'RetroGamingFont';
  src: url('/fonts/RetroGaming.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@import 'tailwindcss';

@theme {
  --font-retro: 'RetroGamingFont', sans-serif;
  --font-playground: 'Playground', monospace;
  --color-clifford: #da373d;
}
</style>

<h1 class="font-retro text-clifford text-3xl font-bold underline">
  Hello world with Retro!
</h1>

<h1 class="font-playground text-clifford text-3xl font-bold underline">
  Hello world with Playground!
</h1>

Legacy JavaScript-based configuration

As an alternative, you can still use tailwind.config.js via the @config directive.

./src/index.css

@import 'tailwindcss';

@config './../tailwind.config.js';

@font-face {
  font-family: 'RetroGamingFont';
  src: url('/fonts/RetroGaming.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}

tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  theme: {
    extend: {
      fontFamily: {
        'retro': ['RetroGamingFont', 'sans-serif'],
      },
    },
  },
  plugins: [],
}

Note: In this case, there's no need to declare content property. TailwindCSS v4 comes with automatic source detection.

Sign up to request clarification or add additional context in comments.

Comments

0

The v4 tailwind does not use styles from the config, you will need to create your styles directly in your css file and create a variable.

@theme {
  --font-poppins: "Poppins", sans-serif;
}

You can use the font in your HTML:

<p class="font-poppins">Hello world</p>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.