Zum Inhalt springen

Using waitlists

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

This walkthrough follows one back-in-stock cycle end to end: a shopper signs up on an out-of-stock product, you restock it, and every pending subscriber is emailed automatically.

When a product is out of stock or on backorder, Restock renders its form in the product summary, an email field, a required consent checkbox, and a submit button. A logged-in customer’s email is pre-filled.

The shopper enters an email, ticks consent and submits. The submit is an asynchronous fetch to admin-ajax.php (action restock_waitlist_subscribe, nonce-checked), no page reload. The button shows its Sending… busy label, the form sets aria-busy, and the result is announced in an aria-live region: success, invalid email, or missing consent. A confirmed signup resets the form and plays a one-shot success animation (suppressed under prefers-reduced-motion).

Server-side, the same email on the same product is deduplicated by a unique key, so a second signup updates the existing row rather than creating a duplicate. If the row was already notified, re-subscribing reactivates it.

On a variable product the form is output hidden. WooCommerce’s variation script fires found_variation; Restock checks whether that variation is out of stock or on backorder and, if so, reveals the form and stores the variation ID in the hidden product_id field. Choosing a different, in-stock variation hides it again. This is the one place Restock relies on jQuery, it listens to WooCommerce’s own variation events, which are jQuery-based; the submit itself is plain fetch.

If the shopper somehow submits while still on the variable parent (no variation chosen), the server rejects it with the variation required message.

Set the product (or variation) back to In stock. When WooCommerce fires woocommerce_product_set_stock_status with instock, Restock collects pending subscribers for that product ID and, for a variation, its parent, deduplicates across the two, and emails each one with wp_mail. Each subscriber emailed successfully is marked notified, so nobody is contacted twice. There is no queue or cron service to set up.

The notification is plain text, built from your configured subject, intro and closing. {product_name} is substituted in the subject and intro; the product permalink is appended on its own line before the closing. It is sent through your site’s mailer, so deliverability depends on your WordPress email setup (an SMTP plugin or your host). If a test email never arrives, check mail delivery before debugging Restock.

Logged-in customers see a Waitlists tab listing their active (not-yet-notified) signups, matched by user ID or by the email on the account, each with the product’s current stock status and a Leave waitlist button. Leaving is an AJAX call (restock_waitlist_unsubscribe, nonce-checked, logged-in only) that removes the row in place; clearing the last row reloads the empty state. Guests have no account view but still receive the restock email.

By default the form is added to the single-product summary. To put it elsewhere in a custom layout, use the shortcode:

[restock_waitlist]
[restock_waitlist id="123"]

id targets a specific product; without it the shortcode uses the current product in the loop. Either way the form still renders only when that product is out of stock or on backorder, and only while Show form on product page is on, with that setting off the shortcode returns nothing.

Open WooCommerce → Restock → Subscribers for a list with Total, Waiting and Notified counts. Each product link on a subscriber jumps to its edit screen. Append ?product_id=123 (or follow a per-product link) to filter to one product, note the filtered view shows that product’s waiting subscribers only, while the unfiltered view shows everyone. Export CSV downloads the current view (id, product, email, user id, notified flag, created and notified timestamps), nonce-protected, handy for gauging demand before you reorder.

Restock loads templates through a theme-aware loader and exposes two filters around it. There are no shortcode-replacing or form-markup filters beyond these, to change markup, override the template (see Configuration).

// Adjust the variables passed into a Restock template.
add_filter( 'restock/template/args', function ( array $args, string $template ): array {
// $template is e.g. 'single-product/waitlist-form'.
// $args holds 'product', 'settings', 'email' (and 'subscriptions' for the account view).
return $args;
}, 10, 2 );
// Override which file is loaded for a template.
add_filter( 'restock/template/path', function ( string $path, string $template ): string {
return $path;
}, 10, 2 );

(restock/booted exists but is an internal boot signal, not a public extension point.)

The form is server-rendered in PHP in the normal document flow on the product summary, no lazy injection, so no Cumulative Layout Shift. The only front-end script is the small fetch submit handler, enqueued defer in the footer on single-product pages (and on the My Account waitlists endpoint). The email field has a real label as screen-reader text, the consent checkbox is genuinely required, the form reports aria-busy while submitting, and results are announced via aria-live="polite", built with WCAG 2.2 AA in mind.