@cloudillo/fonts
Overview
The @cloudillo/fonts library provides a curated collection of Google Fonts metadata and pairing suggestions for Cloudillo applications. It enables font selection UIs, typography systems, and design tools.
Key Features:
- Curated font metadata for 22 Google Fonts
- Pre-defined font pairings (heading + body combinations)
- Helper functions for filtering and lookup
- Full TypeScript support
Installation
pnpm add @cloudillo/fontsFont Metadata API
FONTS Constant
The FONTS array contains metadata for all available fonts.
import { FONTS } from '@cloudillo/fonts'
// List all fonts
FONTS.forEach(font => {
console.log(font.displayName, font.category, font.roles)
})Each font entry includes:
family- CSS font-family value (e.g.,'Roboto')displayName- Human-readable namecategory-'sans-serif' | 'serif' | 'display' | 'monospace'roles- Suitable uses:'heading' | 'body' | 'display' | 'mono'weights- Available font weightshasItalic- Whether italic variants existlicense-'OFL'or'Apache-2.0'directory- Font directory name
getFontByFamily
Look up a font by its family name.
import { getFontByFamily } from '@cloudillo/fonts'
const roboto = getFontByFamily('Roboto')
// { family: 'Roboto', category: 'sans-serif', roles: ['body', 'heading'], ... }
const unknown = getFontByFamily('Unknown Font')
// undefined
getFontsByCategory
Filter fonts by category.
import { getFontsByCategory } from '@cloudillo/fonts'
const serifFonts = getFontsByCategory('serif')
// Returns: Playfair Display, Merriweather, Lora, Crimson Pro, Source Serif 4, DM Serif Display
const displayFonts = getFontsByCategory('display')
// Returns: Oswald, Bebas Neue, Abril Fatface, Permanent Marker
Available categories:
sans-serif- Clean, modern fonts (Roboto, Open Sans, Montserrat, etc.)serif- Traditional fonts with serifs (Playfair Display, Merriweather, etc.)display- Decorative fonts for headlines (Oswald, Bebas Neue, etc.)monospace- Fixed-width fonts (JetBrains Mono)
getFontsByRole
Filter fonts by intended use.
import { getFontsByRole } from '@cloudillo/fonts'
const headingFonts = getFontsByRole('heading')
// Fonts suitable for headings: Roboto, Montserrat, Poppins, Playfair Display, etc.
const bodyFonts = getFontsByRole('body')
// Fonts suitable for body text: Roboto, Open Sans, Lato, Inter, etc.
Available roles:
heading- Suitable for titles and headingsbody- Suitable for body textdisplay- Decorative, for large display textmono- Monospace, for code
Font Pairings API
The library includes curated heading + body font combinations that work well together.
FONT_PAIRINGS Constant
import { FONT_PAIRINGS } from '@cloudillo/fonts'
FONT_PAIRINGS.forEach(pairing => {
console.log(`${pairing.name}: ${pairing.heading} + ${pairing.body}`)
})Available pairings:
| ID | Name | Heading | Body | Description |
|---|---|---|---|---|
modern-professional |
Modern Professional | Oswald | Roboto | Business presentations |
elegant-editorial |
Elegant Editorial | Playfair Display | Source Sans 3 | Articles and long-form |
clean-modern |
Clean Modern | Montserrat | Open Sans | Tech and startups |
readable-classic |
Readable Classic | Merriweather | Lato | Blogs and docs |
contemporary-tech |
Contemporary Tech | Poppins | Inter | Digital products |
literary-warm |
Literary Warm | Lora | Nunito Sans | Classic with friendly body |
light-minimalist |
Light Minimalist | Raleway | Work Sans | Minimal designs |
academic-formal |
Academic Formal | Crimson Pro | DM Sans | Scholarly content |
bold-impact |
Bold Impact | Bebas Neue | Source Serif 4 | Impactful headlines |
geometric-harmony |
Geometric Harmony | DM Serif Display | DM Sans | Cohesive DM family |
getPairingById
Look up a specific pairing.
import { getPairingById } from '@cloudillo/fonts'
const pairing = getPairingById('modern-professional')
// { id: 'modern-professional', name: 'Modern Professional', heading: 'Oswald', body: 'Roboto', ... }
getPairingsForFont
Find pairings that use a specific font.
import { getPairingsForFont } from '@cloudillo/fonts'
const robotoPairings = getPairingsForFont('Roboto')
// Returns pairings where Roboto is used as heading or body
getSuggestedBodyFonts
Get body font suggestions for a heading font.
import { getSuggestedBodyFonts } from '@cloudillo/fonts'
const bodyOptions = getSuggestedBodyFonts('Oswald')
// ['Roboto']
const playfairBodies = getSuggestedBodyFonts('Playfair Display')
// ['Source Sans 3']
getSuggestedHeadingFonts
Get heading font suggestions for a body font.
import { getSuggestedHeadingFonts } from '@cloudillo/fonts'
const headingOptions = getSuggestedHeadingFonts('Inter')
// ['Poppins']
const latoHeadings = getSuggestedHeadingFonts('Lato')
// ['Merriweather']
TypeScript Types
import type {
FontCategory,
FontRole,
FontWeight,
FontMetadata,
FontPairing
} from '@cloudillo/fonts'FontCategory
type FontCategory = 'sans-serif' | 'serif' | 'display' | 'monospace'FontRole
type FontRole = 'heading' | 'body' | 'display' | 'mono'FontWeight
interface FontWeight {
value: number // CSS font-weight value (400, 700, etc.)
label: string // Display name ('Regular', 'Bold', etc.)
italic?: boolean // Whether this is an italic variant
}FontMetadata
interface FontMetadata {
family: string // CSS font-family value
displayName: string // Human-readable name
category: FontCategory // Font category
roles: FontRole[] // Suitable roles
weights: FontWeight[] // Available weights
hasItalic: boolean // Has italic variants
license: 'OFL' | 'Apache-2.0'
directory: string // Font directory name
}FontPairing
interface FontPairing {
id: string // Unique identifier
name: string // Human-readable name
heading: string // Heading font family
body: string // Body font family
description: string // Pairing description
}Integration with FontPicker
The @cloudillo/fonts library works with the FontPicker component from @cloudillo/react.
import { FontPicker } from '@cloudillo/react'
import { FONTS, FONT_PAIRINGS, getSuggestedBodyFonts } from '@cloudillo/fonts'
function TypographySettings() {
const [headingFont, setHeadingFont] = useState('Montserrat')
const [bodyFont, setBodyFont] = useState('Open Sans')
// Get suggested body fonts when heading changes
const suggestedBodies = getSuggestedBodyFonts(headingFont)
return (
<div>
<FontPicker
label="Heading Font"
value={headingFont}
onChange={setHeadingFont}
/>
<FontPicker
label="Body Font"
value={bodyFont}
onChange={setBodyFont}
/>
{suggestedBodies.length > 0 && (
<p>Suggested body fonts: {suggestedBodies.join(', ')}</p>
)}
</div>
)
}Available Fonts
Sans-Serif
| Font | Roles | Weights |
|---|---|---|
| Roboto | body, heading | 400, 700 |
| Open Sans | body | 400, 700 |
| Montserrat | heading, body | 400, 700 |
| Lato | body | 400, 700 |
| Poppins | heading, body | 400, 700 |
| Inter | body | 400, 700 |
| Nunito Sans | body | 400, 700 |
| Work Sans | body | 400, 700 |
| Raleway | heading | 400, 700 |
| DM Sans | body | 400, 700 |
| Source Sans 3 | body | 400, 700 |
Serif
| Font | Roles | Weights |
|---|---|---|
| Playfair Display | heading, display | 400, 700 |
| Merriweather | heading, body | 400, 700 |
| Lora | heading, body | 400, 700 |
| Crimson Pro | heading, body | 400, 700 |
| Source Serif 4 | body | 400, 700 |
| DM Serif Display | heading, display | 400 |
Display
| Font | Roles | Weights |
|---|---|---|
| Oswald | heading, display | 400, 700 |
| Bebas Neue | heading, display | 400 |
| Abril Fatface | display | 400 |
| Permanent Marker | display | 400 |
Monospace
| Font | Roles | Weights |
|---|---|---|
| JetBrains Mono | mono | 400, 700 |
See Also
- React Components - Including FontPicker component
- @cloudillo/react - React integration library