Previous Article
PayPal Webhooks in PHP: The Modern Replacement for IPN
1 May 2018
WooCommerce shortcodes let you drop products, carts and account pages into any post or page. The list has changed substantially over the years — a dozen product shortcodes were consolidated into one, and Cart and Checkout have been replaced by blocks as the default.
This is the current reference: what still works, what was removed and what to use instead.
Since WooCommerce 8.3, new installations create the Cart and Checkout pages using blocks rather than the [woocommerce_cart] and [woocommerce_checkout] shortcodes.
The shortcodes still function — existing stores were not broken — but the blocks are where development now happens. They render faster, because the block versions avoid a full page reload on quantity changes, and several newer features (express payment buttons, the local pickup option) are block-only.
If you are running an older store, you can switch by editing the Cart or Checkout page, deleting the shortcode block, and inserting the Cart or Checkout block instead. Test your payment gateways afterwards — some third-party gateways took a long time to support the block checkout, and a few still do not.
Stay on the shortcodes if you have heavy customisation via checkout hooks, since most of those hooks do not fire in the block version.
These are inserted automatically when WooCommerce is installed. You rarely need to place them by hand.
| Shortcode | Purpose |
|---|---|
[woocommerce_cart] | The cart page |
[woocommerce_checkout] | The checkout page |
[woocommerce_my_account] | The customer account area |
[woocommerce_order_tracking] | The order tracking form |
Each belongs on its own page, and WooCommerce needs to know which page is which — check WooCommerce → Settings → Advanced if pages behave oddly after a migration.
The following were valid in WooCommerce 2.0 and are gone. They are now endpoints of the My Account page, handled automatically by [woocommerce_my_account]:
[woocommerce_edit_account] → /my-account/edit-account/
[woocommerce_change_password] → /my-account/edit-account/
[woocommerce_view_order] → /my-account/view-order/{id}/
[woocommerce_edit_address] → /my-account/edit-address/
[woocommerce_lost_password] → /my-account/lost-password/
[woocommerce_logout] → /my-account/customer-logout/
[woocommerce_pay] → part of the checkout flow
[woocommerce_thankyou] → part of the checkout flow
If an old page still contains one of these, it renders as literal text on the front end. Configure endpoint URLs under WooCommerce → Settings → Advanced → Account endpoints.
WooCommerce 3.2 consolidated [recent_products], [featured_products], [sale_products], [best_selling_products], [top_rated_products], [product_category] and [related_products] into a single flexible shortcode. The old ones still work but are deprecated and receive no new features.
[products limit="8" columns="4" orderby="date" order="DESC"]
| Attribute | Values | Notes |
|---|---|---|
limit | number | How many to show. -1 for all. |
columns | number | Grid columns; default 4. |
paginate | true / false | Adds pagination. Requires limit. |
orderby | date, price, popularity, rating, rand, title, menu_order, id | Several may be space-separated. |
order | ASC / DESC | Direction. |
category | slug(s) | Comma-separated. |
tag | slug(s) | Comma-separated. |
attribute | attribute slug | Without the pa_ prefix. |
terms | term slug(s) | Used with attribute. |
ids | product IDs | Comma-separated. |
skus | SKUs | Comma-separated. |
on_sale | true | Cannot combine with best_selling or top_rated. |
best_selling | true | As above. |
top_rated | true | As above. |
visibility | visible, catalog, search, hidden, featured | featured replaces the old shortcode. |
class | string | Extra CSS class on the wrapper. |
<!-- Featured products (replaces [featured_products]) --> [products limit="4" columns="4" visibility="featured"] <!-- On sale, cheapest first --> [products limit="8" columns="4" on_sale="true" orderby="price" order="ASC"] <!-- One category, paginated --> [products category="hoodies" limit="12" columns="3" paginate="true"] <!-- Specific products by SKU, in a chosen order --> [products skus="HD-001, TS-114, MG-020" orderby="menu_order"] <!-- Filter by an attribute term --> [products attribute="colour" terms="blue" limit="8"] <!-- Best sellers --> [products limit="5" columns="5" best_selling="true"]
Embeds a complete single-product page — gallery, description, add-to-cart form and all — inside another page:
[product_page id="99"] [product_page sku="HD-001"]
Just the price and button for one product:
[add_to_cart id="99"] [add_to_cart id="99" show_price="false" style="" quantity="2"]
Pass style="" to drop the inline border WooCommerce applies by default, which almost never matches a custom theme.
Outputs only the URL, for use in your own markup:
<a class="btn" href="[add_to_cart_url id='99']">Buy now</a>
[product_categories limit="6" columns="3" orderby="name" hide_empty="1" parent="0"]
Setting parent="0" shows only top-level categories. hide_empty="0" includes categories with no products.
Insert a Shortcode block and paste it in. Better still, use the native WooCommerce product blocks — they render a live preview while you edit rather than a grey placeholder, and support the same filtering through the sidebar.
In a classic-theme template file, render them from PHP:
<?php echo do_shortcode('[products limit="4" columns="4" visibility="featured"]'); ?>
Use echo do_shortcode(), not do_shortcode() alone — the function returns a string rather than printing it.
Each [products] shortcode runs its own database query. Half a dozen on one page means half a dozen product queries plus their meta lookups, which on a large catalogue is genuinely slow. Keep the count low on high-traffic pages, and use a page cache so the queries run once rather than per visitor.
Use [products] with attributes for anything product related — the older per-purpose shortcodes are deprecated. The four page shortcodes remain valid, though Cart and Checkout are now blocks by default and that is where new features land. And if an old account shortcode is rendering as plain text on your site, it was removed years ago; the My Account endpoints handle it now.
Advertisement
Written by
Amit VermaFounder / Senior Software Engineer
Amit leads engineering at Being Idea. With 15+ years building scalable software products across global markets, he drives architecture decisions and engineering culture across every engagement.
More articles by AmitYou might also like
We ship software that scales. Let's work together.