Tutorial
Gutenberg block vs shortcode for forms
Both work. They're not equivalent. Here's the rule for when to use the Core Forms block versus the shortcode, with the actual tradeoffs.
Core Forms ships two ways to embed a form: the Gutenberg block and the shortcode. They render the same HTML. They’re not equivalent for the editor experience.
Picking the right one per use case saves clients confusion and saves you support tickets.
The block wins when
1. You’re using the Block Editor (Gutenberg). Obvious but worth stating. Inside the Block Editor, the block gives you a live server-rendered preview, an inspector sidebar with form-picker dropdown, and per-block controls (alignment, max-width, anchor, header toggle).
2. You’re working with a non-technical editor. Block UI is more discoverable. The “Insert block” search finds “Core Form” instantly. The shortcode requires the user to remember the shortcode syntax and the form’s slug.
3. You want per-instance overrides. The block has per-instance settings: show form title, set heading level, alignment, max-width, anchor ID, force-load or force-disable each stylesheet. None of that is reachable through the shortcode without writing a custom shortcode wrapper.
4. You’re building Full Site Editing templates. FSE template parts only support blocks. The shortcode in an FSE template requires a workaround block to render.
For 80% of modern WordPress sites, the block is the right call.
The shortcode wins when
1. You’re working in the Classic Editor. Some sites still are. The shortcode is the only path.
2. You’re embedding inside a non-Block context. Widgets (in some themes), email templates, custom theme templates calling do_shortcode(), page builders that don’t natively support blocks (Bricks, GeneratePress’ Element system).
3. You want to embed via PHP. A theme template that includes the form via <?php echo do_shortcode('[cf_form slug="contact"]'); ?> is shorter than the equivalent block-render call.
4. You want one canonical reference and no per-instance variation. If every embed of “Contact” should look identical, the shortcode forces that. The block tempts editors to tweak alignment, max-width, etc. on every instance.
For legacy sites, theme-template embeds, and “consistency over flexibility” use cases, the shortcode wins.
The thing nobody mentions
Both render the same HTML. The form is a <form> element with the same fields, same attributes, same classes. The block doesn’t add wrapper divs by default. The shortcode doesn’t add wrapper divs.
So once the form is rendered to the page, you can’t tell which embedding method was used.
This means: switching from shortcode to block (or back) on an existing page is safe. The form keeps working. CSS targets stay valid. JavaScript hooks stay attached.
Don’t fear the migration in either direction.
What the block does that the shortcode can’t
Five things, in order of usefulness:
1. Live server-rendered preview. In the Block Editor, you see the actual form (with real field labels, real submit button) as you edit the page. The shortcode shows [cf_form slug="contact"] as text. For previewing layouts, the block is night-and-day better.
2. Form picker dropdown. Pick the form from a dropdown of all forms on the site. Versus typing slug="contact" and hoping you didn’t typo.
3. Optional title rendering. The block can render the form’s title as a heading above the form. The shortcode doesn’t. (This is a v4.0.0 feature.)
4. Alignment / max-width / anchor. All three are inspector controls on the block. The shortcode would need wrapper HTML for the same.
5. Per-block stylesheet override. Force-load or force-disable the form theme stylesheet on a per-block basis. Useful for “this one form on this one page should look different.” The shortcode obeys global settings only.
What the shortcode does that the block can’t
Two things:
1. PHP embedding. <?php echo do_shortcode('[cf_form slug="contact"]'); ?> works in any theme template. The block doesn’t have a clean PHP API for the same.
2. Embedding in places blocks can’t go. Some widget areas, some page-builder layouts, classic-editor posts, and email templates accept shortcodes but not blocks. The shortcode’s universality is its main advantage.
The hybrid pattern
For a site where the homepage uses the Block Editor but the theme has a custom footer template:
- Use the block on Block-Editor pages. Editors get the visual UX.
- Use the shortcode in the theme template (
<?php echo do_shortcode('[cf_form slug="contact"]'); ?>).
Same form. Two embedding contexts. Both render the same HTML.
I do this on most client sites. The block is for the marketing team, the shortcode is for the developer-controlled templates.
The migration in v4.0.0
In Core Forms 4.0.0, the Gutenberg block got a significant overhaul:
- The block stylesheet was removed from
block.json(it was force-loading on every page that had the block, ignoring the user’s “Default form theme” setting). - The form-picker dropdown got friendlier.
- Per-block controls (header toggle, heading level, alignment, max-width, anchor, stylesheet override) all landed.
If you’re on an older version, the block had fewer controls. The migration to v4.0.0 cleaned those up.
The next step
Pick one site. Look at how forms are embedded. If everything’s a shortcode but the editors are in Gutenberg, swap to the block on the next form edit — they’ll thank you.
Both are bundled in Core Forms. Pick the right one per use case. Pricing.