@docx-editor.dev/fonts/google

@docx-editor.dev/fonts/google — Google-hosted faces, fetched on demand.

Nothing is fetched until a document turns out to name a family this module can answer. Open a file using only Calibri and exactly one family is fetched.

Be deliberate about this: it makes OPENING A DOCUMENT perform network requests, which the engine never does on its own. What keeps it safe is that a document-declared family is only ever a LOOKUP KEY against a closed, commit-pinned catalog, and every face is trusted by content hash rather than by origin.

Functions (1)

googleFontsfunctionSource ↗

A [FontResolver](FontResolver) that serves the document's declared families from the pinned Google catalog — plus the package's own bundled faces for families the catalog has no metric-compatible answer for — loading only what that document turned out to need.

ts <DocxEditor.Root fonts={googleFonts()} />

Same call shape as packagedFonts() from @docx-editor.dev/fonts, so the two compose by sitting next to each other: useFonts(packagedFonts(), googleFonts()) serves the bundled faces first and reaches the catalog only for what they do not cover.

Compose it with your own bytes by wrapping it — the resolver is an ordinary async function of the families, so a wrapper can merge fragments before returning.

declare function googleFonts(options?: GoogleFontsOptions): GoogleFontsResolver;

Interfaces (11)

DefaultFontFaceRequestinterfaceSource ↗

A concrete font face request, structurally identical to the editor contract's.

interface DefaultFontFaceRequest
MemberTypeSummary
familystring
style'normal' | 'italic'
weightnumber

DefaultFontSourceinterfaceSource ↗

A byte-backed source, structurally identical to the editor contract's FontSource.

interface DefaultFontSource
MemberTypeSummary
bytesUint8Array
faceIndexnumber
hashstring
idstring
requestDefaultFontFaceRequest

DefaultFontSubstitutioninterfaceSource ↗

One Word-name → substitute redirect, structurally identical to the editor contract's FontSourceSubstitution. from is the proprietary face a document asks for, to is the metric-compatible face this package actually ships.

interface DefaultFontSubstitution
MemberTypeSummary
fromDefaultFontFaceRequest
lineMetrics?{ readonly heightEm: number; readonly baselineEm: number; }
toDefaultFontFaceRequest

FontOriginRequestinterfaceSource ↗

The request both resolvers in this package take, structurally identical to the editor contract's FontResolutionRequest.

Named rather than written inline at each call site so a mismatch reports one line rather than a four-line structural wall.

interface FontOriginRequest
MemberTypeSummary
defaultFamilystringThe face a run naming no font resolves to. The engine reports Calibri by default.
familiesreadonly string[]Families the document declares, already name-validated and capped by the engine.
resolvedFaces?readonly ResolvedFontFace[]Faces an earlier origin in the same composition can already paint.
signal?AbortSignalCancels document-scoped resolution. `packagedFonts` rejects with `signal.reason` and does not translate cancellation into per-face failures or `onFailure` callbacks.

FontResolverMarkinterfaceSource ↗

The TYPE-level half of the resolver mark, structurally identical to the editor contract's FontResolverMark.

A string key rather than a symbol precisely so the two unify without this package importing anything from the engine: two unique symbol declarations in two packages are two different types. Because they unify, useFonts(packagedFonts()) typechecks against a FontOrigin list that REQUIRES the mark, and a hand-written resolver that forgot defineFontResolver does not.

interface FontResolverMark
MemberTypeSummary
"docx-editor.dev/font-resolver"trueAlways `true`. Set non-enumerably on the resolvers this package builds.

GoogleCjkOptionsinterfaceSource ↗

How googleFonts({ cjk }) loads Chinese, Japanese, and Korean faces.

interface GoogleCjkOptions
MemberTypeSummary
loading?CjkFontLoadingDefaults to `'background'`. See [CjkFontLoading](CjkFontLoading).

GoogleFontFaceinterfaceSource ↗

One fetchable face in the pinned catalog.

The catalog is a CLOSED set: a document-declared family is only ever a lookup key against it, never interpolated into a URL, so a crafted w:rFonts cannot redirect a fetch. Bytes are trusted by hash, not by origin.

interface GoogleFontFace
MemberTypeSummary
byteLengthnumberExpected size; a response of any other length is rejected before use.
familystringThe family name a document would name, e.g. "PT Sans".
hashstring`sha256:` digest the engine's admission path re-derives, catching a swapped CDN asset.
style'normal' | 'italic'
urlstringImmutable, commit-pinned jsDelivr URL.
weight400 | 700Only the two static weights; variable-only families are excluded by the generator.

GoogleFontLoadFailureinterfaceSource ↗

One face that did not arrive. Non-fatal: the resolver returns whatever else succeeded, and the affected family falls back to the engine's fixed measurement.

A hashMismatch does NOT appear here — bytes are trusted by content at the engine's admission path, which rejects them after this resolver has handed them over.

