HTML to Etch Converter — Python Script for WordPress Etch Builder
A free Python converter that turns ordinary HTML into Etch v2.1 NDJSON blocks — paste any HTML file in, get a valid Etch import structure out. Handles messy markup, inline CSS, stylesheet links, script blocks, and single-root wrapping. Python 3.9+, no dependencies, one CLI command.
Etch is a new WordPress builder with a specific nested-block JSON schema — gutenbergBlock, styles, innerBlocks, innerHTML, innerContent. Moving an existing HTML landing page or a Bootstrap snippet into Etch by hand is grim. This converter does the translation in one command: element nodes become etch/element blocks, text nodes become etch/text, inline styles get extracted into proper Etch style definitions, and the output is NDJSON (newline-delimited JSON) ready for Etch paste-import.
What the converter does
- Parses HTML robustly — recovers from malformed or messy markup (unclosed tags, missing quotes, copy-paste soup)
- Converts element and text nodes —
etch/elementfor tags,etch/textfor text content - Extracts CSS from three sources — inline
<style>blocks, local linked stylesheets, inlinestyle=""attributes — all become proper Etch style definitions - Preserves attributes — id, class, href, src, data-* attributes carry over where Etch supports them
- Handles inline scripts — encodes
<script>contents intoattrs.script.codefor Etch script handling - Single-root wrapping — optional flag wraps multiple top-level nodes into one pasteable Etch root block for clean import
- Output formats — NDJSON by default (what Etch paste expects), JSON array for manual inspection
Install and use
Clone the repo. You need Python 3.9+ and nothing else. Run the script with an input HTML file. Default command (recommended for Etch paste-import) wraps content into a single root and outputs NDJSON.
# Clone
git clone https://github.com/wpgaurav/html-to-etch-converter.git
cd html-to-etch-converter
# Recommended command: produces a pasteable Etch import
python3 html_to_etch.py input.html --single-root --root-class etch-page -o output.ndjson
# Basic conversion, print to stdout
python3 html_to_etch.py input.html
# Save NDJSON to a file
python3 html_to_etch.py input.html -o output.ndjson
# Read HTML from stdin (pipe-friendly)
cat page.html | python3 html_to_etch.py -
# Skip empty Etch style definitions
python3 html_to_etch.py input.html --no-empty-styles
# Output a single JSON array instead of NDJSON
python3 html_to_etch.py input.html --format json-array
# Import the output:
# 1. Open the generated NDJSON file
# 2. Select all, copy
# 3. In Etch builder, paste into the structure panel
# 4. Etch resolves the blocks — element structure, styles, and text all renderHow it works
The script uses Python’s built-in html.parser (no third-party dependencies) with recovery logic for malformed HTML. Each element node becomes an etch/element block with its attributes mapped to Etch’s attribute schema. Inline styles are hoisted into the Etch styles field so they persist correctly in the builder. Linked stylesheets (if local to the input file) are read, parsed, and their rules injected into the relevant element’s styles array. Text nodes become etch/text blocks. The output is NDJSON — one JSON object per line — which is the exact format Etch’s paste-import expects. The --single-root flag wraps multiple top-level elements into a single etch/element root with a configurable class name, which is what you usually want when importing a full page.
Download and source
- Repo: github.com/wpgaurav/html-to-etch-converter (MIT)
- Etch builder: etchwp.com — required to paste the output
- Pairs with: GenerateBlocks Skills for other Gutenberg target formats
- Sibling converters: elementor-to-generateblocks, figma-to-generateblocks
FAQs
What Etch version is this targeting?
Etch v2.1 NDJSON format. If you’re on an older Etch beta (pre-2.1), the script’s output will not import cleanly — upgrade Etch first. The script emits the current paste-import schema documented in Etch’s developer docs.
Does it handle CSS Grid and Flexbox?
Yes. Both inline display: grid / flex declarations and linked stylesheet rules with grid/flex are preserved in the styles output. Etch renders them natively.
What about external stylesheets on a CDN?
The script only reads LOCAL stylesheets via relative or file:// paths. CDN-hosted CSS is skipped — use curl to fetch it first, save locally, then run the converter. This is a deliberate safety constraint (no network fetches).
Will inline JS survive the conversion?
Yes, inline <script> blocks are encoded into attrs.script.code. External script tags (src="...") are preserved as attribute references but the script file itself is not downloaded.
Can I convert Bootstrap or Tailwind HTML?
Yes. Bootstrap’s grid classes, Tailwind’s utility classes, and any other class-based framework survive — the script preserves the class attribute. You’ll need the corresponding CSS loaded in Etch for the classes to render (add it to your theme’s global CSS).
Does it work with WordPress post HTML exports?
Yes. Paste the rendered HTML from wp-json/wp/v2/posts/{id} (the content.rendered field) into the converter and it produces a valid Etch import. Great for migrating posts from other builders to Etch.