@docx-editor.dev/fonts
v2.21.1 · 2 published subpaths with full TypeScript signatures and JSDoc.
Subpaths
Package root
Word's own defaults (Calibri, Cambria, Times New Roman, Arial, Courier New) are proprietary and cannot ship in an open package. What CAN ship are the faces built to MATCH THEIR METRICS: matching advance widths for the glyphs they cover, though outlines differ slightly. Scripts outside that coverage still need a suitable native or app-supplied font.
Nothing loads until an app calls in. Importing this module fetches no bytes, and the editor engine never calls it on its own.
Functions (4)
defaultFontsfunctionSource ↗
Load the default-font bytes and report failures for the editor's fonts prop.
The editor registers these bytes under private aliases for measurement and paint. This loader leaves public CSS family names unchanged, so native fonts remain available when a packaged substitute lacks a script.
Non-cancellation face failures are WARNED, not thrown: one unavailable face degrades that family to fixed-width measurement rather than refusing the document. Pass onFailure to route them somewhere other than the console. Caller cancellation rejects with signal.reason before any per-face warnings or callbacks are produced.
declare function defaultFonts(options?: LoadDefaultFontsOptions & {
readonly onFailure?: (failure: DefaultFontLoadFailure) => void;
}): Promise<DefaultFontsFragment>;installDefaultFontFacesfunctionSource ↗
Deprecated. Does nothing and resolves to `0`. It does not fetch or register fonts. Remove this call. Supply [defaultFonts](defaultFonts) or [packagedFonts](packagedFonts) through the editor's `fonts` option for private font registration.
Compatibility stub for the removed page-wide font installer.
declare function installDefaultFontFaces(_options?: LoadDefaultFontsOptions & {
readonly document?: Document;
readonly loaded?: readonly DefaultFontSource[];
}): Promise<number>;loadDefaultFontsfunctionSource ↗
Load the packaged substitute faces for the given Word families ([WORD_DOCUMENT_DEFAULT_FAMILIES](WORD_DOCUMENT_DEFAULT_FAMILIES) by default) and return a configuration fragment: byte-backed sources for the SUBSTITUTE families plus the Word-name → substitute substitution map, so a document naming "Calibri" resolves without the host mapping anything.
Only the requested families' assets are fetched, in parallel. A face that fails to load appears in failures and the rest of the fragment stays usable — compose it anyway and the missing face measures via the engine's fixed fallback. Caller cancellation is different: the promise rejects with signal.reason and returns no partial failure report.
declare function loadDefaultFonts(options?: LoadDefaultFontsOptions): Promise<DefaultFontsFragment>;packagedFontsfunctionSource ↗
The packaged substitutes, served ON DEMAND: an editor-shaped font resolver that loads the families a document turns out to name, plus its default face, rather than every family this package ships.
Same call shape as googleFonts() from @docx-editor.dev/fonts/google, so the two compose by sitting next to each other rather than by being combined differently:
ts
const fonts = useFonts(packagedFonts()); // bundled faces only
const fonts = useFonts(packagedFonts(), googleFonts()); // and the Google catalog
Prefer this to [defaultFonts](defaultFonts) unless you need the eager guarantee. defaultFonts() loads all 20 faces of [WORD_DOCUMENT_DEFAULT_FAMILIES](WORD_DOCUMENT_DEFAULT_FAMILIES) — 7.4 MB — whichever document opens, because it is called before there is a document to ask. This is called AFTER the parse, so a file using only Times New Roman costs Liberation Serif plus the four Carlito faces instead.
A family loads when a document NAMES it, or when it is that document's DEFAULT face. The default counts because a run that authors no font still has to be measured in one. The engine reports Calibri as the default, so Carlito is a floor here: even a document naming none of the six loads it. Narrow that with [PackagedFontsOptions.allow](PackagedFontsOptions.allow) if a document's families are known in advance.
What you trade for that is one reflow. The eager form settles before the first layout, so the document paginates once; this form cannot know the families until the file is parsed, so the document opens on the engine's fixed measurer and re-paginates when the faces arrive. Nothing is fetched from a third party either way — the bytes are the ones inside this package.
The families are file-derived, so they are matched case-insensitively against the closed [ALL_WORD_DEFAULT_FAMILIES](ALL_WORD_DEFAULT_FAMILIES) list and never used to build a path. A name outside it resolves to nothing here; pair with googleFonts() to cover more.
declare function packagedFonts(options?: PackagedFontsOptions): PackagedFontsResolver;Interfaces (12)
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 |
DefaultFontLoadFailureinterfaceSource ↗
One face that did not load. family is the Word name that was asked for, file the packaged asset that failed, and diagnostic a human-readable cause — a missing manifest entry, an HTTP status, a byte-length mismatch against the baked manifest, or a thrown fetch error.
Non-fatal by design: the surrounding fragment stays usable and the affected family falls back to the engine's fixed measurement.
interface DefaultFontLoadFailure| Member | Type | Summary |
|---|---|---|
| diagnostic | string | |
| family | string | |
| file | string |
DefaultFontsFragmentinterfaceSource ↗
What loadDefaultFonts resolves to — composes as a FontConfigurationFragment.
interface DefaultFontsFragment| Member | Type | Summary |
|---|---|---|
| failures | readonly DefaultFontLoadFailure[] | Faces that failed to load; the rest of the fragment is still usable. |
| sources | readonly DefaultFontSource[] | |
| substitutions | readonly DefaultFontSubstitution[] |
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 |
FontAssetManifestEntryinterfaceSource ↗
One packaged font asset, as measured at packaging time.
byteLength and hash are baked here and CI-verified against the shipped files, so a fetched asset is content-checked without hashing at runtime.
interface FontAssetManifestEntry| Member | Type | Summary |
|---|---|---|
| byteLength | number | Exact packaged size. A fetch returning any other length is rejected. |
| file | string | Asset filename under the package's `assets/` directory, e.g. `Carlito-Bold.ttf`. |
| hash | string | `sha256:`-prefixed digest, re-derived and compared by the engine's admission path. |
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. |
LoadDefaultFontsOptionsinterfaceSource ↗
Options shared by [loadDefaultFonts](loadDefaultFonts) and [defaultFonts](defaultFonts). All fields are optional, so {} loads [WORD_DOCUMENT_DEFAULT_FAMILIES](WORD_DOCUMENT_DEFAULT_FAMILIES) over the global fetch.
interface LoadDefaultFontsOptions| Member | Type | Summary |
|---|---|---|
| families? | readonly WordDefaultFamily[] | Narrow or widen the families to load. The default is [WORD_DOCUMENT_DEFAULT_FAMILIES](WORD_DOCUMENT_DEFAULT_FAMILIES); pass [ALL_WORD_DEFAULT_FAMILIES](ALL_WORD_DEFAULT_FAMILIES) to add the families this package substitutes for that Word does not apply by default. |
| fetcher? | typeof fetch | Injectable for tests; defaults to global `fetch`. |
| signal? | AbortSignal | Cancels outstanding reads in `loadDefaultFonts` and `defaultFonts`. Cancellation rejects with `signal.reason`; it is not reported as one failure per face and does not call `onFailure`. |
PackagedFontsFragmentinterfaceSource ↗
What one [packagedFonts](packagedFonts) resolver call produced.
interface PackagedFontsFragment extends DefaultFontsFragment| Member | Type | Summary |
|---|---|---|
| families | readonly WordDefaultFamily[] | The Word families this call actually loaded, in [ALL_WORD_DEFAULT_FAMILIES](ALL_WORD_DEFAULT_FAMILIES) order. |
| supportedFamilies? | readonly WordDefaultFamily[] | Families this provider can serve, including faces not loaded by this request. |
PackagedFontsOptionsinterfaceSource ↗
How [packagedFonts](packagedFonts) behaves once a document hands it a family list. Every field is optional; packagedFonts() with no options serves any of the six families a document names, over the global fetch, warning to the console on failure.
interface PackagedFontsOptions| Member | Type | Summary |
|---|---|---|
| allow? | readonly WordDefaultFamily[] | Narrow what may ever be loaded. Omitted, any of the six substituted families a document names is fair game — [ALL_WORD_DEFAULT_FAMILIES](ALL_WORD_DEFAULT_FAMILIES), not the smaller set the eager loader defaults to. Set it to run against a shorter list. |
| fetcher? | typeof fetch | Injectable for tests; defaults to global `fetch`. |
| install? | boolean | Legacy registration option, retained for source compatibility. |
| onFailure? | (failure: DefaultFontLoadFailure) => void | Non-cancellation per-face failures. Defaults to a console warning; pass a handler to route them. Caller cancellation rejects the resolver without invoking this callback. |
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)
PackagedFontsResolvertypeSource ↗
What [packagedFonts](packagedFonts) returns: a marked resolver over the packaged substitutes.
type PackagedFontsResolver = ((request: FontOriginRequest) => Promise<PackagedFontsFragment>) & FontResolverMark;WordDefaultFamilytypeSource ↗
The common Word families this package can stand in for.
type WordDefaultFamily = 'Calibri' | 'Cambria' | 'Times New Roman' | 'Arial' | 'Courier New' | 'Century Gothic';Variables (4)
ALL_WORD_DEFAULT_FAMILIESconstSource ↗
Every Word family this package substitutes for, including the ones Word does not apply by default. NOT the default for [LoadDefaultFontsOptions.families](LoadDefaultFontsOptions.families) — pass it explicitly to load them all:
ts
const fonts = await defaultFonts({ families: ALL_WORD_DEFAULT_FAMILIES });
[packagedFonts](packagedFonts) covers the extra families on demand instead, so a document that never names Century Gothic never pays for its assets — from these same bundled bytes, with no network involved. googleFonts() covers them too, for an app already opted into the catalog.
ALL_WORD_DEFAULT_FAMILIES: readonly WordDefaultFamily[]FONT_ASSET_MANIFESTconstSource ↗
Every font asset this package ships, in generator order. Drives both loadDefaultFonts (which looks entries up by filename) and the packaging check that keeps the shipped bytes honest.
FONT_ASSET_MANIFEST: readonly FontAssetManifestEntry[]FONT_ASSET_ROOTconstSource ↗
Directory URL of the packaged font files this package serves.
Headless exporters pass this to Core createPackagedFileFetch as trustedRoot. The value comes from the same packaged face URLs the loaders fetch, so the trusted directory matches Node, Bun, pnpm, Yarn PnP, and nested installs.
In a browser bundle this resolves to an HTTP URL rather than a file: one. That is why every consumer gates on FONT_ASSET_ROOT.protocol === 'file:': HTTP fetches do not use a trusted directory, and confining them to one would be meaningless.
Deriving this MUST NOT throw. It runs at module scope, so a throw here is uncatchable and takes down the whole bundle that imported this package rather than degrading font loading.
In Node, the DOCX_EDITOR_FONT_ASSET_ROOT environment variable relocates this directory. Single-file bundles set it to a copy of the package's assets/ directory that ships beside the executable, and every packaged face is then read from there.
FONT_ASSET_ROOT: URLWORD_DOCUMENT_DEFAULT_FAMILIESconstSource ↗
The families Word applies to a document by DEFAULT, and what [LoadDefaultFontsOptions.families](LoadDefaultFontsOptions.families) falls back to. Frozen — treat it as a constant rather than a mutable list to filter in place.
This is the load-every-document set, so it stays as small as correctness allows: a family here costs four faces on every load, whether or not the file names it.
WORD_DOCUMENT_DEFAULT_FAMILIES: readonly WordDefaultFamily[]