The one thing to know first
The GrapesJS canvas is an iframe with its own document. Loading
Tailwind on the host page does nothing for the canvas — utility classes won't
render until Tailwind is loaded inside the canvas. GrapesJS gives you
canvas.styles and canvas.scripts for exactly this.
1. Load Tailwind into the canvas (development)
The Tailwind Play CDN is the quickest way to see classes render live in the editor:
import grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
const editor = grapesjs.init({
container: '#gjs',
height: '100vh',
fromElement: true,
storageManager: false,
canvas: {
// Injected into the canvas iframe, not the host page.
scripts: ['https://cdn.tailwindcss.com'],
},
});
2. Use a built stylesheet (production)
For production, build Tailwind to a real CSS file and pass its URL in
canvas.styles so only the classes you use are shipped:
canvas: {
styles: ['/assets/tailwind.css'],
}
Make sure your Tailwind content globs include wherever your block
HTML lives, so the classes used by blocks aren't purged.
3. Add Tailwind blocks
editor.BlockManager.add('tw-hero', {
label: 'Hero',
content: `
<section class="bg-slate-900 text-white py-20 text-center">
<h1 class="text-4xl font-bold">Headline</h1>
<p class="mt-4 text-slate-300">Supporting copy</p>
</section>`,
});
4. Export Tailwind-styled HTML
const html = editor.getHtml(); // markup keeps its Tailwind classes
const css = editor.getCss(); // GrapesJS-managed styles, if any
// Serve `html` alongside your built Tailwind CSS.
Common pitfalls
Two things catch everyone. First, the canvas is an iframe with its own document — loading Tailwind on the host page does nothing; it must go in canvas.styles or canvas.scripts. Second, purging: in a production Tailwind build, any class that only appears in block strings (not your source files) gets stripped unless your content globs include wherever those blocks live, so hero/section classes silently vanish. The Play CDN is for development only — ship a built stylesheet in production. And remember exported HTML keeps its utility classes, so serve it alongside that same built Tailwind CSS.
Prerequisites
You'll need a GrapesJS setup and a Tailwind workflow (the Play CDN for development or a built stylesheet for production). The one rule to remember: the GrapesJS canvas is an iframe, so Tailwind must be loaded inside it, not just on the host page.
Add Tailwind-styled blocks
Register blocks whose content uses Tailwind utility classes so they render styled on the canvas:
editor.BlockManager.add('tw-hero', {
label: 'Hero',
category: 'Sections',
content: `
<section class="bg-slate-900 text-white py-20 text-center">
<h1 class="text-4xl font-bold">Headline</h1>
<p class="mt-4 text-slate-300">Supporting copy</p>
</section>`,
});
Production: build Tailwind for the canvas
In production, replace the Play CDN with a built stylesheet passed in
canvas.styles, and make sure your Tailwind content globs
include wherever your block HTML lives — otherwise the classes your blocks use are
purged and sections render unstyled:
// tailwind.config.js
content: ['./src/**/*.{html,js,ts}', './src/blocks/**/*.js'],
// grapesjs.init
canvas: { styles: ['/assets/tailwind.css'] }
Performance tips
Ship a purged, built Tailwind stylesheet in production rather than the Play CDN, so the canvas only loads the classes you actually use. Exported HTML keeps its utility classes, so serve it alongside that same built CSS — no per-page style duplication.
Troubleshooting common errors
Classes don't render in the editor means Tailwind isn't loaded
inside the canvas iframe — add it via canvas.styles or
canvas.scripts. Blocks look unstyled in production but fine in
dev means purge removed their classes; widen the content globs.
The host UI changes unexpectedly means you loaded Tailwind on the
page instead of (or as well as) the canvas.
When to use Tailwind with GrapesJS
Tailwind pairs well with GrapesJS when your design system is utility-first and you want exported pages to match production exactly. If your project uses a component CSS framework instead, load that into the canvas the same way — the iframe approach is identical.
Next steps
See the related GrapesJS + React and GrapesJS + Vite guides, browse block library plugins and the GrapesJS marketplace, or start from the GJS.Market home page.
FAQ
Why don't Tailwind classes render in GrapesJS?
The canvas is an iframe with its own document, so Tailwind must be loaded inside
the canvas via canvas.styles or canvas.scripts.
How do I load Tailwind into the canvas?
Dev: add the Play CDN to canvas.scripts. Production: build a Tailwind
stylesheet and pass its URL in canvas.styles.
Does exported HTML keep Tailwind classes?
Yes — editor.getHtml() returns markup with its utility classes
intact; serve it with your built Tailwind CSS.