Fonts
How to wire the fonts a generated theme.dart names — bundle them or use google_fonts. flutterwindcss applies the theme's families automatically; you only register the font.
A generated theme.dart names the fonts the theme wants — for example:
const FwTypographyTheme _type = FwTypographyTheme(
sans: 'Outfit',
serif: 'Georgia',
mono: 'Geist Mono',
);These are family-name strings. flutterwindcss bundles no fonts, so there are two halves to getting them on screen:
- Apply the family to your text — this is automatic.
FwThemeapplies the theme'ssansfamily as the subtree's default, and.tw.fontSans/.fontSerif/.fontMonoresolve to the theme's families (just likeroundedMd/shadowMdresolve radius/shadow). You don't wire anything. - Register the font so Flutter actually has "Outfit" / "Geist Mono" — this is your job, and it's the only step. Pick one of the two recipes below.
Georgia (and other system faces) are usually already present on the OS, so they need no registration. You only register custom families like Outfit or Geist Mono.
Recipe 1 — bundle the font files (recommended)
Predictable and offline. Drop the .ttf/.otf files in your app and declare them under the exact
family names the theme uses:
flutter:
fonts:
- family: Outfit # must match typography.sans
fonts:
- asset: assets/fonts/Outfit-Regular.ttf
- asset: assets/fonts/Outfit-Bold.ttf
weight: 700
- family: Geist Mono # must match typography.mono
fonts:
- asset: assets/fonts/GeistMono-Regular.ttfThat's it — pass the generated theme and the fonts apply:
FwTheme(tokens: lightTheme, child: const HomeScreen());The theme stays const, the names line up, and .fontSerif / .fontMono switch families correctly.
Recipe 2 — google_fonts (no asset files)
google_fonts fetches and caches fonts at runtime. The
robust way to combine it with a generated theme is to build the theme's typography from the
families google_fonts registers — so the names always match:
flutter pub add google_fontsimport 'package:google_fonts/google_fonts.dart';
// Calling GoogleFonts.* registers the family and returns its name. Drop `const`
// from _type (and the FwTokens that use it) since these aren't compile-time.
final FwTypographyTheme _type = FwTypographyTheme(
sans: GoogleFonts.outfit().fontFamily!,
serif: GoogleFonts.ptSerif().fontFamily!,
mono: GoogleFonts.geistMono().fontFamily!,
);Because the theme's family strings are exactly what google_fonts registered, FwTheme's default and
.fontSans / .fontSerif / .fontMono all resolve to a font that's really there.
Why not just hardcode the names?
google_fonts registers each face under a family name; reading it back with .fontFamily (instead
of hardcoding 'Outfit') guarantees a match regardless of the package's internal naming. If you'd
rather keep the theme const, use Recipe 1.
Overriding a single family — and using fonts with no theme
font('Inter') sets a literal family for one chain (Tailwind font-[Inter]), independent of the
theme — handy for a one-off, and it needs no FwTheme at all. Don't combine it with
fontSans/fontSerif/fontMono in the same chain (the engine asserts, since both would set the
family).
You're not forced into a theme: with no FwTheme present, fontSans/fontSerif/fontMono fall back
to the stock FwTokens.light families (the generic sans-serif/serif/monospace) rather than
crash. So font('YourFont') is the no-theme path for a custom face; the role getters are the
theme-aware path. (See You're not forced into a theme.)
Interop path (MaterialApp)
On the pure path FwTheme applies the default family for you. Inside a MaterialApp, the host owns
the default text theme, so set the family there (e.g. ThemeData(fontFamily: lightTheme.typography.sans)
or a textTheme); .fontSans / .fontSerif / .fontMono still resolve to the theme via context.fw.
Next steps
Semantic tokens & theming
How theming works by semantic indirection — components reference roles, the theme resolves them, and swapping the theme reskins the whole app.
Conditional styling
Apply styles only in a state — hover, focus, pressed, disabled — and propagate state to descendants and siblings with groups and peers.