---
canonical_url: "https://tiptap.dev/docs/conversion/export/_shared/_export-styles-guide"
---

```ts
// Import the ExportDocx extension
import { ExportDocx } from '@tiptap-pro/extension-export-docx'

const editor = new Editor({
  extensions: [
    // Other extensions ...
    ExportDocx.configure({
      onCompleteExport: (result: string | Buffer<ArrayBufferLike> | Blob | Stream) => {}, // required
      styleOverrides: { // Style overrides
        paragraphStyles: [
          // Heading 1 style override
          {
            id: 'Heading1',
            name: 'Heading 1',
            basedOn: 'Normal',
            next: 'Normal',
            quickFormat: true,
            run: {
              font: 'Aptos',
              size: pointsToHalfPoints(16),
              bold: true,
              color: 'FF0000',
            },
            paragraph: {
              spacing: {
                before: pointsToTwips(12),
                after: pointsToTwips(6),
                line: lineHeightToDocx(1.15),
              },
            },
          },
        ]
      }
    }),
    // Other extensions ...
  ],
  // Other editor settings ...
})
```

In the example above we are exporting a document with a custom `Heading 1` style. The style is based on the `Normal` style, has a red color, and uses the `Aptos` font. The spacing before the paragraph is set to `12pt`, and `6pt` after it. The line height is set to `1.15`.

You can also create custom styling for other elements like `Heading 2`, `Heading 3`, `List Bullet`, `List Number`, etc. The `paragraphStyles` array accepts an array of objects with the following properties:

### Paragraph style object

A `paragraphStyle` object accepts the following properties:

| Property      | Type      | Description                                                       |
| ------------- | --------- | ----------------------------------------------------------------- |
| `id`          | `string`  | Unique identifier for the style.                                  |
| `name`        | `string`  | Display name of the style.                                        |
| `basedOn`     | `string`  | The base style (e.g., `Normal`) that this style builds upon.      |
| `next`        | `string`  | The style to apply to the following paragraph.                    |
| `quickFormat` | `boolean` | If `true`, the style appears in the quick format menu.            |
| `run`         | `object`  | Defines text formatting (font, size, color, bold, etc.).          |
| `paragraph`   | `object`  | Defines paragraph formatting (spacing, alignment, borders, etc.). |

### Run style properties

The `run` object from a `paragraphStyle` accepts the following properties:

