Fonts and typography
Start with the theme overview for brand colors and design tokens. Cookbook configures font loading at build time and applies named presets to the rendered site.
The base typography presets are
body, heading, h1 through h6, navigation, small, and code. Onest
Variable is self-hosted and used for body and heading text by default, with a
continuous weight range from 100 to 900. This supports intermediate preset
weights such as 450 for navigation and 610 for headings. JetBrains Mono
Variable is self-hosted for code with weights from 100 to 800.
Both default fonts bundle their Latin subset and require no Google Fonts
requests at build time or in the browser. For other character sets, configure
theme.fonts with a Google family or local files as described below.
Specialized roles preserve the component sizes while sharing their base typography:
| Preset | Used for | Base typography |
|---|---|---|
hero-title |
Hero heading | h1, with a larger responsive size |
hero-tagline |
Hero description | body, with a responsive size and 1.55 line height |
prose |
Markdown content | body, at 1.025rem |
inline-code |
Code within prose | code, at 0.875em |
Customize these through theme.presets as well. Changes to the base font family,
weight, tracking, and other shared fields continue to flow into the derived roles.
Set theme.fonts to load fonts and apply them to the matching presets. A Google
Fonts family needs only its name:
theme: {
fonts: {
body: "Inter",
heading: "Newsreader"
}
}The short form follows the regular and strong weights in your configured presets, including heading and custom preset references. It requests normal and italic styles, prefers a variable range, and falls back to real static weights when ranges are unavailable. A font without italics produces a build warning; choose another family or select only its supported styles. To control the request exactly, list weights or ascending variable ranges and styles. Google Fonts must support them; see the Google Fonts CSS API for its available styles and weight syntax.
theme: {
fonts: {
body: { google: "Inter", weights: ["400 750"], styles: ["normal", "italic"] }
}
}For a font you own, put its files in public/fonts/ and give Cookbook their
public paths. Cookbook checks that each file exists during the build and adjusts
its URL for the Astro base path. A variable font can cover a weight range;
use separate entries for regular and italic files when needed:
theme: {
fonts: {
body: {
family: "Acme Sans",
files: [
{ src: "/fonts/acme-sans.woff2", weight: "100 900" },
{ src: "/fonts/acme-sans-italic.woff2", weight: "100 900", style: "italic" }
]
}
}
}The body role also feeds navigation and small text. heading feeds h1
through h6, while code covers code text. Each role has a system fallback.
Cookbook emits font faces through Tasty with font-display: swap. Google CSS
and font files are downloaded at build time and cached in
<Astro cacheDir>/cookbook-fonts. Files are served from your own site’s
_cookbook/fonts/ path by default, including the deployment base. Visitors make
no Google Fonts requests. Existing local-file definitions keep working.
theme: {
fonts: { body: "Inter" },
fontLoading: {
google: "self-hosted", // or "remote" to keep Google's font CDN URLs
cache: "reuse", // "refresh" to fetch again; "offline" to forbid network
display: "swap" // also auto, block, fallback, optional
}
}The first build requires network access. Preserve the Astro cache between CI
runs; offline fails with an actionable message when an entry is missing or
corrupt. Cache entries are content-verified and keyed by the exact request.
refresh deliberately updates them. For a fully checked-in font source, copy
licensed files into public/fonts/ and use the local form. Only wght and
ital axes are requested; use local variable files and Tasty typography styles
for other axes. Styles and weights that do not exist are rejected for explicit
requests. For static fonts, browsers select their nearest real weight;
intermediate weights require a variable font.
Migration: name-only Google font configuration now downloads the required
weights and italics and serves them locally. This increases the initial build’s
font downloads and removes visitors’ external font dependency. Set
fontLoading.google: "remote" to retain CDN delivery. Existing CSS-variable
weights that cannot be resolved from presets require explicit weights.
Presets merge property-by-property, so changing size, weight, or line height
does not require copying the rest of the preset. theme.presets takes precedence
over theme.fonts for an explicitly set fontFamily:
theme: {
presets: {
body: {
boldFontWeight: 680
},
heading: {
fontWeight: 650,
boldFontWeight: 740
},
h1: {
fontSize: "3rem",
letterSpacing: "-0.02em"
},
code: { fontSize: "0.9rem" }
}
}For a system or already loaded font, set its CSS family directly with
theme.presets.<role>.fontFamily. This does not load a font file. Additional
named presets are available to custom MDX components.
Heading presets reference the heading family and weights; body, navigation,
and controls reference body. Semantic strong and b elements use Tasty’s
strong modifier, so their weight comes from the active preset’s
boldFontWeight instead of a separate element-specific value. strong is a
reserved modifier keyword, not a named preset; the modifier-only form is
equivalent to inherit / strong. Body text uses a regular 400 weight and
neutral tracking, while
headings use a medium 610 weight and progressively gentle negative tracking.
The separate 720 heading bold weight keeps emphasized heading text distinct.
Navigation uses a lighter 450 weight with 580 for the current sidebar page,
while smaller group labels establish hierarchy without oversized bold text.
Inactive sidebar links use sidebar-text, a slightly softer blend of text-soft
and the surface. In high-contrast mode it matches text-soft. Set
theme.palette['sidebar-text'] to adjust that color without changing other
secondary text, or theme.styles.Sidebar.Control to customize the control.
See Search and navigation
for sidebar group and disclosure behavior. Inline code scales to 0.875em
of its surrounding text, including smaller table text; code blocks keep the
code preset size. Customize inline code through
theme.styles.MarkdownInlineCode.
Cookbook applies each semantic typography role through its complete Tasty
preset, so configured fields such as fontStyle and textTransform are not
silently omitted.
The exported DEFAULT_THEME_TOKENS and DEFAULT_TYPOGRAPHY_PRESETS constants
are useful when building a theme editor or presenting a reset action.