@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/fonts

Font 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 name
  • category - 'sans-serif' | 'serif' | 'display' | 'monospace'
  • roles - Suitable uses: 'heading' | 'body' | 'display' | 'mono'
  • weights - Available font weights
  • hasItalic - Whether italic variants exist
  • license - '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 headings
  • body - Suitable for body text
  • display - Decorative, for large display text
  • mono - 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