HTML to Gutenberg Blocks Converter
Turn pasted HTML into real block markup: headings, lists, images, quotes, tables and groups, with anything else kept as a custom HTML block.
Enable JavaScript to convert your own HTML; the blocks below are the example.
Nothing is uploaded. The conversion happens in this tab.
15 blocks: 1 code, 1 group, 2 heading, 1 html, 1 image, 1 list, 3 list-item, 3 paragraph, 1 quote, 1 table. Dropped 1 <script>, which a block cannot carry past kses.
-
-
heading<h1>Release 2.4 -
paragraph<p>Some bold text and a link. -
list<ul>One Two Nested -
image<figure>The settings screen -
quote<blockquote>A quote, with its own paragraph. -
code<pre>if ( a < b ) { run(); } -
table<table>SettingDefaultcacheon -
group<div>In a wrapperNested content. -
html<iframe>
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Release 2.4</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Some <strong>bold</strong> text and a <a href="https://example.com">link</a>.</p>
<!-- /wp:paragraph -->
<!-- wp:list -->
<ul class="wp-block-list">
<!-- wp:list-item -->
<li>One</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>Two
<!-- wp:list -->
<ul class="wp-block-list">
<!-- wp:list-item -->
<li>Nested</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
<!-- wp:image -->
<figure class="wp-block-image"><img src="/wp-content/uploads/shot.png" alt="A screenshot" width="1200" height="800" /><figcaption class="wp-block-image__caption">The settings screen</figcaption></figure>
<!-- /wp:image -->
<!-- wp:quote -->
<blockquote class="wp-block-quote">
<!-- wp:paragraph -->
<p>A quote, with its own paragraph.</p>
<!-- /wp:paragraph -->
</blockquote>
<!-- /wp:quote -->
<!-- wp:code -->
<pre class="wp-block-code"><code>if ( a < b ) { run(); }</code></pre>
<!-- /wp:code -->
<!-- wp:table -->
<figure class="wp-block-table"><table><thead><tr><th>Setting</th><th>Default</th></tr></thead><tbody><tr><td>cache</td><td>on</td></tr></tbody></table></figure>
<!-- /wp:table -->
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
<!-- wp:heading -->
<h2 class="wp-block-heading">In a wrapper</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Nested content.</p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:group -->
<!-- wp:html -->
<iframe src="https://www.youtube.com/embed/x" width="560" height="315"></iframe>
<!-- /wp:html -->
Pasting HTML into the WordPress editor gives you one enormous custom HTML block, or a pile of paragraphs with the structure flattened out of them. Block markup is what the editor actually stores: HTML with a comment in front of each piece saying which block it is. This writes those comments.
Paste it into the editor’s code editor view and every block is a real block: editable, movable, styled by the theme.
How to use
- Paste the HTML. A whole page, one section, or a fragment from an old post.
- Leave Keep wrappers as groups on if the layout matters, off if you want
the contents of a
divto become top-level blocks. Off is usually right when moving one section out of an old theme. - Read the report. It says how many of each block came out, and names anything that was dropped or stripped.
- Copy the markup. In the post editor, open the options menu (three dots, top right), choose Code editor, paste, then switch back to the visual editor.
Example
This HTML:
<ul>
<li>One
<li>Two
<ul><li>Nested</li></ul>
</ul>
becomes this:
<!-- wp:list -->
<ul class="wp-block-list">
<!-- wp:list-item -->
<li>One</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>Two
<!-- wp:list -->
<ul class="wp-block-list">
<!-- wp:list-item -->
<li>Nested</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
Three things happened there that a search and replace could not do. The
unclosed <li> elements were closed, because HTML says an <li> closes the
one before it. Each item became its own wp:list-item block, which is what
makes items draggable in the editor. And the nested list went inside its
parent item rather than beside it, which is the shape the list block requires;
put it beside and the editor shows the whole list as invalid content.
Pitfalls
<script> and <style> are dropped. Not converted, dropped, and the report
says how many. WordPress strips both from post content on save for anyone
without unfiltered_html, so a block that carried them would lose them the
first time the post was updated. Put scripts in the theme or a plugin.
Inline event handlers and unsafe links go too. onclick, and any href or
src whose scheme is not http, https, mailto, tel or a relative path. Same
reason: kses would remove them, and a block whose saved markup differs from its
stored markup is a block the editor flags as invalid.
Classes are dropped by default. A pasted class="lead" means nothing
without the stylesheet it came from. Turn Keep class attributes on if you are
bringing the CSS too.
A custom HTML block is a real answer. An <iframe>, a <video>, a
<form>: there is no core block that holds them with their attributes intact,
so they become wp:html. That is what the editor’s own “convert to HTML” does,
and it is better than dropping the element.
The markup is not validated against your block versions. It targets core
blocks as they are in WordPress 6.5 and later. A block plugin that replaces
core/list may parse it differently.
Compatibility
Block markup is stable: the comment format has not changed since Gutenberg
shipped in WordPress 5.0, and the attributes used here (level on a heading,
ordered on a list, layout on a group) are all current in WordPress 6.5
through 6.8.
The conversion happens in the browser and nothing is uploaded, so an unpublished page can be converted without leaving the tab.
Blocks produced: paragraph, heading, list, list-item, image, quote, code, separator, table, buttons, button, group and html. Elements with no block of their own become html rather than disappearing.
Frequently asked questions
Where do I paste the result?
Why did my <div> disappear?
wp:group with the layout attribute
instead.Can I convert a whole exported page?
<head>, <script> and <style> parts of it will be dropped
rather than converted. What comes out is the content, which is what a post can
hold.What about ACF or a page builder’s markup?
<!-- wp:acf/... --> comments are not read as blocks, because the input is
treated as HTML, not as block markup.