# Headings

The heading feature helps you structure your document by adding headings to parts of the text, making your content easier to scan for both readers and search engines. It provides configurable heading levels, rendered as `<h2>` to `<h4>` by default.

<a id="demo">

## Demo

Use the toolbar dropdown to style a heading. You can also type one or more `#` characters (depending on the heading level) followed by a space, and the [autoformatting feature](autoformat.md) will create a new heading.

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

This demo presents a limited set of features. Visit the [feature-rich editor example](../examples/builds-custom/full-featured-editor.md) to see more in action.

<a id="heading-levels">

## Heading levels

By default, this feature is configured to support `<h2>`, `<h3>`, and `<h4>` elements which are named: “Heading 1,” “Heading 2,” and “Heading 3,” respectively. The rationale behind starting from `<h2>` is that `<h1>` should be reserved for the [page’s main title](title.md) and the page content will usually start from `<h2>`.

> **Note**
>
> Support for adding a document title is provided through the [`Title`](../api/module_heading_title-Title.md) plugin. When it is enabled, a `<h1>` element pasted into the editor will be rendered as the [document title](title.md).

By default, when your editor preset does not include the title plugin, an `<h1>` element pasted into the rich-text editor is converted to `<h2>` (“Heading 1”).

> **Note**
>
> You can read more about why the editor should not create `<h1>` elements for content headings in the [Headings section of Editor Recommendations](http://ckeditor.github.io/editor-recommendations/features/headings.html).

<a id="heading-buttons">

## Heading buttons

The heading feature lets you also use a set of heading buttons instead of the dropdown list. The toolbar buttons are configurable, and it is possible to include a paragraph button, too. Compare the heading toolbar dropdown from the demo above with the heading buttons below to check the functionality and usability of this variation.

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

<a id="installation">

## Installation

After [installing the editor](../getting-started/installation/cloud/quick-start.md), add the feature to your plugin list and toolbar configuration:

**NPM**

```js
import { ClassicEditor, Heading } from 'ckeditor5';

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
		plugins: [ Heading, /* ... */ ],
		toolbar: [ 'heading', /* ... */ ]
		heading: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

**CDN**

```js
const { ClassicEditor, Heading } = CKEDITOR;

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>',
		plugins: [ Heading, /* ... */ ],
		toolbar: [ 'heading', /* ... */ ]
		heading: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="installation-with-toolbar-heading-buttons">

### Installation with toolbar heading buttons

To configure the toolbar buttons for styling text as headings and paragraphs, you need to import the following into your plugin list and configuration:

**NPM**

```js
import { ClassicEditor, HeadingButtonsUI, ParagraphButtonUI } from 'ckeditor5';
```

**CDN**

```js
const { ClassicEditor, HeadingButtonsUI, ParagraphButtonUI } = CKEDITOR;
```

<a id="configuration">

## Configuration

<a id="configuring-heading-levels">

### Configuring heading levels

You can configure which heading levels the editor will support and how they should be named in the Headings dropdown. Use the [`heading.options`](../api/module_heading_headingconfig-HeadingConfig.md#member-options) configuration option to do so.

For example, the following editor will support only two levels of headings – `<h1>` and `<h2>`:

```html
<div id="editor">
	<h1>Heading 1</h1>
	<h2>Heading 2</h2>
	<p>This is <a href="https://ckeditor.com">CKEditor 5</a>.</p>
</div>
```

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		heading: {
			options: [
				{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
				{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
				{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' }
			]
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

<a id="configuring-custom-heading-elements">

### Configuring custom heading elements

It is also possible to define fully custom elements for headings by using the [advanced format](../api/module_engine_conversion_conversion-Conversion.md#function-elementToElement) of the [`heading.options`](../api/module_heading_headingconfig-HeadingConfig.md#member-options) configuration option.

For example, the following editor will support the following two heading options at the same time: `<h2 class="fancy">` and `<h2>`:

```html
<style>
	/* Styles for the heading in the content and for the dropdown item. */
	h2.fancy, .ck.ck-button.ck-heading_heading2_fancy {
		color: #ff0050;
		font-size: 17px;
	}
</style>

<div id="snippet-custom-heading-levels">
	<h1>Heading 1</h1>
	<h2>Heading 2</h2>
	<h2 class="fancy">Fancy Heading 2</h2>
	<p>This is <a href="https://ckeditor.com">CKEditor 5</a>.</p>
</div>
```

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		heading: {
			options: [
				{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
				{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
				{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
				{
					model: 'headingFancy',
					view: {
						name: 'h2',
						classes: 'fancy'
					},
					title: 'Heading 2 (fancy)',
					class: 'ck-heading_heading2_fancy',

					// It needs to be converted before the standard 'heading2'.
					converterPriority: 'high'
				}
			]
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

<a id="configuring-toolbar-buttons">

### Configuring toolbar buttons

To use individual toolbar buttons instead of the heading dropdown, you need to properly configure the feature. You also need to import proper UI elements; see the [installation section](#installation-with-toolbar-heading-buttons) for instructions on how to do it.

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6', '|', 'undo', 'redo' ],
		heading: {
			options: [
				{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
				{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
				{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
				{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
				{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },
				{ model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' },
				{ model: 'heading6', view: 'h6', title: 'Heading 6', class: 'ck-heading_heading6' }
			]
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

<a id="related-features">

## Related features

There are more CKEditor 5 features that can help you format your content:

* [Basic text styles](basic-styles.md) – The essentials, like **bold**, _italic_, and others.
* [Document title](title.md) – Clearly divide your content into a title and body.
* [Block indentation](indent.md) – Set indentation for text blocks such as paragraphs or lists.
* [Lists](lists/lists.md) – Organize your content better with ordered and unordered lists you can style.
* [Remove format](remove-format.md) – Easily clean basic text formatting.
* [Autoformatting](autoformat.md) – Add formatting elements (such as headings) as you type with Markdown code.

<a id="common-api">

## Common API

The [`Heading`](../api/module_heading_heading-Heading.md) plugin registers:

* The `'heading'` dropdown.

* The `'heading'` command that accepts a value based on the [`heading.options`](../api/module_heading_headingconfig-HeadingConfig.md#member-options) configuration option.

  You can turn the currently selected block(s) to headings by executing one of these commands:

  ```js
  editor.execute( 'heading', { value: 'heading2' } );
  ```

The [`HeadingButtonsUI`](../api/module_heading_headingbuttonsui-HeadingButtonsUI.md) plugin registers six UI button components that will execute the `'heading'` command with the proper value of the `value` attribute:

* `'heading1'`
* `'heading2'`
* `'heading3'`
* `'heading4'`
* `'heading5'`
* `'heading6'`

The [`ParagraphButtonUI`](../api/module_paragraph_paragraphbuttonui-ParagraphButtonUI.md) plugin registers the UI button component: `'paragraph'`.

> **Note**
>
> We recommend using the official [CKEditor 5 inspector](../framework/development-tools/inspector.md) for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.

<a id="contribute">

## Contribute

The source code of the feature is available on GitHub at <https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-heading>.

---

Full index of the CKEditor 5 documentation: [llms.txt](../../llms.txt)
