Skip to main content

Woo Template Integration Contract

Woo components are not enough by themselves. A starter also has to own the Woo routes that WordPress and WooCommerce resolve: product archive, single product, cart, checkout, order confirmation, and any product taxonomy archives the starter exposes.

This page is the public contract for that ownership.

Required Route Ownership​

Route surfaceStarter-owned contentRequired slug or optionNotes
Product archiveActive-theme block templatearchive-productUse Template::new() and render a product loop. The default Woo shop route is usually /shop/.
Single productActive-theme block templatesingle-productUse Template::new() and current-product dynamic data such as {this.id} and {this.omewoo.*}.
CartPage content plus optional page templatewoocommerce_cart_page_id, optionally page-cartAssign a real cart page. A page-cart template should pass through page content or render the Woo cart block.
CheckoutPage content plus optional page templatewoocommerce_checkout_page_id, optionally page-checkoutAssign a real checkout page. A page-checkout template should pass through page content or render the Woo checkout block.
Order confirmationActive-theme block template or Woo-owned page contentorder-confirmation and order-received flowKeep Woo's order received lifecycle intact. Render Woo core order confirmation output for completed orders.
Product taxonomiesActive-theme taxonomy templates when customizedtaxonomy-product_cat, taxonomy-product_tagUse product-loop-aware markup. Do not let taxonomy archives fall back to a non-product post layout if the starter presents them as store routes.

Builder Shape​

The minimum code-owned content shape is:

Demo builder route ownership shape
Template::new()
->slug( 'archive-product' )
->title( 'Product Archive' )
->overwrite()
->blocks_markup( product_archive_blocks() )
->register();

Template::new()
->slug( 'single-product' )
->title( 'Single Product' )
->overwrite()
->blocks_markup( single_product_blocks() )
->register();

$cart_page_id = Page::new()
->slug( 'cart' )
->title( 'Cart' )
->overwrite()
->blocks_markup( cart_page_blocks() )
->register();

$checkout_page_id = Page::new()
->slug( 'checkout' )
->title( 'Checkout' )
->overwrite()
->blocks_markup( checkout_page_blocks() )
->register();

if ( is_int( $cart_page_id ) ) {
update_option( 'woocommerce_cart_page_id', $cart_page_id, false );
}

if ( is_int( $checkout_page_id ) ) {
update_option( 'woocommerce_checkout_page_id', $checkout_page_id, false );
}

Use Page::new() for cart and checkout because those are Woo page settings. A starter can additionally own page-cart and page-checkout templates, but those templates must not hide the assigned page content.

Product Archive And Single Product​

Use Template::new() for archive-product and single-product so the active theme owns those Woo block templates.

Archive templates should render a product loop. Inside each loop item, use {item.*} and {item.omewoo.*} values. Single product templates should use {this.*} and {this.omewoo.*} values from the current product.

Read Product Archive Flow and Single Product Flow for component composition.

Cart And Checkout Page Assignment​

Woo still needs assigned pages. The starter must create or update page content and write the Woo options:

OptionMeaning
woocommerce_cart_page_idPage Woo uses for /cart/, cart links, and cart redirects.
woocommerce_checkout_page_idPage Woo uses for /checkout/, checkout redirects, and payment return fallbacks.

The page slug can be cart and checkout for public starter sites.

If the starter also registers block templates for page-cart or page-checkout, those templates should preserve page content:

Pass assigned page content through page templates
Template::new()
->slug( 'page-cart' )
->title( 'Cart Page Template' )
->overwrite()
->blocks_markup( '<!-- wp:post-content /-->' )
->register();

Template::new()
->slug( 'page-checkout' )
->title( 'Checkout Page Template' )
->overwrite()
->blocks_markup( '<!-- wp:post-content /-->' )
->register();

If your starter has a helper such as CoreBlock::post_content(), use that for the same pass-through behavior. If it does not, the raw core block markup is: <!-- wp:post-content /-->.

Woo Core Block Fallbacks​

When a starter is not composing the cart or checkout with OhMyEtch Woo components, use Woo core blocks inside the assigned page content:

Woo core fallback blocks
$cart_blocks = '<!-- wp:woocommerce/cart /-->';

$checkout_blocks = '<!-- wp:woocommerce/checkout /-->';

$order_confirmation_blocks = '<!-- wp:woocommerce/order-confirmation /-->';

Do not mix a full OhMyEtch checkout form and the Woo checkout block in the same visible checkout surface. Pick one owner for the checkout UI.

Order Confirmation​

The checkout Store API success path redirects into Woo's order received flow. The route can include order-received, and payment gateways may also use Woo-owned return URLs.

If the starter owns order-confirmation, render the Woo core order confirmation block or pass through Woo-managed page content:

Order confirmation template
Template::new()
->slug( 'order-confirmation' )
->title( 'Order Confirmation' )
->overwrite()
->blocks_markup( '<!-- wp:woocommerce/order-confirmation /-->' )
->register();

Do not replace this route with a generic static thank-you page. The customer must land on a Woo-aware surface that can read the completed order context.

Taxonomy Archive Considerations​

Product taxonomy routes are store routes too. If the starter links to product categories or tags, add product-aware taxonomy templates for product_cat and product_tag.

The normal WordPress block template slugs are:

TaxonomyTemplate slug
Product categoriestaxonomy-product_cat
Product tagstaxonomy-product_tag

The template content should reuse the product archive loop shape rather than a generic post archive card. It should render product purchase components only inside a product loop context where {item.omewoo.*} is available.

Starter Skill Smoke Recipe​

A starter-building skill or generated recipe should explicitly mention every required ownership slug before it claims Woo route integration is complete:

Required starter route slugs:
- archive-product
- single-product
- page-cart
- page-checkout
- order-confirmation

Required assigned Woo page options:
- woocommerce_cart_page_id
- woocommerce_checkout_page_id

The smoke should fail if any slug is missing from the generated starter plan or if cart and checkout pages are not assigned to Woo options.

Route Smoke Checklist​

After building a starter, run browser smoke checks against all customer-facing routes:

RouteWhat to verify
/shop/Product archive renders product cards and add-to-cart controls.
/product/.../Single product renders current product data, variation selectors when needed, and purchase controls.
/cart/Cart page is the page stored in woocommerce_cart_page_id; cart rows and empty state render.
/checkout/Checkout page is the page stored in woocommerce_checkout_page_id; checkout fields, payment selector, notices, order summary, and place-order flow render.
order-receivedA completed checkout reaches a Woo order received or order confirmation surface with order-aware content.

A production starter should expose equivalent route checks through its own smoke workflow.