Font family and size

Beta

Font family and font size are inline text styling attributes that flow through the textStyle mark. The same pattern as text color and highlight: TextStyle is the base, and specific extensions layer on top.

What you need

  • Extensions: ConvertKit. Its bundled TextStyleKit provides TextStyle, Color, BackgroundColor, FontFamily, FontSize, and LineHeight in one extension.
  • Configuration: None required.
import { ConvertKit } from '@tiptap-pro/extension-convert-kit'

new Editor({ extensions: [ConvertKit] })

Don't use the deprecated standalone font-size package

Do not install @tiptap/extension-font-size separately, and don't pull @tiptap/extension-font-family and @tiptap/extension-font-size à la carte — everything lives inside TextStyleKit, which ConvertKit registers automatically.

Support overview

ImportEditorExport
Font familySupported (textStyle.fontFamily)Supported (FontFamily)Supported (first font only)
Font sizeSupported (textStyle.fontSize in px)Supported (FontSize)Supported (converted to half-points)
Letter spacingSupported (textStyle.letterSpacing in px)Requires extending TextStyle (not bundled in ConvertKit / TextStyleKit)Not supported

Import

Import font family and size using the editor extension or the REST API. Both produce identical output.

The conversion service reads the w:ascii attribute from <w:rFonts>, falling back to w:hAnsi if w:ascii is not present. The raw attribute value is stored as-is in textStyle.fontFamily (e.g., "Courier New").

Font size comes from <w:sz> in half-points and is converted to pixels:

pixels = halfPoints * 0.5 * (96 / 72)

The result is rounded to the nearest integer pixel via Math.round(). Standard sizes like 12pt (16px), 14pt (19px), and 18pt (24px) convert cleanly. The result is stored as textStyle.fontSize (e.g., "16px").

Letter spacing is also extracted from <w:spacing> on text runs (converted from twips to pixels) and stored as textStyle.letterSpacing. Neither ConvertKit's bundled TextStyleKit nor CSS injection renders this attribute. Letter spacing is the canonical "extracted but not rendered out of the box" case. To make it visible in the editor, extend TextStyle with a letterSpacing attribute that emits style="letter-spacing: ..." in renderHTML. The Styling converted content guide has a copy-paste example. Letter spacing is not preserved on export.

Editor rendering

FontFamily and FontSize both depend on TextStyle. All three are bundled inside TextStyleKit, which ConvertKit registers automatically:

npm install @tiptap-pro/extension-convert-kit

Font family renders as style="font-family: ..." and font size as style="font-size: ..." on <span> elements. If you disable ConvertKit.configure({ textStyleKit: false }), the attributes from import are not recognised by the schema. See the invalid schema guide for how to manage this.

Export

Export font family and size using the editor extension or the REST API. Both handle font family and size identically.

On export, font family values are sanitized: quotes are stripped and only the first font from a comma-separated value is used. Since import produces a single font name, round-tripped values pass through unchanged.

Font fallback lists are collapsed

DOCX does not support CSS-style font fallback lists. If your editor content contains a manually set value like "Arial, Helvetica, sans-serif", the exporter picks the first font name (Arial) and discards the rest. Values imported from DOCX are already single font names and are not affected.

Font size converts back from pixels to half-points:

halfPoints = pixels * 1.5

Values that were imported from DOCX will produce the same half-point value on export, provided the original half-point value converts to an exact integer pixel. When Math.round() alters the pixel value during import (e.g., 14pt becomes 18.67px, rounded to 19px), the exported half-point value will differ from the original (19px exports as 28.5 half-points instead of the original 28). Non-numeric font size values (if any) are skipped with a console warning.