interface GoogleFontLoadFailure
MemberTypeSummary
diagnosticstring
familystringThe family of the face that failed to load — the SERVING name ("Carlito", "TeX Gyre Adventor"), not the name the document wrote. A document naming Calibri sees "Carlito" here, because that is the file that did not arrive.
urlstringThe pinned catalog URL, or the asset filename for a face served from the bundle.

GoogleFontsFragmentinterfaceSource ↗

What one resolver call produced, for callers that want it without the editor.

interface GoogleFontsFragment
MemberTypeSummary
deferred?Promise<GoogleFontsFragment>With `cjk` loading in the background: the CJK faces, settled after they download.
failuresreadonly GoogleFontLoadFailure[]
sourcesreadonly DefaultFontSource[]
substitutionsreadonly DefaultFontSubstitution[]
supportedFamilies?readonly string[]Families this provider can serve after applying allow and substitute options.

GoogleFontsOptionsinterfaceSource ↗

How googleFonts() behaves once a document hands it a family list. Every field is optional; googleFonts() with no options fetches any catalogued family a document names, over the global fetch, warning to the console on failure.

interface GoogleFontsOptions
MemberTypeSummary
allow?readonly string[]Narrow what may ever load, by the name of the face that would SERVE the request ("Carlito", "TeX Gyre Adventor"). Omitted, any family this module can answer is fair game; set it to run against a closed short list.
cjk?boolean | GoogleCjkOptionsServe Chinese, Japanese, and Korean families, such as SimSun, MS Mincho, and Malgun Gothic, with the regional Noto Sans face for each: JP, SC, TC, or KR. Off by default.
fetcher?typeof fetchInjectable for tests and CSP-constrained hosts; defaults to global `fetch`.
onFailure?(failure: GoogleFontLoadFailure) => voidPer-face failures. Defaults to a console warning; pass a handler to route them.
substitute?Readonly<Record<string, string>>Extra document-family - catalog-family mappings, merged OVER [GOOGLE_METRIC_SUBSTITUTES](GOOGLE_METRIC_SUBSTITUTES). Only metric-compatible pairs keep pagination Word-accurate; anything else trades line breaks for closer-looking glyphs.

ResolvedFontFaceinterfaceSource ↗

One face an earlier origin can already paint, structurally identical to the editor contract's FontFaceRequest.

interface ResolvedFontFace
MemberTypeSummary
familystringThe family name, matched case-insensitively as Word matches font names.
style'normal' | 'italic'Whether this is the upright or the italic face.
weightnumberCSS numeric weight; the packaged faces are 400 and 700.

Type aliases (2)

CjkFontLoadingtypeSource ↗

Whether a large CJK font download may delay the first paint.

- 'background': the faces install in a separate step, after the document's other fonts. The first paint never waits for them, and text in them can move once when they arrive. - 'wait': the faces install in the same step as the document's other fonts. A large document (over about 512 KB of uncompressed content) waits up to 2 seconds for them before its first paint. A small document paints at once and lays out again when all of its fonts arrive.

Either way, a document export that receives this resolver waits for the faces.

The same type as CjkFontLoading in @docx-editor.dev/fonts-cjk/browser.

type CjkFontLoading = 'background' | 'wait';

GoogleFontsResolvertypeSource ↗

What [googleFonts](googleFonts) returns: a marked resolver over the pinned catalog.

type GoogleFontsResolver = ((request: FontOriginRequest) => Promise<GoogleFontsFragment>) & FontResolverMark;

Variables (4)

GOOGLE_FONT_CATALOGconstSource ↗

Every face googleFonts() may fetch, sorted by family then weight then style. Closed and pinned: nothing outside this list is reachable, which is what makes resolving a document-declared family name safe.

GOOGLE_FONT_CATALOG: readonly GoogleFontFace[]

GOOGLE_FONT_FAMILIESconstSource ↗

Every family the catalog can serve, sorted — the set a font picker may offer.

GOOGLE_FONT_FAMILIES: readonly string[]

GOOGLE_FONTS_REVISIONconstSource ↗

The main google/fonts catalog revision. Some static aliases use older immutable revisions because their current upstream families are variable-only.

GOOGLE_FONTS_REVISION = "ea14f3c4c462af1d847b1abe96fcb3c3a8a66f97"

GOOGLE_METRIC_SUBSTITUTESconstSource ↗

Word families with a METRIC-COMPATIBLE catalogued stand-in: identical advance widths, so a document laid out on the substitute paginates like Word.

Arial and Helvetica are absent on purpose. Their match is Arimo, which google/fonts now ships variable-only, and the shaper refuses variation axes — a variable file would render bold at regular weight. packagedFonts() covers both from the bundle.

GOOGLE_METRIC_SUBSTITUTES: Readonly<Record<string, string>>