How to Add an Order Bump to the WooCommerce Block Checkout Page (No jQuery, No Legacy AJAX)
The new WooCommerce Checkout Block brings a modern React-based checkout experience. But customizing it — like adding an order bump — requires a slightly different approach compared to classic shortcodes or hooks.
In this guide, you’ll learn how to:
- Insert a specific product (by ID) as an order bump.
- Render the product in a list-style layout.
- Add the bump product to the cart using modern WooCommerce JS (not
$.ajax
oradmin-ajax.php
).
Step 1: Inject HTML After a Specific Checkout Block
In block themes, hooks like woocommerce_before_checkout_form
don’t work. Instead, we use render_block
to inject our custom HTML container directly after the checkout block.
PHP – Add HTML container for the order bump:
add_filter('render_block', function ($block_content, $block) {
if ($block['blockName'] === 'woocommerce/checkout') {
$custom_bump = '<div id="my-order-bump" class="order-bump-container" style="display:none;" data-product-id="123"></div>';
return $block_content . $custom_bump;
}
return $block_content;
}, 10, 2);
Replace
123
with your bump product ID.
Step 2: Move the Container into Position After Checkout Block Renders
React renders the checkout in parts, so you can’t insert your bump HTML right away. Use polling (setInterval
) to wait until the DOM node appears.
JS – Wait and inject the bump:
document.addEventListener('DOMContentLoaded', function () {
const MAX_ATTEMPTS = 50;
const INTERVAL_MS = 300;
let attempts = 0;
const injectBumpAfter = (selector, bumpId = 'my-order-bump') => {
const ref = document.querySelector(selector);
const bump = document.getElementById(bumpId);
if (ref && bump && !bump.dataset.injected) {
ref.insertAdjacentElement('afterend', bump);
bump.style.display = 'block';
bump.dataset.injected = 'true';
return true;
}
return false;
};
const interval = setInterval(() => {
if (injectBumpAfter('.wp-block-woocommerce-checkout-shipping-methods-block') || ++attempts >= MAX_ATTEMPTS) {
clearInterval(interval);
}
}, INTERVAL_MS);
});
Step 3: Render the Product in List Format via REST API
Let’s fetch the product using WooCommerce’s REST API and show it inside the order bump container.
JS – Fetch and display product:
async function renderOrderBump(productId) {
const container = document.getElementById('my-order-bump');
if (!container) return;
const res = await fetch(`/wp-json/wc/store/products/${productId}`);
const product = await res.json();
container.innerHTML = `
<div class="bump-product" style="border:1px solid #ccc; padding:1em; margin-top:1em;">
<h3>${product.name}</h3>
<img src="${product.images?.[0]?.src}" alt="${product.name}" style="max-width:100px;" />
<p>${product.price_html}</p>
<button class="add-bump-to-cart" data-product-id="${product.id}">Add to Order</button>
</div>
`;
}
document.addEventListener('DOMContentLoaded', () => {
const bump = document.getElementById('my-order-bump');
if (bump?.dataset.productId) {
renderOrderBump(bump.dataset.productId);
}
});
Step 4: Add to Cart Using WooCommerce Store API (Not jQuery AJAX)
WooCommerce’s block-based system uses the Store API and JS events. Use the @woocommerce/blocks-checkout
client or call the REST endpoint directly.
JS – Add product to cart with fetch (no jQuery):
document.addEventListener('click', async (e) => {
if (!e.target.matches('.add-bump-to-cart')) return;
const productId = e.target.dataset.productId;
e.target.disabled = true;
e.target.textContent = 'Adding...';
const res = await fetch('/?rest_route=/wc/store/cart/add-item', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({ id: parseInt(productId, 10), quantity: 1 })
});
if (res.ok) {
e.target.textContent = 'Added!';
document.dispatchEvent(new CustomEvent('wc-blocks-cart__updated'));
} else {
e.target.textContent = 'Try again';
e.target.disabled = false;
}
});
Final Notes
- You can customize the
renderOrderBump()
function to show multiple products or a custom layout. - Styling can be adjusted with CSS or Tailwind.
- Use the
wc/store/cart
endpoints for quantity changes, removals, etc. - You don’t need jQuery or
admin-ajax.php
.
Bonus: Support Multiple Order Bumps?
Just repeat the container with different data-product-id
s and render them dynamically.
Leave a Reply