Collection of utility extensions for Tiptap rich text editor including character counting, placeholders, focus management, and history controls
—
The Character Count extension provides comprehensive text and document analysis capabilities, including character counting, word counting, and content limit enforcement.
Tracks character and word counts in the document with optional limits and custom counting functions.
/**
* Character count extension with limit enforcement and custom counting functions
*/
const CharacterCount: Extension<CharacterCountOptions, CharacterCountStorage>;
interface CharacterCountOptions {
/** Maximum number of characters allowed (default: null) */
limit: number | null | undefined;
/** Counting mode: 'textSize' uses textContent, 'nodeSize' uses nodeSize (default: 'textSize') */
mode: 'textSize' | 'nodeSize';
/** Custom text counter function (default: text => text.length) */
textCounter: (text: string) => number;
/** Custom word counter function (default: word splitting on spaces) */
wordCounter: (text: string) => number;
}
interface CharacterCountStorage {
/** Get character count for the current document or specified node */
characters: (options?: {
node?: ProsemirrorNode;
mode?: 'textSize' | 'nodeSize'
}) => number;
/** Get word count for the current document or specified node */
words: (options?: { node?: ProsemirrorNode }) => number;
}Usage Examples:
import { Editor } from "@tiptap/core";
import { CharacterCount } from "@tiptap/extensions/character-count";
// Basic character counting
const editor = new Editor({
extensions: [
CharacterCount.configure({
limit: 280, // Twitter-like limit
}),
],
});
// Access counts
const characterCount = editor.storage.characterCount.characters();
const wordCount = editor.storage.characterCount.words();
console.log(`Characters: ${characterCount}, Words: ${wordCount}`);
// Custom counting functions
const editorWithCustomCounting = new Editor({
extensions: [
CharacterCount.configure({
limit: 1000,
textCounter: (text) => {
// Count using internationalization-aware segmenter
return [...new Intl.Segmenter().segment(text)].length;
},
wordCounter: (text) => {
// Custom word splitting
return text.split(/\s+/).filter(word => word !== '').length;
},
}),
],
});
// Count specific node
const specificNode = editor.state.doc.firstChild;
const nodeCharacters = editor.storage.characterCount.characters({
node: specificNode
});The extension supports two counting modes:
Text Size Mode (default):
textContent of the documenttextCounter functionNode Size Mode:
nodeSize property// Text size mode (default)
CharacterCount.configure({
mode: 'textSize', // Counts visible text only
});
// Node size mode
CharacterCount.configure({
mode: 'nodeSize', // Includes document structure
});When a limit is set, the extension automatically:
import { CharacterCount } from "@tiptap/extensions/character-count";
const editor = new Editor({
extensions: [
CharacterCount.configure({
limit: 500,
mode: 'textSize',
}),
],
content: 'Initial content...',
});
// The extension will automatically prevent content that exceeds 500 characters
// and will trim pasted content to fit within the limitdeclare module '@tiptap/core' {
interface Storage {
characterCount: CharacterCountStorage;
}
}The extension adds its storage interface to the global Tiptap storage, making character and word counting methods available on any editor instance that includes this extension.
Install with Tessl CLI
npx tessl i tessl/npm-tiptap--extensions