Customization

Fonts

Configure DOCX editor fonts with validated font bytes, substitutions, on-demand loading, and React and Vue font pickers.

Pass a font configuration through fonts. Use loadFonts() for application font files. Include each weight and style that your document uses.

CSS @font-face rules supply browser rendering only. The editor also needs font bytes to measure text.

The preview starts with Default fonts. Select Default + Google Fonts to add Lato, Arvo, and PT Serif to the toolbar font picker. Select document text, then choose a font. Changing the font source resets the preview.

Embedded DOCX fonts load automatically. Font names from the document do not authorize remote font requests.

Font configuration reference

The DOCX editor needs font bytes for text shaping and page layout. Choose the supplied font sources, selectable families, substitutions, and loading behavior.

Input to Root.fontsUse
FontConfigurationFragmentSupplies font sources, substitutions, or selectable families.
FontConfigurationSupplies a complete configuration with defaults and limits.
FontResolverLoads application-approved faces after document font requests become known.

Configuration fields

FieldWhat you can customize
sourcesValidated font bytes and their exact family, weight, and style descriptors.
supportedFamiliesSelectable provider families. Listing a family performs no fetch.
substitutionsMaps a requested face to a supplied substitute face.
defaultFontFamily and sizeHalfPoints for text with no font declaration. Default: Calibri, 22 half-points.
languageBCP-47 language tag for language-sensitive text shaping.
epochIdentifies the configured font byte set.
maxFontBytesPer-face admission limit. Lower it to restrict accepted font resources.

Use composeFontConfiguration to combine font origins. Earlier sources take priority for the same family, weight, and style. A directly supplied face takes priority over a substitution for that face. The composition freezes its configuration and arrays.

URL loading options

loadFonts returns admitted sources and typed failures. A failed source does not discard the other loaded faces. Cancellation rejects the loading operation through signal.reason.

OptionUse
sources[].urlAn explicit application-selected font URL.
sources[].familyThe font family supplied by those bytes.
sources[].weightInteger from 1 through 1000.
sources[].stylenormal or italic.
sources[].hashOptional expected sha256: content hash. Mismatched bytes are refused.
sources[].faceIndexFont collection face index. Defaults to 0.
cacheNameCache API bucket. Defaults to docx-editor-fonts.
fetcherApplication fetch implementation. Defaults to global fetch.
maxFontBytesPer-source byte limit. Defaults to the engine's hard limit.
signalCancels the request and its network operations.

The failure reasons are networkError, httpError, hashMismatch, overLimit, emptyResponse, invalidRequest, and malformed. Display useful feedback from the failure list before the application starts editing. A cache entry undergoes content validation before use.

Local bytes and on-demand loading

Use createFontSource when you already hold bytes from a file input, bundle, or application storage. It accepts a face descriptor and returns either a source or a typed failure. It also accepts faceIndex, an application id, and maxFontBytes where specified by its types.

A FontResolver receives requested families, defaultFamily, an optional cancellation signal, and optional resolvedFaces. Use resolvedFaces to avoid loading faces supplied by an earlier origin. Return a configuration, fragment, or undefined when the resolver covers none of the requested fonts. The editor calls the resolver after loading a document and when editing requests another family.

Use an application-owned family lookup to select remote assets. Do not turn document font names directly into network URLs. A network-backed resolver makes document opening fetch the assets your application approves.

Font picker customization

Use Toolbar.FontFamily for the default picker. Use its Trigger, Content, and Item parts to change the picker layout. Each item uses its family name as value. Use useFontFamily() for a complete application picker.

Hook memberMeaning
valueCurrent family, or null for mixed values or no document.
optionsValidated, deduplicated, sorted configured and document families.
isEnabledWhether the engine allows the font operation.
setValue(family)Applies a permitted font family change.

A selectable family does not prove that its bytes are loaded. The font catalog includes standard and document-declared choices. Use your loading configuration to provide those faces and their regular, bold, italic, and bold italic variants.

Layout and loading limits

Embedded document fonts enter the font pipeline automatically when usable. Opening a document does not automatically fetch remote font declarations. A CSS @font-face rule changes browser rendering but does not supply the shaping pipeline with bytes. Missing font coverage can change line breaks and page layout. Use onFontError for initialization failures and the loader's failure list for individual URL failures.

Keep the font configuration's identity stable after editing starts. Changing Root.fonts creates another editor instance and resets selection and undo history. Use a stable on-demand resolver when users must choose fonts during editing.

Load Google Fonts on demand

Combine packaged fonts with the Google Fonts provider. The allow list limits which Google families the editor can download.

