Back to templates

Template details

unplugin-fonts

Universal Webfont loader plugin for Vite, Nuxt, SvelteKit, and Astro that generates @font-face rules, preload links, and fallback metrics.

About this template

unplugin-fonts (Unfonts) is an open-source universal webfont loader plugin that generates @font-face rules, preload/prefetch links, and fallback font metrics for Vite, Nuxt, SvelteKit, and Astro projects, pulling fonts from Typekit, Google Fonts, Fontsource, or custom files.

What is unplugin-fonts?

unplugin-fonts is a build-time plugin that automates web font loading. It takes font configuration (provider, families, styles) and outputs a virtual CSS module (unfonts.css) plus head-injection tags for preconnect, preload, and prefetch. It runs inside Vite, Nuxt, SvelteKit, and Astro, and also shows a Webpack configuration (marked "not implemented yet"). The project is published on npm as unplugin-fonts and installs as a dev dependency.

Key Features

  • Provider support — Loads fonts from Typekit (via project ID), Google Fonts (CSS2 API), Fontsource npm packages, and local custom font files matched by glob patterns.
  • Automatic link injection — Generates <link rel="preconnect">, preload, and prefetch tags with configurable injection points (head, body, head-prepend, body-prepend) and a non-blocking defer renderer.
  • Font fallback metrics — Optionally generates fallback @font-face rules using the fontaine library, adding size-adjust, ascent-override, descent-override, and line-gap-override to reduce Cumulative Layout Shift, and rewrites existing font-family declarations automatically.
  • Custom font transformation — Custom provider accepts a transform(font) function to edit font weight or skip fonts before rule generation.
  • Flexible Google Fonts loading — Configure display (auto, block, swap, fallback, optional), load subsets via text, and define families as strings (weight 400 only) or objects with specific styles.
  • Variable font support — Fontsource provider can load variable font axes (e.g., wght, slnt, ital) for packages like @fontsource-variable/cabin.
  • Inline font-face option — inlineFontFace: true moves @font-face rules into an inline <style> tag in the HTML <head> to avoid render-blocking requests.
  • TypeScript definitions — Ships a client type reference (unplugin-fonts/client) for generated CSS module declarations.

Who is it for?

unplugin-fonts is built for front-end developers who want to optimize web font delivery without hand-writing CSS or managing font files.

  • Vite users — Add the plugin to vite.config.ts to generate and inject font rules for any provider.
  • Nuxt developers — Register the plugin in nuxt.config.js under the modules array and configure options via the unfonts key.
  • SvelteKit and Astro users — Integrate via the SvelteKit Vite config or Astro integration, then render head links with the provided unplugin-fonts/head module or component.astro.
  • Sites measuring Core Web Vitals — Use the fallback metrics feature to reduce CLS from web font swaps.

What can you do with unplugin-fonts?

  • Load Google Fonts without extra network round-trips: specify families and get preconnect, preload, and swap display rules generated at build time.
  • Serve self-hosted fonts from local files: point the custom provider at a glob like ./src/assets/fonts/*.ttf and the plugin creates the corresponding @font-face rules with weights derived from filenames.
  • Add fallback fonts to an existing design system: enable fallback: { category: 'sans-serif' } on any provider to auto-rewrite font-family declarations with a metric-compatible local fallback.
  • Package subsetted fontsource fonts: load only specific weights, styles, and subsets (e.g., latin-ext) to keep CSS small.

How does unplugin-fonts work?

After installing (npm i --save-dev unplugin-fonts), you add the plugin to your bundler config and choose a provider. At build time the plugin fetches or reads the font data, generates a virtual CSS file (unfonts.css) that you must import (required for custom and fontsource providers), and injects the appropriate <link> tags into your HTML output. For fallback metrics, it computes override values from the font's metrics via fontaine and rewrites your CSS font-family stack.

Alternatives

  • vite-plugin-fonts — The predecessor that unplugin-fonts provides a migration path from (import unfonts.css instead of virtual:fonts.css).
  • webfontloader — A runtime font loader library, marked as unmaintained in the project's resources.

FAQ

Does unplugin-fonts work with Webpack?

The README includes a Webpack configuration example, but it is marked "Not implemented yet". Only the Vite entry is demonstrated, along with Rollup in a comment. In practice, you should use the Vite, Nuxt, SvelteKit, or Astro integrations.

Do I need to import unfonts.css?

Yes, if you use the custom or fontsource providers. The README states: "Required if using custom or fontsource providers." For Google and Typekit, the generated CSS is injected via head tags, so no import is needed.

Is unplugin-fonts free?

The package is distributed as an npm package and installable with npm i --save-dev unplugin-fonts; the README does not list any paid tiers or plans, and the repository is publicly hosted on GitHub.

What is the defer option for?

The defer option (default true) enables a non-blocking renderer for Typekit and Google Fonts families. It injects a <link rel="preload" href="..." as="style" onload="this.rel='stylesheet'"> tag so the font stylesheet loads without blocking page rendering.

How does the fallback feature reduce layout shift?

When you enable fallback on a font family, the plugin generates a companion @font-face that uses a local system font (e.g., Arial) with metrics overrides (size-adjust, ascent-override, descent-override, line-gap-override) so the fallback takes up the same space as the web font, then rewrites font-family declarations to include this fallback. This prevents the layout shift that occurs when the web font swaps in.