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. It translates the repo-backed demo flow into starter-safe rules.

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.

Source-Backed Builder Shape

The local demo store builder proves the minimum code-owned content shape:

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 );
}

The demo uses 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. The demo uses ome-demo-cart and ome-demo-checkout to keep fixture pages isolated.

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.

For the repo demo flow, WooDemoStoreBuilder returns preview URLs for archive, single, cart, and checkout. A production starter should expose equivalent route checks through its own smoke workflow.