Tiptap is a suite of open source content editing and real-time collaboration tools for developers building apps like Notion or Google Docs.
This package provides the ability to adjust the size of the tip tab image. It has been tested in React, Vue, and NextJS, and stability in VanillaJS may not be guaranteed. Additionally, it can align the image position.
| tiptap-extension-resize-image | Supported TipTap Versions |
|---|---|
| ≤ 1.2.2 | v2 only |
| ≥ 1.2.3 | v2 and v3 |
You can install it using npm:
$ npm install tiptap-extension-resize-imageimport StarterKit from '@tiptap/starter-kit';
import ImageResize from 'tiptap-extension-resize-image';
import { EditorContent, useEditor } from '@tiptap/react';
const editor = useEditor({
extensions: [StarterKit, ImageResize],
content: `<img src="https://source.unsplash.com/8xznAGy4HcY/800x400" />`,
});If you want to render images as inline elements, you can configure the extension like this:
const editor = useEditor({
extensions: [
StarterKit,
ImageResize.configure({
inline: true,
}),
],
content: `<img src="..."/>`,
});You can set minimum and maximum width constraints to limit how small or large images can be resized:
const editor = useEditor({
extensions: [
StarterKit,
ImageResize.configure({
minWidth: 100, // Minimum width in pixels
maxWidth: 800, // Maximum width in pixels
}),
],
content: `<img src="..."/>`,
});Both minWidth and maxWidth are optional. You can set one, both, or neither:
// Only set a minimum width
ImageResize.configure({ minWidth: 50 });
// Only set a maximum width
ImageResize.configure({ maxWidth: 1200 });
// Set both constraints
ImageResize.configure({ minWidth: 100, maxWidth: 800 });| Option | Type | Default | Description |
|---|---|---|---|
inline |
boolean |
false |
Render images as inline elements |
minWidth |
number |
undefined |
Minimum width in pixels (cannot resize smaller) |
maxWidth |
number |
undefined |
Maximum width in pixels (cannot resize larger) |
Figure and Figcaption extensions allow you to add a caption to an image. The Figure node wraps an image with a figcaption element, and provides commands to add, remove, or toggle captions.
import StarterKit from '@tiptap/starter-kit';
import { ImageResize, Figure, Figcaption } from 'tiptap-extension-resize-image';
const editor = useEditor({
extensions: [StarterKit, ImageResize, Figure, Figcaption],
});| Command | Description |
|---|---|
addCaption() |
Converts a selected imageResize node to a figure node |
removeCaption() |
Converts a selected figure node to an imageResize node |
toggleCaption() |
Toggles between imageResize and figure node |
// Add a caption to a selected image
editor.commands.addCaption();
// Add a caption with initial text
editor.commands.addCaption('My caption');
// Remove a caption from a selected figure
editor.commands.removeCaption();
// Toggle between imageResize and figure
editor.commands.toggleCaption();When ImageResize is configured with inline: true, the image becomes an
inline node that lives inside paragraphs (or other inline containers).
A figure, on the other hand, is a block-level node by HTML spec and cannot
be nested inside such inline containers without breaking the document
structure.
For this reason, addCaption() (and toggleCaption() when the current node
is an inline image) will return false and do nothing in this case. You can
use this return value to disable the caption button in your UI:
<button
onClick={() => editor.chain().focus().addCaption().run()}
disabled={!editor.can().addCaption()}
>
Add Caption
</button>If you need both inline images and captions in the same editor, configure
ImageResize without inline (the default) so that all images are block
nodes and can be converted into a figure with a caption.
Figcaption placeholders are displayed with the help of CSS. Add the following styles to your project. You can customize these styles to match your design:
/* Basic figcaption styles */
figcaption {
text-align: left;
font-size: 0.875rem;
color: #666;
}
/* Placeholder styles - displayed when figcaption is empty */
/* Uses the data-placeholder attribute set by the Figcaption extension */
figcaption.is-empty::before {
color: #adb5bd;
content: attr(data-placeholder);
float: left;
height: 0;
pointer-events: none;
}| Option | Type | Default | Description |
|---|---|---|---|
placeholder |
string |
'Write a caption...' |
Placeholder text for empty caption |
Figcaption.configure({
placeholder: 'placeholder text as you want',
});In Tiptap v3, shouldRerenderOnTransaction defaults to false, which means components won't automatically re-render on editor state changes. To reactively update button states (e.g., disabled), use one of the following approaches:
Option 1: Enable shouldRerenderOnTransaction
const editor = useEditor({
shouldRerenderOnTransaction: true,
extensions: [...],
});
// Now you can use editor.can() directly
<button
onClick={() => editor.commands.addCaption()}
disabled={!editor.can().addCaption()}
>
Add Caption
</button>Option 2: Use useEditorState (recommended)
import { useEditorState } from '@tiptap/react';
const { canAddCaption, canRemoveCaption } = useEditorState({
editor,
selector: (ctx) => ({
canAddCaption: ctx.editor.can().addCaption(),
}),
});
<button onClick={() => editor.commands.addCaption()} disabled={!canAddCaption}>
Add Caption
</button>;Contributions are welcome! Please read our Contributing Guide before submitting a Pull Request.
