@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| Member | Type | Summary |
|---|---|---|
| family | string | |
| style | 'normal' | 'italic' | |
| weight | number |
DefaultFontSourceinterfaceSource ↗
A byte-backed source, structurally identical to the editor contract's FontSource.
interface DefaultFontSource| Member | Type | Summary |
|---|---|---|
| bytes | Uint8Array | |
| faceIndex | number | |
| hash | string | |
| id | string | |
| request | DefaultFontFaceRequest |
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| Member | Type | Summary |
|---|---|---|
| from | DefaultFontFaceRequest | |
| lineMetrics? | {
readonly heightEm: number;
readonly baselineEm: number;
} | |
| to | DefaultFontFaceRequest |
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| Member | Type | Summary |
|---|---|---|
| defaultFamily | string | The face a run naming no font resolves to. The engine reports Calibri by default. |
| families | readonly 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? | AbortSignal | Cancels 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| Member | Type | Summary |
|---|---|---|
| "docx-editor.dev/font-resolver" | true | Always `true`. Set non-enumerably on the resolvers this package builds. |
GoogleCjkOptionsinterfaceSource ↗
How googleFonts({ cjk }) loads Chinese, Japanese, and Korean faces.
interface GoogleCjkOptions| Member | Type | Summary |
|---|---|---|
| loading? | CjkFontLoading | Defaults 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| Member | Type | Summary |
|---|---|---|
| byteLength | number | Expected size; a response of any other length is rejected before use. |
| family | string | The family name a document would name, e.g. "PT Sans". |
| hash | string | `sha256:` digest the engine's admission path re-derives, catching a swapped CDN asset. |
| style | 'normal' | 'italic' | |
| url | string | Immutable, commit-pinned jsDelivr URL. |
| weight | 400 | 700 | Only 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| Member | Type | Summary |
|---|---|---|
| diagnostic | string | |
| family | string | The 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. |
| url | string | The 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| Member | Type | Summary |
|---|---|---|
| deferred? | Promise<GoogleFontsFragment> | With `cjk` loading in the background: the CJK faces, settled after they download. |
| failures | readonly GoogleFontLoadFailure[] | |
| sources | readonly DefaultFontSource[] | |
| substitutions | readonly 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| Member | Type | Summary |
|---|---|---|
| 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 | GoogleCjkOptions | Serve 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 fetch | Injectable for tests and CSP-constrained hosts; defaults to global `fetch`. |
| onFailure? | (failure: GoogleFontLoadFailure) => void | Per-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| Member | Type | Summary |
|---|---|---|
| family | string | The family name, matched case-insensitively as Word matches font names. |
| style | 'normal' | 'italic' | Whether this is the upright or the italic face. |
| weight | number | CSS 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>>