

The WooCommerce checkout shortcode is [woocommerce_checkout]. It belongs on one page only: the WordPress page WooCommerce has assigned as checkout. That page renders the form, address fields, order review, and payment methods. Put the shortcode on an unassigned page and it is just content in the wrong place. The usual result is a checkout that looks blank or broken while the real fault is one missed setting.
WooCommerce checkout page assignment setting
Open WooCommerce > Settings > Advanced > Page setup. This is where you assign the WordPress pages for cart, checkout, and account. Checkout needs two things to line up: the assigned page must contain the shortcode or Checkout block, and WooCommerce must be told to use that same page.
WooCommerce stores that choice as a page ID and uses it throughout the purchase flow. Add-to-cart redirects, wc_get_checkout_url() in custom code, gateway return URLs, payment links for existing orders, and the order-received endpoint all resolve from that ID.
Choose the wrong page and the shortcode can still render where you placed it. The URLs WooCommerce generates will lead somewhere else.
A missing or stale assignment often produces symptoms that do not look like a settings issue:
If the option is not where you expect it, or a setting seems to have no effect at all, our walkthrough on how to customize the WooCommerce checkout page explains the current layout and the overrides that can hide those settings.
WooCommerce offers two checkout paths. The classic [woocommerce_checkout] shortcode renders through PHP templates and the established action and filter hooks around them. The Checkout block takes a newer route: it renders the same core journey in the block interface and keeps its configuration in block attributes.
New stores may start with block-based cart and checkout pages. Existing stores keep their shortcode until someone changes it. WooCommerce does not silently migrate a live checkout. Both paths remain supported, and the block toolbar can transform one into the other. That reversibility makes it the sensible route for a controlled trial.
WooCommerce checkout shortcode versus checkout block
Both paths work with the same order data. The meaningful difference is where custom code and extensions connect. That determines whether this is a short edit or a migration project.
| Area | Classic shortcode | Checkout block |
|---|---|---|
| Rendering | PHP templates, server rendered | Block based, rendered client side |
| Field customization | Classic hooks and filters, template overrides | Block settings plus the Additional Checkout Fields API |
| Payment gateways | Works with any gateway that supports the classic checkout | Needs a gateway with block support, or a compatibility fallback |
| Extension compatibility | Broad, since most plugins were written against the classic hooks | Varies by extension, and the editor flags known incompatibilities |
| Styling | Theme CSS and template overrides | Block styles, theme.json, and block settings |
| Newer checkout features | Not available | Local pickup, express payment area, and other block only additions |
| Editing | Page content and code | Visual editing with live settings in the editor |
Shortcode vs checkout block feature comparison
Treat the editor compatibility notice as an early warning, not decoration. When you add or transform the Checkout block, WooCommerce identifies extensions it knows are incompatible. That is a faster starting inventory than working through release notes.
There is no universal winner. The store decides.
Keep the shortcode when checkout relies heavily on classic hooks, a required gateway lacks block support, or a critical extension appears in the incompatibility list. A known working checkout is more valuable than a newer rendering path.
Move to the block when customization is light or mostly visual, required gateways and extensions support it, and its block-only options are useful to your store. If you are already rebuilding the page, combine the work and test it as one controlled change.
When checkout shows the header and footer with nothing between them, WooCommerce usually does not recognize that page as checkout. Go to WooCommerce > Settings > Advanced > Page setup and confirm that Checkout page points to the URL you are loading. Then check these three items in order:
If the assignment is correct and the page remains empty, inspect the source. Empty markup between header and footer can indicate a suppressed PHP error. Enable WP_DEBUG_LOG on staging and read the log before changing anything else.
If the front end prints [woocommerce_checkout] literally, WordPress did not process it. There are two main causes.
Either the shortcode sits in a context that escapes it, such as a Code block, Preformatted block, or builder text field that emits raw content. Or it is not registered when the page renders. WordPress prints an unregistered shortcode as text, which is exactly what happens if WooCommerce is inactive.
Also rule out copy-and-paste damage. A trailing space in [woocommerce_checkout ] is tolerated, but curly brackets and non-breaking spaces are not. Retype the shortcode directly in WordPress.
Two checkout forms mean two rendering paths are active. The shortcode may be in page content twice, or a theme or builder template already supplies checkout and the shortcode adds another copy.
This is not a visual nuisance. Both forms can submit to the same handler with matching field names and nonce values. The result can be validation errors, wrong totals, or a button that appears unresponsive.
Fix the duplicate at its source. Remove the shortcode when the template owns checkout, or use a plain page template when the shortcode should own the page. Do not hide a form with CSS.
Elementor, Divi, and WPBakery add their own markup and JavaScript around page content. That creates three common failure modes. Some require a shortcode widget or module instead of a text field, so the shortcode prints as text. Others nest the checkout form in containers that interfere with the AJAX order review used to recalculate shipping and totals after an address change.
The third is easy to miss. Many builders ship their own checkout widget. Use it alongside the shortcode and you get duplicate output.
To isolate the builder, create a plain WordPress page containing only the shortcode. Assign it as checkout on staging and load it. If that works, the builder layout is the problem.
“Your cart is currently empty” after you reached checkout with products in the cart is a session or cache issue, not a shortcode issue. WooCommerce uses cookies to identify the session. Anything that strips, rewrites, or caches them can make the cart appear empty.
Typical causes are a full-page cache or CDN returning a cached checkout page, an http/https or www/non-www hostname mismatch, and aggressive object caching. Exclude cart and checkout from every cache layer in use.
Never cache checkout
A migration rarely fails in an obvious way. It can fail for one gateway, one product type, or one country while the rest of checkout still works. That is why it needs a plan.
The failures that come up most often:
Custom Field Compatibility
Custom fields are usually the largest difference. Fields added through the classic checkout fields array or output hooks do not simply appear in the Checkout block. The block uses its own Additional Checkout Fields API. Moving a field means registering it there, not pasting the old snippet into a new page.
Before migrating, inventory every custom field and its source: your own snippet, a plugin, or a builder. Treat anything you cannot trace as at risk. If you cannot list the fields from memory, customizing the checkout page with the block in mind is the better starting point.
Payment Gateway Support
Many major gateways support the Checkout block. Some without native support can still appear through a compatibility layer. “Can” is the important word.
Check the documentation for every enabled payment method. Then verify in the editor: put the Checkout block on a staging page and read the compatibility notice. Treat every unconfirmed gateway as unsupported until a test order proves otherwise, including the methods customers use infrequently.
Use this order, starting on staging:
Keep the classic page
A checkout-page change affects the page, its assignment, and every route that resolves a checkout URL. Test the whole purchase path, not just the first page view:
Step 4 is the one that catches builder and block problems, because it depends on the AJAX order review rather than the initial page load. Our guide on how to test your checkout covers the manual version in more detail, and if the failure started after a plugin or core update, checkout broken after an update narrows it down faster.
That pattern is why checkout changes carry risk: the page can look fine while a subset of orders stops completing. ShopMonitor runs browser-based checkout and form tests every day, then alerts you if the checkout form or thank-you path fails. It verifies the browser checkout and order-received journey, not inbox or email delivery.
ShopMonitor runs browser-based checkout and form tests every day and alerts you when a path breaks. No code changes. No plugins. Setup in 5 minutes.
No credit card required.

About the author
Written by the team at Winning Solutions, the agency behind ShopMonitor. We help WooCommerce teams verify checkout behavior after shortcode changes, page-assignment fixes, and shortcode-to-block migrations.