Use the provider's onFailure callback to report failed downloads. A font formatting command can succeed before its font bytes arrive.

The provider fetches font files from a pinned Google Fonts catalog. It supplies bytes for text layout and browser rendering. A font change can change line breaks and pagination.

Create the configuration once. Pass it to DocxEditor.Root through fonts.

import { useFonts } from '@docx-editor.dev/react';
import { packagedFonts } from '@docx-editor.dev/fonts';
import { googleFonts } from '@docx-editor.dev/fonts/google';

const local = packagedFonts();
const remote = googleFonts({ allow: ['Lato', 'Arvo', 'PT Serif'] });

export function useContractFonts() {
  return useFonts(local, remote);
}

The toolbar font picker applies the selected family to selected text. Google Fonts download when the editor needs their font bytes.

React and Vue reference

Pass your DOCX bytes and loaded fonts to this component. The preview uses a fictional contract.

import { DocxEditor, type DocxEditorRootProps } from '@docx-editor.dev/react';
import { reviewModule, DocxEditorReview } from '@docx-editor.dev/pro/react';
import '@docx-editor.dev/core/styles/editor.css';

const modules = [reviewModule()];

export function ContractEditor({
  bytes,
  fonts,
}: {
  bytes: Uint8Array;
  fonts: DocxEditorRootProps['fonts'];
}) {
  return (
    <div className="docx-editor contract-workspace">
      <DocxEditor.Root
        document={bytes}
        fonts={fonts}
        modules={modules}
        author="Demo reviewer"
        mode="suggesting"
        reviewDisplayMode="all-markup"
      >
        <DocxEditor.Toolbar preset={false}>
          <DocxEditor.Toolbar.FontFamily />
          <DocxEditor.Toolbar.FontSize />
        </DocxEditor.Toolbar>
        <DocxEditor.Viewport style={{ height: 520 }}>
          <DocxEditor.Content />
          <DocxEditor.HyperLink />
          <DocxEditor.ContextMenu />
          <DocxEditorReview />
        </DocxEditor.Viewport>
      </DocxEditor.Root>
    </div>
  );
}

Load your font files

Host font files in your application. Load them before you mount the editor. This helper supplies bytes for measurement and rendering.

// contract-fonts.ts
import { loadFonts } from '@docx-editor.dev/core/editor';

export function loadContractFonts() {
  return loadFonts({
    sources: [
      {
        url: '/fonts/ContractSans-Regular.ttf',
        family: 'Contract Sans',
        weight: 400,
        style: 'normal',
      },
      {
        url: '/fonts/ContractSans-Bold.ttf',
        family: 'Contract Sans',
        weight: 700,
        style: 'normal',
      },
    ],
  });
}

Call the helper after mount. Keep loading failures visible.

import { useEffect, useState } from 'react';
import { DocxEditor } from '@docx-editor.dev/react';
import { loadContractFonts } from './contract-fonts';

type Fonts = Awaited<ReturnType<typeof loadContractFonts>>;

export function FontEditor({ bytes }: { bytes: Uint8Array }) {
  const [fonts, setFonts] = useState<Fonts>();
  const [failed, setFailed] = useState(false);
  useEffect(() => {
    let disposed = false;
    loadContractFonts().then(
      (value) => {
        if (disposed) return;
        if (value.failures.length > 0) {
          setFailed(true);
          return;
        }
        setFonts(value);
      },
      () => {
        if (!disposed) setFailed(true);
      }
    );
    return () => {
      disposed = true;
    };
  }, []);
  if (failed) return <p role="alert">Fonts failed to load.</p>;
  if (!fonts) return <p role="status">Loading fonts…</p>;
  return <DocxEditor document={bytes} fonts={fonts} />;
}

Use useFonts() with packagedFonts() to load the packaged families. fonts identity changes remount a Root. Load a stable configuration before editing starts.

Build an application picker

Mount this picker inside DocxEditor.Root with the document surface. The hook reads the loaded document and checks whether the selection supports a change. A native select retains its normal keyboard and focus behavior.

import { useFontFamily } from '@docx-editor.dev/react';

export function ContractFontPicker() {
  const { value, options, isEnabled, setValue } = useFontFamily();
  return (
    <label>
      Font family
      <select
        aria-label="Font family"
        disabled={!isEnabled}
        value={value ?? ''}
        onChange={(event) => setValue(event.currentTarget.value)}
      >
        <option value="" disabled>
          Mixed or default
        </option>
        {options.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
    </label>
  );
}

More control

See Fonts and measurement for supported parts, types, and additional examples.