---
canonical_url: "https://tiptap.dev/docs/conversion/export/_shared/_custom-node-conversion-guide"
---

> **Custom node conventions:**
>
> Custom node converters must adhere to the underlying DOCX generation library's requirements. In practice, a custom converter function for DOCX should return one of the allowed DOCX elements for that node: a `Paragraph` class (or an array of `Paragraph` classes), a `Table` class, a `TextRun` class, an `ExternalHyperlink` class, or `null` if the node should be skipped in the output.

### Define the custom node extension

For the sake of the example, suppose your editor has a custom node type `hintbox` (a callout-styled box). You can define how it should appear in the exported document.

Here's how the `Hintbox` extension's custom node might look like:

```ts
import { mergeAttributes, Node } from '@tiptap/core'

export interface ParagraphOptions {
  /**
   * The HTML attributes for a paragraph node.
   * @default {}
   * @example { class: 'foo' }
   */
  HTMLAttributes: Record<string, any>
}

declare module '@tiptap/core' {
  interface Commands<ReturnType> {
    hintbox: {
      /**
       * Set a hintbox
       * @example editor.commands.setHintbox()
       */
      setHintbox: () => ReturnType
      /**
       * Toggle a hintbox
       * @example editor.commands.toggleHintbox()
       */
      toggleHintbox: () => ReturnType
    }
  }
}

/**
 * This extension allows you to create hintboxes.
 * @see https://www.tiptap.dev/api/nodes/paragraph
 */
export const Hintbox = Node.create<ParagraphOptions>({
  name: 'hintbox',

  priority: 1000,

  addOptions() {
    return {
      HTMLAttributes: {
        style: 'padding: 20px; border: 1px solid #b8d8ff; border-radius: 5px; background-color: #e6f3ff;',
      },
    }
  },

  group: 'block',

  content: 'inline*',

  parseHTML() {
    return [{ tag: 'p' }]
  },

  renderHTML({ HTMLAttributes }) {
    return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]
  },

  addCommands() {
    return {
      setHintbox:
        () =>
        ({ commands }) => {
          return commands.setNode(this.name)
        },
      toggleHintbox:
        () =>
        ({ commands }) => {
          return commands.toggleNode(this.name, 'paragraph')
        },
    }
  },

  addKeyboardShortcuts() {
    return {
      'Mod-Alt-h': () => this.editor.commands.toggleHintbox(),
    }
  },
})
```
