> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ueberdosis/tiptap/llms.txt
> Use this file to discover all available pages before exploring further.

# Extension

> The Extension class is the base class for creating custom extensions in Tiptap.

## Creating an Extension

Use the static `create` method to define a new extension.

```typescript theme={null}
import { Extension } from '@tiptap/core'

const MyExtension = Extension.create<Options, Storage>({
  name: 'myExtension',
  // ... configuration
})
```

<ParamField path="config" type="Partial<ExtensionConfig<Options, Storage>> | (() => Partial<ExtensionConfig<Options, Storage>>)">
  The extension configuration object or a function that returns a configuration object.
</ParamField>

## Configuration Options

### name

The unique name for the extension.

```typescript theme={null}
name: string
```

<ParamField path="name" type="string" required>
  A unique identifier for the extension. This must be unique across all extensions.
</ParamField>

**Example**

```typescript theme={null}
const MyExtension = Extension.create({
  name: 'myExtension',
})
```

### priority

The priority of the extension. Higher values are called earlier.

```typescript theme={null}
priority?: number
```

<ParamField path="priority" type="number" default="100">
  Extensions with higher priority take precedence. Core extensions typically use 100.
</ParamField>

**Example**

```typescript theme={null}
const HighPriorityExtension = Extension.create({
  name: 'highPriority',
  priority: 1000,
})
```

### addOptions()

Define options for the extension.

```typescript theme={null}
addOptions?(this: { name: string; parent: ParentConfig['addOptions'] }): Options
```

**Example**

```typescript theme={null}
interface MyExtensionOptions {
  color: string
  size: number
}

const MyExtension = Extension.create<MyExtensionOptions>({
  name: 'myExtension',
  
  addOptions() {
    return {
      color: 'blue',
      size: 16,
    }
  },
})
```

### addStorage()

Define storage for the extension to persist data.

```typescript theme={null}
addStorage?(this: {
  name: string
  options: Options
  parent: ParentConfig['addStorage']
}): Storage
```

**Example**

```typescript theme={null}
interface MyExtensionStorage {
  count: number
}

const MyExtension = Extension.create<{}, MyExtensionStorage>({
  name: 'myExtension',
  
  addStorage() {
    return {
      count: 0,
    }
  },
  
  addCommands() {
    return {
      incrementCount: () => ({ editor }) => {
        editor.storage.myExtension.count++
        return true
      },
    }
  },
})
```

### addGlobalAttributes()

Add attributes to specific node or mark types.

```typescript theme={null}
addGlobalAttributes?(this: {
  name: string
  options: Options
  storage: Storage
  extensions: (Node | Mark)[]
  parent: ParentConfig['addGlobalAttributes']
}): GlobalAttributes
```

**Example**

```typescript theme={null}
const TextAlign = Extension.create({
  name: 'textAlign',
  
  addGlobalAttributes() {
    return [
      {
        types: ['heading', 'paragraph'],
        attributes: {
          textAlign: {
            default: 'left',
            parseHTML: element => element.style.textAlign || 'left',
            renderHTML: attributes => ({
              style: `text-align: ${attributes.textAlign}`,
            }),
          },
        },
      },
    ]
  },
})
```

### addCommands()

Add commands to the editor.

```typescript theme={null}
addCommands?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['addCommands']
}): Partial<RawCommands>
```

**Example**

```typescript theme={null}
const MyExtension = Extension.create({
  name: 'myExtension',
  
  addCommands() {
    return {
      setColor: (color: string) => ({ commands }) => {
        return commands.updateAttributes('textStyle', { color })
      },
    }
  },
})

// Usage
editor.commands.setColor('red')
```

### addKeyboardShortcuts()

Register keyboard shortcuts.

```typescript theme={null}
addKeyboardShortcuts?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['addKeyboardShortcuts']
}): { [key: string]: KeyboardShortcutCommand }
```

**Example**

```typescript theme={null}
const MyExtension = Extension.create({
  name: 'myExtension',
  
  addKeyboardShortcuts() {
    return {
      'Mod-Shift-x': () => this.editor.commands.clearContent(),
      'Mod-k': () => {
        console.log('Keyboard shortcut triggered')
        return true
      },
    }
  },
})
```

### addInputRules()

Add input rules that trigger on typing patterns.

```typescript theme={null}
addInputRules?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['addInputRules']
}): InputRule[]
```

**Example**

```typescript theme={null}
import { markInputRule } from '@tiptap/core'

const MyExtension = Extension.create({
  name: 'myExtension',
  
  addInputRules() {
    return [
      markInputRule({
        find: /(?:^|\s)((?:==)((?:[^=]+))(?:==))$/,
        type: this.editor.schema.marks.highlight,
      }),
    ]
  },
})
```

### addPasteRules()

Add paste rules that trigger on pasting content.

```typescript theme={null}
addPasteRules?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['addPasteRules']
}): PasteRule[]
```

**Example**

```typescript theme={null}
import { markPasteRule } from '@tiptap/core'

const MyExtension = Extension.create({
  name: 'myExtension',
  
  addPasteRules() {
    return [
      markPasteRule({
        find: /https?:\/\/[^\s]+/g,
        type: this.editor.schema.marks.link,
        getAttributes: match => ({ href: match[0] }),
      }),
    ]
  },
})
```

### addProseMirrorPlugins()

Add ProseMirror plugins.

```typescript theme={null}
addProseMirrorPlugins?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['addProseMirrorPlugins']
}): Plugin[]
```

