---
title: "Placeholder extension"
description: "Configure a helpful placeholder to fill the emptiness in your Tiptap editor. Learn how to set up and use it here in the Docs!"
canonical_url: "https://tiptap.dev/docs/editor/extensions/functionality/placeholder"
---

# Placeholder extension

Configure a helpful placeholder to fill the emptiness in your Tiptap editor. Learn how to set up and use it here in the Docs!

This extension provides placeholder support. Give your users an idea what they should write with a tiny hint. There is a handful of things to customize, if you feel like it.

> **Interactive demo:** [Placeholder](https://embed.tiptap.dev/preview/Extensions/Placeholder)

## Install

```bash
npm install @tiptap/extensions
```

## Usage

```js
import { Editor } from '@tiptap/core'
import { Placeholder } from '@tiptap/extensions'

new Editor({
  extensions: [
    Placeholder.configure({
      placeholder: 'Write something …',
    }),
  ],
})
```

### Additional Setup

Placeholders are displayed with the help of CSS.

**Display a Placeholder only for the first line in an empty editor.**

```
.tiptap p.is-editor-empty:first-child::before {
  color: #adb5bd;
  content: attr(data-placeholder);
  float: left;
  height: 0;
  pointer-events: none;
}
```

**Display Placeholders on every new line.**

```
.tiptap p.is-empty::before {
  color: #adb5bd;
  content: attr(data-placeholder);
  float: left;
  height: 0;
  pointer-events: none;
}
```

## Settings

### emptyEditorClass

The added CSS class if the editor is empty.

Default: `'is-editor-empty'`

```js
Placeholder.configure({
  emptyEditorClass: 'is-editor-empty',
})
```

### emptyNodeClass

The added CSS class if the node is empty.

Default: `'is-empty'`

```js
Placeholder.configure({
  emptyNodeClass: 'my-custom-is-empty-class',
})
```

It's also possible to use a function to determine the class based on the node:

```js
Placeholder.configure({
  emptyNodeClass: ({ node }) => {
    if (node.type.name === 'heading') {
      return 'my-custom-is-empty-heading-class'
    }
    return ''
  },
})
```

### dataAttribute

The data attribute used to store the placeholder text. When setting this to `'my-placeholder'`, the placeholder text will be stored in the `data-my-placeholder` attribute, for example.

Default: `'placeholder'`

```js
Placeholder.configure({
  dataAttribute: 'my-placeholder'
})
```

### placeholder

The placeholder text added as `data-placeholder` attribute.

Default: `'Write something …'`

```js
Placeholder.configure({
  placeholder: 'My Custom Placeholder',
})
```

You can even use a function to add placeholder depending on the node:

```js
Placeholder.configure({
  placeholder: ({ node }) => {
    if (node.type.name === 'heading') {
      return 'What’s the title?'
    }

    return 'Can you add some further context?'
  },
})
```

### showOnlyWhenEditable

Show decorations only when editor is editable.

Default: `true`

```js
Placeholder.configure({
  showOnlyWhenEditable: false,
})
```

### showOnlyCurrent

Show decorations only in currently selected node.

Default: `true`

```js
Placeholder.configure({
  showOnlyCurrent: false,
})
```

### includeChildren

Show decorations also for nested nodes. Only textblock nodes (nodes that directly contain inline content, such as `paragraph` or `heading`) will receive a placeholder — wrapper nodes like `bulletList` or `listItem` are automatically skipped.

Default: `false`

```js
Placeholder.configure({
  includeChildren: true,
})
```

## Source code

[packages/extensions/src/placeholder](https://github.com/ueberdosis/tiptap/blob/main/packages/extensions/src/placeholder)

## Minimal Install

```js
import { Editor } from '@tiptap/core'
import { Placeholder } from '@tiptap/extensions/placeholder'

new Editor({
  extensions: [Placeholder],
})
```
