Better Blocks
An enhanced Rich Text (Blocks) editor with inline text color picker, background highlight, customizable color palettes. A drop-in replacement for the native Blocks field.
Strapi - Better Blocks Plugin
An enhanced Rich Text (Blocks) editor for Strapi v5 with inline text color, background highlight, and more.
Table of Contents
- Features
- Compatibility
- Installation
- Configuration
- Usage
- Custom Color Presets
- Media Embeds (CSP Configuration)
- Frontend Rendering
- Contributing
- License
Feature showcase
Text color & background highlight
Tables
Nested lists
Media embeds (YouTube / Vimeo)
Text alignment
Line height & indentation
Image captions & alignment
Emoji & special character pickers
Find & replace
Undo / redo, remove formatting & word count
Features
- Inline Text Color — Apply foreground color to selected text from a configurable palette
- Background Highlight — Apply background color to selected text for highlighting
- Live Preview Button — The toolbar button reflects the currently active text and highlight colors
- Customizable Palettes — Define custom color presets per field via Content-Type Builder
- Dark & Light Mode — Fully compatible with both Strapi themes
- Drop-in Replacement — Works as a custom field alongside the native Rich Text (Blocks) field
- Nested Lists — Infinitely nestable ordered and unordered lists with per-level format switching (Tab to indent, Shift+Tab to outdent)
- To-do Lists — Checkbox list items with click-to-toggle and strikethrough on checked items
- Tables — Insert tables with header row, add/remove rows and columns via hover toolbar
- Media Embeds — Insert YouTube and Vimeo videos with thumbnail preview in editor (iframe on frontend)
- Math (LaTeX / KaTeX) — Inline and block math rendered with KaTeX; insert from the toolbar, the
/mathslash command, the blocks selector, or by typing$$(block) /$…$(inline), then edit in a full-screen modal with a side-by-side source editor and live preview. Block math supports multi-line equations via\\and LaTeX environments such asalignedandcases - Diagrams (Mermaid) — Block-level Mermaid diagrams (flowcharts, sequence, class, state, ER, pie, and more) rendered to SVG; insert from the blocks selector, the
/mermaidslash command, or by typing```mermaidthen a space, then edit the definition in a full-screen modal with live preview and zoom controls. Theme follows Strapi's light/dark mode - Callouts / Admonitions — GitHub-style callouts in five variants (
Note,Tip,Important,Warning,Caution) with an optional custom title and nested rich-text content (paragraphs, lists, links). Insert from the blocks selector or the/note,/tip,/important,/warning,/cautionslash commands; switch variant, edit the title, or remove from the header popover. Colors follow Strapi's design tokens and adapt to light/dark mode - Details / Collapsible — GitHub-style collapsible
<details>/<summary>sections for managing content density. Insert from the blocks selector or the/detailsslash command; edit the summary label and toggle open/closed-by-default (defaultOpen) from the header. Holds full rich-text block content (paragraphs, lists, tables, images) and supports nesting. Admins can set the default summary text and choose a GitHub-minimal (default) or Custom (bordered + background) style. Stored as{ "type": "details", "summary": "…", "defaultOpen": false, "children": [...] } - Button (WordPress-style CTA) — Insert a styled call-to-action button from the blocks selector or by typing
[button]then a space. Two modes: Link (URL + open-in-new-tab + ARIA label) and File (pick any asset from the Media Library to render a download button with optional file size and type icon, and choose direct download or preview-in-new-tab). A full-screen editor with live preview controls alignment, background/text colors (including hover colors), border radius, font size/weight, padding presets, border, and a custom CSS class. One-click style presets (Primary / Secondary / Outline / Filled) keep CTAs on-brand. Admins can set default button colors and customize the presets. Stored as{ "type": "button", "buttonType": "link" | "file", "label": "…", "alignment": "center", "link": {…} | "file": {…}, "style": {…} } - Horizontal Line — Insert
<hr>dividers between content blocks - Text Alignment — Per-block left, center, right, and justify alignment
- Undo / Redo — Toolbar buttons wired to Slate's built-in history
- Remove Formatting — One-click button to strip all marks from selected text
- Link Decorators — "Open in new tab" option with
target="_blank"andrel="noopener noreferrer" - Word & Character Count — Live counter displayed at the bottom of the editor
- Line Height — Per-block line spacing control (1, 1.15, 1.5, 2, 2.5, 3)
- Indent / Outdent — Block-level indentation buttons (up to 6 levels)
- Image Captions — Editable figcaption below images
- Image Alignment — Left, center, and right alignment for images via hover buttons
- Emoji Picker — Searchable popup grid with 130+ common emojis
- Special Characters — Categorized picker for currency, math, arrows, Greek, legal symbols and more
- Find and Replace — Search with real-time highlighting (yellow for all matches, orange for active), prev/next navigation, replace and replace all
- Font Family — Inline font family selector (Arial, Georgia, Times New Roman, and more)
- Font Size — Inline font size selector (10px to 48px)
- Slash Commands — Type
/to open a block insertion menu with search, arrow key navigation, and Enter to select - Auto Text Transformations — Automatic symbol replacement on space:
(c)→ ©,1/2→ ½,--→ —,->→ →, and more - Editor Placeholder — "Start writing..." placeholder shown when the editor is empty
- Responsive Toolbar — Wraps to multiple rows on smaller screens so all buttons remain accessible
- Full Blocks Editor — Paragraphs, headings, lists, links, quotes, code blocks, and all standard text modifiers (bold, italic, underline, strikethrough, code, uppercase, superscript, subscript)
Compatibility
| Strapi Version | Plugin Version |
|---|---|
| v5.x | v0.1.x |
Installation
# Using yarn
yarn add @k11k/strapi-plugin-better-blocks
# Using npm
npm install @k11k/strapi-plugin-better-blocksAfter installation, rebuild your Strapi admin panel:
yarn build
# or
npm run buildConfiguration
1. Enable the plugin
Add the plugin to your Strapi configuration in config/plugins.ts (or config/plugins.js):
// config/plugins.ts
export default () => ({
'better-blocks': {
enabled: true,
},
});Details / Collapsible defaults (optional)
Set plugin-wide defaults for the collapsible Details block. These apply to every Better Blocks field, and can still be overridden per field in the Content-Type Builder.
// config/plugins.ts
export default () => ({
'better-blocks': {
enabled: true,
config: {
details: {
defaultSummary: 'Show more', // summary label for newly inserted blocks
style: 'custom', // 'github' (minimal) | 'custom' (bordered + tinted background)
},
},
},
});Button defaults (optional)
Set plugin-wide default colors for newly inserted Button blocks, and customize the Style presets (Primary / Secondary / Outline / Filled) offered in the editor's "Style preset" picker so authors deploy on-brand CTAs in one click. These apply to every Better Blocks field, and can still be overridden per field in the Content-Type Builder (and per button in the editor).
// config/plugins.ts
export default () => ({
'better-blocks': {
enabled: true,
config: {
button: {
defaultStyle: {
backgroundColor: '#4945ff',
textColor: '#ffffff',
},
// Brand variants for the "Style preset" picker (each applies
// background, text and border; the rest of the styling is untouched).
presets: {
primary: {
backgroundColor: '#4945ff',
textColor: '#ffffff',
border: 'none',
},
secondary: {
backgroundColor: '#dcdce4',
textColor: '#32324d',
border: 'none',
},
outline: {
backgroundColor: 'transparent',
textColor: '#4945ff',
border: '2px solid #4945ff',
},
filled: {
backgroundColor: '#32324d',
textColor: '#ffffff',
border: 'none',
},
},
},
},
},
});Button JSON shape (for frontend renderers)
A button is stored as a single block. buttonType selects the rendering mode:
{
"type": "button",
"buttonType": "link", // "link" | "file"
"label": "Get started",
"alignment": "center", // "left" | "center" | "right"
// Link mode
"link": {
"url": "https://example.com",
"target": "_blank", // "_self" | "_blank" | "_parent" | "_top"
"rel": "noopener noreferrer", // auto-added when target is "_blank"
"ariaLabel": "Get started",
},
// File mode (instead of `link`)
"file": {
"id": 123,
"url": "/uploads/whitepaper.pdf",
"name": "Product Whitepaper.pdf",
"size": 5242880, // bytes
"ext": ".pdf",
"mime": "application/pdf",
},
"showFileSize": true,
"showFileIcon": true,
"filePreview": false, // false → download the file, true → open/preview in a new tab
"style": {
"variant": "custom", // "primary" | "secondary" | "outline" | "filled" | "custom"
"backgroundColor": "#4945ff",
"textColor": "#ffffff",
"borderRadius": "4px",
"fontSize": "16px",
"fontWeight": "600",
"padding": "12px 24px",
"border": "none",
"hoverBackgroundColor": "#3732c9",
"hoverTextColor": "#ffffff",
},
"cssClass": "my-cta",
}Render link mode as <a href={link.url} target={link.target} rel={link.rel}>. For file
mode, honour filePreview: when true open the file in a new tab
(<a href={file.url} target="_blank" rel="noopener noreferrer">), otherwise force a
download (<a href={file.url} download={file.name}>) — optionally prefixing
file.name/size with showFileIcon/showFileSize. Only the keys for the active mode are
present. style.variant records the selected preset for the editor UI; renderers can
ignore it.
2. Restart Strapi
yarn develop3. Add a Better Blocks field
- Go to Content-Type Builder
- Select or create a content type
- Click Add new field
- Switch to the CUSTOM tab
- Select Better Blocks
- Configure the field name and color settings
- Save and wait for Strapi to restart
Usage
Once added to a content type, the Better Blocks field provides an enhanced Rich Text editor with:
Text Color
- Select text in the editor
- Click the A button in the toolbar
- Switch to the Text tab
- Choose a color from the palette
- Click Remove color to reset
Background Highlight
- Select text in the editor
- Click the A button in the toolbar
- Switch to the Highlight tab
- Choose a background color from the palette
- Click Remove highlight to reset
The toolbar button shows a live preview of the active colors — the icon color reflects the text color, and the button background reflects the highlight color.
Math (LaTeX)
Insert a math block from the toolbar, the /math slash command, the blocks selector, or by typing $$ (block) / $…$ (inline). The editor opens in a full-screen modal with a source editor and live preview. Press Cmd/Ctrl + Enter to save.
A single block can render multi-line equations — there is no need to create a separate block per line. Use the LaTeX line break \\, and an alignment environment when you want the lines to line up:
\begin{aligned}
2x + 3y &= 5 \\
x - y &= 1
\end{aligned}Other supported environments include cases (piecewise), gathered (centered lines), and matrix / pmatrix / bmatrix. A bare \\ outside an environment also breaks to a new (centered) line:
E = mc^2 \\
a^2 + b^2 = c^2Pressing Enter in the source editor only adds a line break to your LaTeX source for readability — it does not create a new block. The rendered line break comes from the LaTeX
\\.
Custom Color Presets
You can customize both text and background color palettes per field in the Content-Type Builder:
Text Colors
In the field's Base settings:
- Disable default text colors — Check to replace default colors with your own
- Custom text color presets — One color per line in
Label:#HEXformat
Example:
Black:#000000
White:#FFFFFF
Brand Red:#E53E3E
Brand Blue:#3182CEBackground Colors
- Disable default background colors — Check to replace default highlights with your own
- Custom background color presets — One color per line in
Label:#HEXformat
Example:
Warning:#FED7D7
Info:#BEE3F8
Success:#C6F6D5
Neutral:#EDF2F7Default Palettes
Text colors: Teal, Dark, Gray, Light Gray, Silver, Medium Gray, White
Background colors: Yellow, Green, Blue, Pink, Purple, Orange, Gray, Teal, Red, Cyan
Media Embeds (CSP Configuration)
If you use the media embed feature (YouTube / Vimeo), you need to update your Strapi security middleware to allow loading thumbnails and video iframes.
In config/middlewares.ts:
export default [
'strapi::logger',
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
directives: {
'img-src': ["'self'", 'data:', 'blob:', 'https://img.youtube.com'],
'media-src': ["'self'", 'data:', 'blob:'],
'frame-src': [
"'self'",
'https://www.youtube.com',
'https://player.vimeo.com',
],
},
},
},
},
'strapi::cors',
'strapi::poweredBy',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
];Without this, YouTube thumbnails will be blocked by the Content Security Policy in the Strapi admin panel. The frame-src directive is needed if you render the embeds as iframes on your frontend while previewing in Strapi.
Frontend Rendering
To render Better Blocks content in your React frontend, use the companion renderer:
# Using yarn
yarn add @k11k/better-blocks-react-renderer
# Using npm
npm install @k11k/better-blocks-react-rendererimport { BlocksRenderer } from '@k11k/better-blocks-react-renderer';
const MyComponent = ({ content }) => {
return <BlocksRenderer content={content} />;
};The renderer supports all Better Blocks features including text colors, background highlights, images, and all standard block types.
See the @k11k/better-blocks-react-renderer repository for full documentation.
Requirements
- Node.js ≥ 20.0.0
- Strapi v5.x
- Slate 0.94.1 (bundled with Strapi)
Contributing
Contributions are welcome! The easiest way to get started is with Docker:
# Clone the repository
git clone https://github.com/k11k-labs/strapi-plugin-better-blocks.git
cd strapi-plugin-better-blocks
# Start the playground with Docker
docker compose upThis will automatically build the plugin and start a Strapi v5 app (SQLite) at http://localhost:1337/admin.
On first launch, create an admin account, then go to Content-Type Builder → Add new field → CUSTOM tab → Better Blocks to try it out.
Development workflow
- Make changes to the plugin source in
admin/src/orserver/src/ - Restart the container to rebuild and pick up changes:
docker compose restart
Full reset
To wipe the database and node_modules and start fresh:
docker compose down -v && docker compose upWithout Docker
yarn install && yarn build
cd playground/strapi && npm install && npm run developCommunity & Support
- GitHub Issues — Bug reports and feature requests
- GitHub Discussions — Questions and ideas
Support this project
This plugin is built and maintained in my free time, and it's free for everyone. If it has saved you time on a project, you can help keep it caffeinated and actively developed:
Every coffee goes toward fixing bugs, reviewing PRs, writing docs, and shipping the features you ask for. Thank you! ☕
License
Install now
npm install @k11k/strapi-plugin-better-blocks
Create your own plugin
Check out the available plugin resources that will help you to develop your plugin or provider and get it listed on the marketplace.