| Property              | Type            | Description                                                                                             |
| --------------------- | --------------- | ------------------------------------------------------------------------------------------------------- |
| `font`                | `string`        | Font family for the text.                                                                               |
| `size`                | `number`        | Font size in half-points (e.g., 16 points = 32).                                                        |
| `bold`                | `boolean`       | Set to `true` to make the text bold.                                                                    |
| `italics`             | `boolean`       | Set to `true` for italic text.                                                                          |
| `color`               | `string`        | Text color in hex format (e.g., `FF0000` for red. No # necessary).                                      |
| `kern`                | `number`        | Adjusts the spacing between characters in points.                                                       |
| `effect`              |                 | Special text effects that can be applied.                                                               |
| `emphasisMark`        | `string`        | Emphasis marks that appear above or below text. (like `dot`)                                            |
| `smallCaps`           | `boolean`       | Set to `true` to display text in small capitals.                                                        |
| `allCaps`             | `boolean`       | Set to `true` to display text in all uppercase.                                                         |
| `strike`              | `boolean`       | Set to `true` to apply a single strikethrough.                                                          |
| `doubleStrike`        | `boolean`       | Set to `true` to apply a double strikethrough.                                                          |
| `subScript`           | `boolean`       | Set to `true` for subscript text.                                                                       |
| `superScript`         | `boolean`       | Set to `true` for superscript text.                                                                     |
| `highlight`           |                 | Highlight color (predefined values).                                                                    |
| `characterSpacing`    | `number`        | Adjusts spacing between characters in TWIPs (…we know, TWIPs right?                                     |
| `shading`             | `object`        | Applies background shading to the text.                                                                 |
| `shading` → `type`    | `ShadingType`   | The shading type (`clear`, `solid`, `horizontalStripe`, etc.).                                          |
| `shading` → `fill`    | `string`        | The shading fill color in hex format (e.g., `FF0000` for red).                                          |
| `shading` → `color`   | `string`        | The shading color in hex format (e.g., `FF0000` for red).                                               |
| `scale`               | `number`        | Adjusts the width of the text (as a percentage).                                                        |
| `underline`           | `object`        | Underline style, specify properties like `color` and `type` or and empty object for a simple underline. |
| `underline` → `color` | `string`        | Underline color in hex format (e.g., `FF0000` for red. No # necessary).                                 |
| `underline` → `type`  | `UnderlineType` | The underline type (`single`, `double` or `thick`)                                                      |

For more advanced styling options and detailed usage you can refer to the `IRunStylePropertiesOptions` type exposed from our package, or refer to the [docx documentation](https://docx.js.org/#/usage/styling-with-js).

### Paragraph style properties

The `paragraph` object from a `paragraphStyle` accepts the following properties:

| Property                  | Type           | Description                                                              |
| ------------------------- | -------------- | ------------------------------------------------------------------------ |
| `spacing`                 | `object`       | Controls spacing: properties like `before`, `after`, and `line`.         |
| `alignment`               | `string`       | Sets paragraph alignment (`left`, `center`, `right`, or `justify`).      |
| `border`                  | `object`       | Defines borders around the paragraph (top, bottom, left, right).         |
| `shading`                 | `object`       | Applies background shading to the paragraph.                             |
| `indent`                  | `object`       | Specifies indentation (first line, hanging, left, right).                |
| `contextualSpacing`       | `boolean`      | If `true`, reduces spacing between paragraphs of the same style.         |
| `keepNext`                | `boolean`      | Keeps this paragraph on the same page as the next.                       |
| `keepLines`               | `boolean`      | Keeps all lines of the paragraph together on the same page.              |
| `outlineLevel`            | `number`       | Sets the outline level for document organization (typically 1–9).        |
| `thematicBreak`           | `number`       | Adds a horizontal line break when set to `true`.                         |
| `rightTabStop`            | `number`       | Sets the position of the right tab stop in twips.                        |
| `leftTabStop`             | `number`       | Sets the position of the left tab stop in twips.                         |
| `numbering`               | `object`       | Controls numbering settings (e.g., reference, level, custom formatting). |
| `numbering` → `reference` | `string`       | The numbering style reference ID.                                        |
| `numbering` → `level`     | `number`       | The level in the numbering hierarchy (0-based).                          |
| `spacing`                 | `object`       | Controls the spacing of the paragraph.                                   |
| `spacing` → `before`      | `number`       | Space before the paragraph.                                              |
| `spacing` → `after`       | `number`       | Space after the paragraph.                                               |
| `spacing` → `line`        | `number`       | Line spacing within the paragraph.                                       |
| `spacing` → `lineRule`    | `LineRuleType` | Defines how the line spacing is calculated.                              |

For more advanced styling options and detailed usage you can refer to the `IParagraphStylePropertiesOptions` type exposed from our package, or refer to the [docx documentation](https://docx.js.org/#/usage/styling-with-js).

## Tiptap's export default styles

Tiptap offers a sensible default styling for the exported document, but you can override these styles by providing your own custom styles. This allows you to create a consistent look and feel across your documents.

```ts
{
  paragraphStyles: [
    // Normal style (default for most paragraphs)
    {
      id: 'Normal',
      name: 'Normal',
      run: {
        font: 'Aptos',
        size: pointsToHalfPoints(11),
      },
      paragraph: {
        spacing: {
          before: 0,
          after: pointsToTwips(10),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // List Paragraph style (used for bullets and numbering)
    {
      id: 'ListParagraph',
      name: 'List Paragraph',
      basedOn: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        size: pointsToHalfPoints(11),
      },
      paragraph: {
        spacing: {
          before: 0,
          after: pointsToTwips(2),
          line: lineHeightToDocx(1),
        },
      },
    },
    // Heading 1 style
    {
      id: 'Heading1',
      name: 'Heading 1',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos Light',
        size: pointsToHalfPoints(16),
        bold: true,
        color: '2E74B5',
      },
      paragraph: {
        spacing: {
          before: pointsToTwips(12),
          after: pointsToTwips(6),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Heading 2 style
    {
      id: 'Heading2',
      name: 'Heading 2',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos Light',
        size: pointsToHalfPoints(14),
        bold: true,
        color: '2E74B5',
      },
      paragraph: {
        spacing: {
          before: pointsToTwips(12),
          after: pointsToTwips(6),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Heading 3 style
    {
      id: 'Heading3',
      name: 'Heading 3',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        size: pointsToHalfPoints(13),
        bold: true,
        color: '2E74B5',
      },
      paragraph: {
        spacing: {
          before: pointsToTwips(12),
          after: pointsToTwips(6),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Heading 4 style
    {
      id: 'Heading4',
      name: 'Heading 4',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        size: pointsToHalfPoints(12),
        bold: true,
        color: '2E74B5',
      },
      paragraph: {
        spacing: {
          before: pointsToTwips(12),
          after: pointsToTwips(6),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Heading 5 style
    {
      id: 'Heading5',
      name: 'Heading 5',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        size: pointsToHalfPoints(11),
        bold: true,
        color: '2E74B5',
      },
      paragraph: {
        spacing: {
          before: pointsToTwips(12),
          after: pointsToTwips(6),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Title style
    {
      id: 'Title',
      name: 'Title',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos Light',
        size: pointsToHalfPoints(22),
        bold: true,
        color: '000000',
      },
      paragraph: {
        alignment: AlignmentType.CENTER,
        spacing: {
          before: 0,
          after: 0,
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Subtitle style
    {
      id: 'Subtitle',
      name: 'Subtitle',
      basedOn: 'Normal',
      next: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos Light',
        size: pointsToHalfPoints(16),
        italics: true,
        color: '666666',
      },
      paragraph: {
        alignment: AlignmentType.CENTER,
        spacing: {
          before: 0,
          after: 0,
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Quote style (typically for indented, italic text)
    {
      id: 'Quote',
      name: 'Quote',
      basedOn: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        italics: true,
      },
      paragraph: {
        alignment: AlignmentType.CENTER,
        spacing: {
          before: pointsToTwips(10),
          after: pointsToTwips(10),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // Intense Quote style (more pronounced indentation)
    {
      id: 'IntenseQuote',
      name: 'Intense Quote',
      basedOn: 'Normal',
      quickFormat: true,
      run: {
        font: 'Aptos',
        italics: true,
        color: '444444',
      },
      paragraph: {
        alignment: AlignmentType.CENTER,
        spacing: {
          before: pointsToTwips(10),
          after: pointsToTwips(10),
          line: lineHeightToDocx(1.15),
        },
      },
    },
    // No Spacing style (no extra space before or after paragraphs)
    {
      id: 'NoSpacing',
      name: 'No Spacing',
      basedOn: 'Normal',
      quickFormat: true,
      paragraph: {
        spacing: {
          before: 0,
          after: 0,
          line: lineHeightToDocx(1),
        },
      },
    },
    // Hyperlink style
    {
      id: 'Hyperlink',
      name: 'Hyperlink',
      basedOn: 'Normal',
      run: {
        color: '0563C1',
        underline: {
          type: 'single',
        },
      },
    },
  ],
}
```

## Element overrides

Element overrides are separate from `styleOverrides`. While `styleOverrides` defines **named paragraph styles** (Heading 1, Normal, etc.) that Word applies through its style system, **element overrides** apply base defaults directly to every paragraph, text run, table, table cell, or image during the conversion process.

This gives you fine-grained control over the raw docx properties of every element without needing to define named styles.

> **Shallow spreading**: All override objects use shallow spreading, not deep merging. When overriding nested properties like `spacing` or `transformation`, provide the complete nested object to avoid undefined fields.

### `paragraphOverrides`

Accepts any `IParagraphOptions` property except `children`. These values are spread **first** as base defaults; per-node computed values (`alignment`, list numbering, heading level) override them.

Applied to: standard paragraphs, headings, blockquotes, bullet lists, ordered lists, and list items.

```ts
ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  paragraphOverrides: {
    spacing: { after: 200, before: 100 },
    alignment: AlignmentType.LEFT,
  },
})
```

> **`spacing` is a partial override**: `spacing.before` and `spacing.after` from `paragraphOverrides` are preserved on every paragraph, but `spacing.line` is always recomputed from each paragraph's `lineHeight` and replaces any value you pass here. The other nested objects on `IParagraphOptions` are still replaced entirely (no deep merge).

### `textRunOverrides`

Accepts any `IRunOptions` property except `text`. These values are spread **first** as base defaults; per-mark formatting (bold, italic, underline, font family, font size, color, highlight, etc.) overrides them.

Useful for setting a default font or size across the entire exported document.

```ts
ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  textRunOverrides: {
    font: 'Arial',
    size: 24, // 12pt in half-points
  },
})
```

### `tableOverrides`

Accepts any `ITableOptions` property except `rows`. These values are spread **last**, so user-provided table-level properties (borders, margins, layout) win over computed defaults.

```ts
ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  tableOverrides: {
    width: { size: 100, type: WidthType.PERCENTAGE },
    layout: TableLayoutType.FIXED,
  },
})
```

### `tableCellOverrides`

Accepts any `ITableCellOptions` property except `children`. These values are spread **first** as base defaults; per-cell computed values (width, colspan, width type) override them.

Useful for applying consistent cell shading, vertical alignment, or border styles across all table cells.

```ts
ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  tableCellOverrides: {
    shading: { fill: 'F0F0F0', type: ShadingType.SOLID },
    verticalAlign: VerticalAlign.CENTER,
  },
})
```

### `imageOverrides`

Accepts any `IImageOptions` property except `data`, `type`, and `fallback`. These values are spread **last**, so user-provided values (e.g. custom `transformation` dimensions) win over the intrinsic dimensions detected from the image buffer. SVG fallback data is always preserved regardless of overrides.

```ts
ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  imageOverrides: {
    transformation: { width: 400, height: 300 },
    floating: {
      horizontalPosition: { offset: 0 },
      verticalPosition: { offset: 0 },
    },
  },
})
```

### Combined usage example

You can combine all element overrides in a single configuration:

```ts
editor.commands.exportDocx({
  onCompleteExport: (result) => { /* ... */ },
  exportType: 'blob',
  paragraphOverrides: {
    spacing: { after: 200, before: 100 },
  },
  textRunOverrides: {
    font: 'Arial',
    size: 24, // 12pt in half-points
  },
  tableCellOverrides: {
    shading: { fill: 'F0F0F0', type: ShadingType.SOLID },
  },
  imageOverrides: {
    transformation: { width: 400, height: 300 },
  },
})
```

### `headerFooterOverrides`

Element overrides apply to header and footer content as well as the body — a `paragraphOverrides`, `textRunOverrides`, `tableOverrides`, `tableCellOverrides`, or `imageOverrides` value set at the top level flows into the running header and footer too.

When you want to style header/footer content **differently** from the body, use `headerFooterOverrides`. It accepts the same five fields and replaces the matching body-wide override scoped to header/footer content only. Each field is a complete replacement, not a deep merge — fields you leave undefined fall back to the body-wide override of the same name.

```ts
import { BorderStyle } from 'docx'

ExportDocx.configure({
  onCompleteExport: (result) => { /* ... */ },
  // Body tables get a 1pt grid border
  tableOverrides: {
    borders: {
      top:    { style: BorderStyle.SINGLE, size: 4, color: '000000' },
      bottom: { style: BorderStyle.SINGLE, size: 4, color: '000000' },
      left:   { style: BorderStyle.SINGLE, size: 4, color: '000000' },
      right:  { style: BorderStyle.SINGLE, size: 4, color: '000000' },
      insideHorizontal: { style: BorderStyle.SINGLE, size: 4, color: '000000' },
      insideVertical:   { style: BorderStyle.SINGLE, size: 4, color: '000000' },
    },
  },
  // Header/footer tables (e.g. a layout table inside a page header) are
  // borderless. Other body overrides still apply unless overridden here.
  headerFooterOverrides: {
    tableOverrides: {
      borders: {
        top:    { style: BorderStyle.NONE },
        bottom: { style: BorderStyle.NONE },
        left:   { style: BorderStyle.NONE },
        right:  { style: BorderStyle.NONE },
        insideHorizontal: { style: BorderStyle.NONE },
        insideVertical:   { style: BorderStyle.NONE },
      },
    },
  },
})
```

> **Scope**: `headerFooterOverrides` only applies to header/footer content auto-extracted from the [Pages extension](https://tiptap.dev/docs/pages/getting-started/overview.md). If you build headers/footers manually with `Docx.Header` / `Docx.Footer` instances or with custom factories passed to the `headers` / `footers` options, those constructions bypass `headerFooterOverrides` — apply the overrides yourself inside your factories.
