Fonts
Manage web font loading with a provider abstraction layer.
The fonts plugin handles web font loading through configurable providers. Google Fonts ('google'), Bunny Fonts ('bunny'), and Fontshare ('fontshare') resolve through unifont at build time and are emitted as concrete @font-face rules. Coollabs ('coollabs') and custom providers keep the stylesheet @import path, while 'none' performs no loading. Every configured token also gets a font-<token> shortcut.
Build-time provider access
Resolving Google, Bunny, or Fontshare requires provider network access while the engine initializes. Entries that unifont cannot resolve fall back to the existing provider stylesheet import instead of failing the build. Provider initialization and resolution exceptions also emit a fonts-provider-resolution-failed warning; an empty resolution falls back silently.
pnpm add -D @pikacss/plugin-fontsnpm install -D @pikacss/plugin-fontsyarn add -D @pikacss/plugin-fontsimport { defineConfig } from '@pikacss/unplugin-pikacss'
import { fonts } from '@pikacss/plugin-fonts'
export default defineConfig({
engine: {
plugins: [fonts()],
fonts: {
provider: 'google',
fonts: {
// Shorthand string: 'Name' or 'Name:weight1,weight2'
sans: 'Inter:400,500,600,700',
// Object form for italic or per-font provider overrides
mono: { name: 'Fira Code', weights: [400, 500], provider: 'bunny' },
},
},
},
})Each key under fonts (and families) is a token: the plugin registers a --pk-font-<token> CSS variable holding the resolved font-family stack and a font-<token> shortcut that applies it. Use the shortcut in your styles:
// Expands to { fontFamily: 'var(--pk-font-sans)' }
pika('font-sans')
// Or combine with other styles
pika('font-mono', { fontSize: '14px' })Tokens named sans, serif, or mono under fonts automatically get sensible fallback stacks (e.g. sans falls back to ui-sans-serif, system-ui, sans-serif).
Config
| Property | Description |
|---|---|
| provider | Default font provider used for entries that do not specify their own. Built-in options: 'google', 'bunny', 'fontshare', 'coollabs', 'none'. Default: 'google'. |
| fonts | Font families grouped by shortcut token. Each entry is a 'Name' / 'Name:400,700' shorthand string or a { name, weights, italic, provider, providerOptions } object; entries are loaded through their provider. |
| families | Raw font-family CSS stacks grouped by shortcut token. No provider loading is performed — use this for fonts that are already available. |
| imports | Additional stylesheet URLs, each wrapped in an @import url("...") rule and injected before legacy/custom provider imports. |
| faces | Explicit @font-face rule definitions for self-hosted or custom fonts. |
| display | font-display value applied to resolved @font-face rules and legacy provider imports. Default: 'swap'. |
| providers | Custom font provider definitions created with defineFontsProvider(), keyed by provider name. |
| providerOptions | Global defaults keyed by provider name. A font entry's providerOptions shallow-overrides these defaults before resolution; Google text maps to unifont glyph subsetting, while Bunny/Fontshare text requests retain the stylesheet path. |
Provider option precedence
Provider options have one canonical resolution rule, independent of whether the font is handled by unifont, a built-in stylesheet fallback, Coollabs, or a custom provider:
fonts: {
provider: 'custom',
providerOptions: {
custom: { text: 'GLOBAL', subset: 'latin' },
},
fonts: {
body: {
name: 'Example Sans',
providerOptions: { text: 'BODY' },
},
},
}The effective options for Example Sans are { text: 'BODY', subset: 'latin' }: global provider options are defaults and per-font options shallow-override them. An explicit null or undefined deletes an inherited option for that font. Deletion markers are removed during normalization, so providers receive an active-only effective map.
Custom providers receive the active-only EffectiveFontsProviderOptions map on each FontsProviderFontEntry.providerOptions. FontsProviderContext contains only request-global provider and display; there is no second provider-options source in the context. Built-in stylesheet providers batch fonts only when their supported effective options match, and emit separate stylesheet URLs when request-scoped options such as text differ.
See API Reference — Plugin Fonts for full type signatures and defaults.
Next
- Reset — CSS reset stylesheets.
- Typography — semantic prose styling.