API reference
Every export, option and signature in one place.
Three runtime exports, one of them a namespace, and the types behind them:
import { createUnifont, defineFontProvider, providers } from 'unifont'
import type { FontFaceData, FontProperties, ResolveFontOptions, ResolveFontResult, Unifont } from 'unifont'createUnifont()
function createUnifont<T extends [Provider, ...Provider[]]>(
providers: T,
options?: UnifontOptions,
): Promise<Unifont<T>>Providers are tried in order. The first one that knows a family answers.
Awaiting this starts every provider, and some fetch a whole family index to do it. Keep the instance rather than making one per request.
| Option | Type | Default | |
|---|---|---|---|
storage | { getItem, setItem } | in memory | Caching |
throwOnError | boolean | false | see below |
apiBase | string | false | the hosted proxy in a browser, otherwise unset | Browser and web containers |
By default a provider that fails to start, or throws from any of the three methods, is logged and skipped. Set throwOnError and you get the error instead.
resolveFont()
resolveFont(
family: string,
options?: Partial<ResolveFontOptions>,
providers?: string[]
): Promise<ResolveFontResult & { provider?: string }>You get back fonts, the @font-face descriptors; fallbacks, the generic families to put after yours in a stack; and the provider that answered.
Options are hints. Ask a provider that only serves woff2 for otf and you'll get woff2.
| Option | Type | Default |
|---|---|---|
weights | string[] | ['400'] |
styles | ('normal' | 'italic' | 'oblique')[] | ['normal', 'italic'] |
subsets | string[] | ['cyrillic-ext', 'cyrillic', 'greek-ext', 'greek', 'vietnamese', 'latin-ext', 'latin'] |
formats | ('woff2' | 'woff' | 'otf' | 'ttf' | 'eot')[] | ['woff2'] |
options | { [provider: string]: Record<string, unknown> } | none |
A weight range is one string with a space in it: '100 900'. The defaults above are exported as defaultResolveOptions.
Resolving fonts explains what each option does to the answer. What goes in options is up to each provider, and the built-in ones are under Providers.
listFonts()
listFonts(providers?: string[]): Promise<string[] | undefined>Every family name the providers will list, or undefined if none of them can. npm and adobe never list.
getFontProperties()
getFontProperties(
family: string,
providers?: string[]
): Promise<(FontProperties & { provider?: string }) | undefined>What a family publishes, from the first provider that knows it, and undefined when none of them do.
Two things to watch when you read the result. weights mixes discrete values ('400') with variable ranges ('100 900'). And a missing field means the provider doesn't publish that information, not that there's nothing to publish: formats in particular is what the provider can serve in general, so a format listed there may still be missing for the family you asked about.
Asking only some providers
All three methods take a list of provider names as their last argument. The default is every provider the instance was built with.
const unifont = await createUnifont([providers.google(), providers.bunny()])
await unifont.resolveFont('Poppins', {}, ['bunny'])
await unifont.getFontProperties('Poppins', ['bunny'])
await unifont.listFonts(['bunny'])FontFaceData
interface FontFaceData {
src: Array<{ name: string } | { url: string, format?: string, tech?: string }>
display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
weight?: string | number | [number, number]
stretch?: string
style?: string
unicodeRange?: string[]
featureSettings?: string
variationSettings?: string
metrics?: FontMetrics
meta?: { priority?: number, subset?: string, init?: RequestInit }
}A src entry with name is a local font, one with url is remote. meta.subset is the provider's own name for the range. meta.init holds a RequestInit for the few providers whose files need headers.
FontMetrics
interface FontMetrics {
unitsPerEm: number
ascent?: number
descent?: number
lineGap?: number
capHeight?: number
xHeight?: number
xWidthAvg?: number
}Values are in font units, using the same vocabulary as @capsizecss/metrics, so they can be used to generate fallback metric overrides (size-adjust, ascent-override, ...) without downloading and parsing the font file.
defineFontProvider()
function defineFontProvider<Name extends string, Options, FamilyOptions>(
name: Name,
provider: (options: Options, ctx: ProviderContext) => Awaitable<{
resolveFont: (family: string, options: ResolveFontOptions<FamilyOptions>) => Awaitable<ResolveFontResult | undefined>
getFontProperties?: (family: string) => Awaitable<FontProperties | undefined>
listFonts?: () => Awaitable<string[] | undefined>
} | undefined>
): (options?: Options) => Provider<Name, FamilyOptions>resolveFont() is the only method you have to write. Writing a provider covers the rest.