A Year In, Gutenberg Is Ready for Real Work

A year after Gutenberg's full launch, much of the controversy has settled. The editor's UX and accessibility have matured, and sites built around it are starting to look beyond the migration headache toward the possibilities. Nobody's turning back now.

I fall into the camp that's all-in. There are still rough edges — no lists inside blockquotes, no classes on links, and the block chooser still doesn't respond to arrow keys — but the potential outweighs the papercuts. So I made it a 2020 goal to move CSS-Tricks onto Gutenberg, and started in January of that year.

Starting With a Head Start

We already had some Gutenberg experience: we'd converted our newsletter authoring to the new editor. Those newsletters are a Custom Post Type, published at public URLs, served through a custom RSS feed, and picked up by MailChimp.

Enabling Gutenberg for the newsletter CPY was straightforward via the Gutenberg Ramp plugin. But I wanted Gutenberg turned on only for new content, not for the tens of thousands of legacy posts. I wound up modifying the plugin to make that happen. The old editor is still the better experience for our older posts — we have special buttons for our custom code blocks and similar — and Gutenberg doesn't cleanly convert them anyway.

Ideally, Gutenberg would parse existing HTML, detect which blocks fit where (including custom ones), and convert everything into proper blocks upon opening. That remains a distant dream. Instead, old content stays on the classic editor. There's no simple toggle to flip an individual post to Gutenberg from within the editor either; it requires hard-coding values into the Ramp setup, which is tedious.

There is a lingering worry that the classic editor will degrade over time. On this site, it already has a frustrating habit of randomly scrolling to the bottom of the page while authoring — a papercut bug that made me want to move to the actively developed editor. Even if the old editor becomes unusable, switching everything over isn't catastrophic: old posts would just become one giant classic block.

New Posts, New Editor

Getting Gutenberg turned on for new posts was its own challenge, but it's done. New content is created in it, and the team is happy. For anyone writing content regularly, it's a significant upgrade.

When Not to Build a Block

Consider a fancy text block we use:

A “callout” block on CSS-Tricks

At first glance, that seems like a good candidate for a custom block. But the only distinguishing feature is a class name that our CSS uses for styling — and class names are built into every block. A custom block isn't needed.

We went one step further and turned that text block into a reusable block. Once created, selecting "Convert to Reusable Block" from the kebab menu saves it permanently, so we don't need to remember or type the class each time.

We've applied the same pattern elsewhere: an "Article Series" block is just an <h4> and <ol> wrapped in a styled <div>, plus footnote blocks.

Custom Blocks for Real Needs

Some blocks genuinely need custom code. I used create-guten-block to build a plugin for those. Our most important one is the code block. The native block puts escaped content in a <pre> tag, but ours lets us specify a language, highlight certain lines, and add custom labels — all of which were previously possible via HTML attributes in the old editor. This block is just a friendlier UI over that functionality.

That block is CSS-Tricks-specific, so it doesn't make sense to open-source it. But the CodePen Embed Block is open source and available on WordPress.org. It lets you paste a CodePen URL and get an embed — oEmbed already does this by default, but this plugin gives you control over height, theme, and default tabs.

Seeing the actual Pens while authoring is a nice touch.

The Image Problem Remains

The biggest challenge right now is images. In the old editor, we had an elaborate Cloudinary integration: images auto-upload, breakpoints are computed programmatically, multiple sizes are generated, and the resulting HTML uses proper responsive image syntax with Cloudinary hosting. That setup gave us CDN delivery and optimal formats.

None of that applies to posts created with Gutenberg.

We need either a new system or a replacement for the old one that works site-wide — ideally something less bespoke and easier to maintain. The options include staying with Cloudinary, trying another service, or letting WordPress handle images natively with Jetpack Site Accelerator. I don't have an answer yet.

I also noticed WordPress themselves has gotten into block scaffolding. Their npm init @wordpress/block [options] [slug] is now part of the Gutenberg repo.