Fonts
raft-ui chooses font families for each theme, but it never loads font files. Your app decides how the fonts arrive: self-hosted, from a font service, or not at all.
What each theme uses
| Theme | Body (--r-font-sans) | Headings (--r-font-heading) | Monospace (--r-font-mono) |
|---|---|---|---|
| Brutal | Space Grotesk | Space Grotesk | Geist Mono |
| Elegant light | Geist | Inter | Geist Mono |
| Elegant dark | Geist | Inter | Geist Mono |
How a font stack is built
Every stack has three parts, in this order:
--r-font-sans: r-sans, "Geist", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, …;
/* ↑ alias ↑ theme font ↑ system fallbacks */- A logical alias:
r-sans,r-headingorr-mono. Nothing is registered under these names by default, so the browser skips them. Register a font under one of them to replace that role everywhere, with no theme override. - The theme’s family: Space Grotesk, Geist, Inter or Geist Mono. This family is used when the page has loaded it or when it is installed on the device.
- System fallbacks: used when neither of the above is available, so text always renders.
Without any font setup, raft-ui renders in system fonts.
Load the theme fonts
Self-hosted (recommended for production)
Serve the font files yourself and declare them with @font-face, using the family names from the table above:
@font-face {
font-family: "Space Grotesk";
src: url("/fonts/SpaceGrotesk-Variable.woff2") format("woff2");
font-weight: 300 700;
font-display: swap;
}
@font-face {
font-family: "Geist";
src: url("/fonts/Geist-Variable.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}Load only the families your themes actually use. An app that only renders Brutal needs Space Grotesk and Geist Mono.
From Google Fonts
This is what this documentation site does:
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400..700&family=Geist+Mono:wght@300..700&family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@300..700&display=swap");Put it in your app’s global CSS. Keep in mind that it makes every page request a third-party origin.
Use your own font
Register your font under the alias for the role you want to change. For example, to use your brand font for body text in every theme:
@font-face {
font-family: r-sans;
src: url("/fonts/Brand-Variable.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}r-heading covers headings. In Brutal, headings follow r-sans unless you register r-heading separately. r-mono covers code.
To change the font for only part of the page, or for only one theme, override the variable instead:
<ConfigProvider theme="elegant" themeOverrides={{ "--r-font-sans": '"Brand", system-ui, sans-serif' }}>
…
</ConfigProvider>Check the font weights
raft-ui uses these weights:
| Token | Value | Used for |
|---|---|---|
--r-common-font-weight | 400 | Body text, Elegant buttons and controls |
--r-common-font-weight-strong | 500 | Emphasis, Elegant strong buttons |
--r-button-font-weight (Brutal) | 500 | Brutal buttons |
--r-button-font-weight-strong (Brutal) | 700 | Brutal strong buttons |
Make sure the font you load provides these weights; a variable font covering 300–700 does. If your font lacks a weight, the browser synthesizes a fake bold or picks the nearest weight, so text can look heavier or lighter than intended. Adjust the tokens through themeOverrides if your font looks better at other weights:
<ConfigProvider theme="elegant" themeOverrides={{ "--r-common-font-weight-strong": "600" }}>…</ConfigProvider>