**Example**

```typescript theme={null}
import { Plugin, PluginKey } from '@tiptap/pm/state'

const MyExtension = Extension.create({
  name: 'myExtension',
  
  addProseMirrorPlugins() {
    return [
      new Plugin({
        key: new PluginKey('myPlugin'),
        props: {
          handleClick(view, pos, event) {
            console.log('Editor clicked at position:', pos)
            return false
          },
        },
      }),
    ]
  },
})
```

### addExtensions()

Add additional extensions (useful for extension kits).

```typescript theme={null}
addExtensions?(this: {
  name: string
  options: Options
  storage: Storage
  parent: ParentConfig['addExtensions']
}): Extensions
```

**Example**

```typescript theme={null}
import { BulletList, OrderedList, ListItem } from '@tiptap/extension-list'

const ListKit = Extension.create({
  name: 'listKit',
  
  addExtensions() {
    return [BulletList, OrderedList, ListItem]
  },
})
```

## Lifecycle Hooks

### onBeforeCreate()

Called before the editor is created.

```typescript theme={null}
onBeforeCreate?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onBeforeCreate']
}, event: { editor: Editor }): void
```

### onCreate()

Called when the editor is ready.

```typescript theme={null}
onCreate?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onCreate']
}, event: { editor: Editor }): void
```

### onUpdate()

Called when the content changes.

```typescript theme={null}
onUpdate?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onUpdate']
}, event: { editor: Editor; transaction: Transaction }): void
```

### onSelectionUpdate()

Called when the selection changes.

```typescript theme={null}
onSelectionUpdate?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onSelectionUpdate']
}, event: { editor: Editor; transaction: Transaction }): void
```

### onTransaction()

Called after each transaction.

```typescript theme={null}
onTransaction?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onTransaction']
}, event: { editor: Editor; transaction: Transaction }): void
```

### onFocus()

Called when the editor gains focus.

```typescript theme={null}
onFocus?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onFocus']
}, event: { editor: Editor; event: FocusEvent; transaction: Transaction }): void
```

### onBlur()

Called when the editor loses focus.

```typescript theme={null}
onBlur?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onBlur']
}, event: { editor: Editor; event: FocusEvent; transaction: Transaction }): void
```

### onDestroy()

Called when the editor is destroyed.

```typescript theme={null}
onDestroy?(this: {
  name: string
  options: Options
  storage: Storage
  editor: Editor
  type: null
  parent: ParentConfig['onDestroy']
}): void
```

## Methods

### configure()

Create a configured version of the extension.

```typescript theme={null}
extension.configure(options?: Partial<Options>): Extension<Options, Storage>
```

<ParamField path="options" type="Partial<Options>">
  Options to override the default options.
</ParamField>

**Example**

```typescript theme={null}
const MyExtension = Extension.create<{ color: string }>({
  name: 'myExtension',
  addOptions() {
    return { color: 'blue' }
  },
})

// Use with custom options
const editor = new Editor({
  extensions: [
    MyExtension.configure({ color: 'red' }),
  ],
})
```

### extend()

Extend the extension with additional configuration.

```typescript theme={null}
extension.extend<ExtendedOptions, ExtendedStorage, ExtendedConfig>(
  extendedConfig?: Partial<ExtendedConfig> | (() => Partial<ExtendedConfig>)
): Extension<ExtendedOptions, ExtendedStorage>
```

<ParamField path="extendedConfig" type="Partial<ExtendedConfig> | (() => Partial<ExtendedConfig>)">
  Additional configuration or a function that returns configuration.
</ParamField>

**Example**

```typescript theme={null}
const BaseExtension = Extension.create({
  name: 'base',
  addCommands() {
    return {
      doSomething: () => () => true,
    }
  },
})

const ExtendedExtension = BaseExtension.extend({
  name: 'extended',
  addCommands() {
    return {
      ...this.parent?.(),
      doSomethingElse: () => () => true,
    }
  },
})
```

## Complete Example

```typescript theme={null}
import { Extension } from '@tiptap/core'
import { Plugin, PluginKey } from '@tiptap/pm/state'

interface CharacterCountOptions {
  limit: number | null
}

interface CharacterCountStorage {
  characters: () => number
  words: () => number
}

const CharacterCount = Extension.create<CharacterCountOptions, CharacterCountStorage>({
  name: 'characterCount',

  addOptions() {
    return {
      limit: null,
    }
  },

  addStorage() {
    return {
      characters: () => {
        return this.editor.state.doc.textContent.length
      },
      words: () => {
        return this.editor.state.doc.textContent.split(/\s+/).filter(word => word).length
      },
    }
  },

  addProseMirrorPlugins() {
    return [
      new Plugin({
        key: new PluginKey('characterCount'),
        filterTransaction: (transaction, state) => {
          const limit = this.options.limit
          
          if (!limit || !transaction.docChanged) {
            return true
          }

          const newLength = transaction.doc.textContent.length
          return newLength <= limit
        },
      }),
    ]
  },

  onCreate() {
    console.log('Character count extension initialized')
  },

  onUpdate() {
    const count = this.storage.characters()
    console.log(`Character count: ${count}`)
  },
})

// Usage
const editor = new Editor({
  extensions: [
    CharacterCount.configure({
      limit: 1000,
    }),
  ],
})

console.log('Characters:', editor.storage.characterCount.characters())
console.log('Words:', editor.storage.characterCount.words())
```
