WPWing Smart Wishlist & Product Waitlist for WooCommerce
Let shoppers save products to a wishlist and get back-in-stock email notifications — guest-friendly, zero configuration.
Quick Start
Both features are live immediately after activation. No configuration is required.
- Go to Plugins → Add New → Upload Plugin, upload the ZIP, and click Activate.
- Visit any product page — the wishlist button and (on out-of-stock products) the waitlist form are already there.
- Optional: Create a page, paste the
[wpwing_wishlist]shortcode, and publish it. Then go to WPWing → Settings and select that page as the Wishlist Page so the nav count badge links to it.
Wishlist
Shoppers can save any product with a single click. The toggle button appears on every product page and switches between Add to wishlist and Remove from wishlist via AJAX — no page reload.
Guest support
Guests save items via a browser cookie. No account needed. Items auto-merge into the shopper's account when they log in — no duplicates.
Variable products
The button is variation-aware. Each variation is tracked independently, and the button state updates in real time as a shopper switches options.
Nav count badge
A live count badge is automatically injected into your site's navigation menu showing the number of items saved. It updates on every toggle without a page reload.
Dedicated wishlist page
Use the [wpwing_wishlist] shortcode on any page to display the shopper's full list with product images, prices, and an inline Remove button.
How the nav badge works
The plugin scans your active nav menus and injects a small count span automatically. No theme edits required. If you want to disable this, add the following to your theme's functions.php:
add_filter( 'wpwing_wl_show_count_in_nav', '__return_false' );
Guest wishlist retention
Guest wishlist items are kept for 30 days by default. This is configurable under WPWing → Settings → Guest Retention. A weekly background job clears expired guest rows automatically.
Back-in-Stock Waitlist
When a product is out of stock, an email capture form appears on the product page automatically. When stock is restored, subscribers receive a notification email and can return to buy.
Automatic form placement
The form appears only when the product (or selected variation) is out of stock. No shortcodes or theme edits needed.
Variation-aware
For variable products the form shows and hides in real time as the shopper selects different options — only out-of-stock variations trigger the form.
Async notifications
Emails are dispatched via Action Scheduler (bundled with WooCommerce). Restocking 500 products never slows down your admin screen.
Spam protection
A hidden honeypot field blocks bots. Rate limiting (30 signups/hour per IP, 5/hour per email) prevents bulk abuse — without a CAPTCHA.
How restock notifications work
- WooCommerce updates stock — the plugin detects the stock change immediately.
- A background job is scheduled via Action Scheduler to process the subscriber list in batches of 50.
- Each subscriber receives a notification email with a one-click unsubscribe link.
- The subscriber's row is marked notified with a timestamp. Clicking unsubscribe marks it unsubscribed.
Guest signups
Guests sign up using only their email address. The plugin sets a cookie per product/variation so the shopper sees the "You're on the list" state if they return to the page before the cookie expires.
One-click unsubscribe
Every notification email includes an unsubscribe link unique to that subscriber. Clicking it immediately removes them from future notifications for that product. The plugin also sends the RFC 8058 List-Unsubscribe header so Gmail and Outlook display a native unsubscribe button in the email client.
Shortcodes
[wpwing_wishlist]
Renders the current shopper's saved products as a table with product image, name, price, an Add to Cart button, and an inline Remove button. Shows an empty-state message when the list is empty.
Place this shortcode on a dedicated My Wishlist page, then select that page under WPWing → Settings → Wishlist Page so the nav count badge links to it correctly.
[wpwing_wishlist_count]
Renders a small count badge showing the number of products in the current shopper's wishlist. Links to the configured Wishlist Page when one is set. Useful if you want to place the badge manually — for example, in a header widget or a custom menu item.
<!-- Example: add to a Custom HTML widget -->
[wpwing_wishlist_count]
Settings
All settings live under WPWing → Settings. Every field has a sensible default — you only need to change what you want to customise.
| Setting | Default | Description |
|---|---|---|
| Enable Wishlist | On | Toggle the entire wishlist feature. Disabling hides the button and shortcodes but keeps existing data. |
| Enable Waitlist | On | Toggle the entire waitlist feature. Disabling hides the form but keeps existing subscriber data. |
| Wishlist Page | None | The page containing the [wpwing_wishlist] shortcode. When set, the nav count badge links here. |
| From Name | Site title | Sender name shown in restock notification emails. |
| From Email | Admin email | Sender address for restock notifications. Must be a valid email address. |
| Reply-To | From email | The address subscribers see when they hit Reply in their email client. |
| Email Subject | Built-in template | Subject line for restock emails. Supports placeholders: {product_name}, {store_name}. |
| Email Body | Built-in template | HTML body of the restock email. Supports: {product_name}, {product_url}, {unsubscribe_url}, {store_name}. |
| Guest Retention | 30 days | How long guest wishlist items are kept before the weekly cleanup removes them. Range: 1–3,650 days. |
Admin Pages
WPWing → Waitlist
A paginated table of all waitlist signups. You can:
- Filter by product and status (Active, Notified, Unsubscribed)
- Delete individual entries or bulk-delete selected rows
- Export the current filtered view to CSV
- Click Resend Notifications to retry sending for entries that may have failed
WPWing → Wishlist
A ranked table of the 50 most-wishlisted products, ordered by the number of times each product has been saved. This gives you a live demand signal — you can see what shoppers want before it shows up in sales. You can also:
- Filter by product
- Delete individual entries or bulk-delete selected rows
- Export the full wishlist table to CSV
Hooks & Filters
Every meaningful step fires an action or filter so you can customise behaviour without modifying plugin files.
Actions
Fires after a product is successfully added to a wishlist.
Parameters: int $product_id, int $variation_id, int|null $user_id
Fires after a product is successfully removed from a wishlist.
Parameters: int $product_id, int $variation_id, int|null $user_id
Fires when WooCommerce records a stock change that brings a product back into stock.
Parameters: int $product_id, int $variation_id, string $new_status
Fires immediately before a restock notification email is sent to a subscriber.
Parameters: object $entry, WC_Product $product
Fires after a restock notification email is sent (or fails).
Parameters: object $entry, WC_Product $product, bool $sent
Fires at the start of each restock queue batch job, before any emails are sent.
Parameters: int $product_id, int $variation_id
Fires at the end of each restock queue batch job, after all emails in the batch are processed.
Parameters: int $product_id, int $variation_id
Filters
Filter the list of subscriber entries before emails are sent in a batch. Use this to deduplicate, apply suppression lists, or skip specific subscribers.
Parameters: array $entries, int $product_id, int $variation_id
Returns: array
add_filter( 'wpwing_wl_restock_queue_entries', function( $entries, $product_id, $variation_id ) {
// Remove entries matching a suppression list.
return array_filter( $entries, fn( $e ) => ! in_suppression_list( $e->email ) );
}, 10, 3 );
Filter the HTML body of the restock notification email before it is sent. Useful for integrating with a transactional email service or applying a custom template.
Parameters: string $message, object $entry, WC_Product $product
Returns: string
add_filter( 'wpwing_wl_restock_email_message', function( $message, $entry, $product ) {
// Replace with your own HTML template.
return my_custom_email_template( $product, $entry->email );
}, 10, 3 );
Return false to prevent the wishlist count badge from being injected into navigation menus.
Parameters: bool $show
Returns: bool
add_filter( 'wpwing_wl_show_count_in_nav', '__return_false' );
FAQ
Does the plugin work with variable products?
Yes. Both features are variation-aware. The waitlist form appears and disappears in real time as a shopper selects different options, and only shows for variations that are actually out of stock. The wishlist button tracks each variation independently.
Do shoppers need an account to use the wishlist or waitlist?
No. Guests can save products to a wishlist using a browser cookie and join waitlists using only an email address. If a guest creates an account or logs in, their wishlist items are automatically merged — no duplicates, nothing lost.
How does the restock notification email get sent?
When WooCommerce records a stock change that brings a product back into stock, the plugin schedules a background job via Action Scheduler (bundled with WooCommerce — no separate install needed). Action Scheduler processes subscribers in batches of 50, so restocking a large catalogue never slows down your admin screen.
Can I customise the restock notification email?
Yes — two ways. The simplest is to edit the subject and body template under WPWing → Settings. The body supports HTML and the placeholders {product_name}, {product_url}, {unsubscribe_url}, and {store_name}. For full control (custom templates, third-party email services), use the wpwing_wl_restock_email_message filter.
What happens to my data if I deactivate the plugin?
Nothing. Deactivating the plugin leaves all wishlist and waitlist data in place. Both database tables and all settings are preserved. Reactivating restores everything.
What happens if I delete (uninstall) the plugin?
Deleting the plugin via Plugins → Delete permanently drops both custom database tables and removes all plugin options. This action cannot be undone. Deactivating without deleting is safe and preserves all data.
Is the plugin GDPR-compliant?
The plugin integrates with WordPress's built-in Tools → Export Personal Data and Erase Personal Data features. When a data export is requested for an email address, the plugin includes all associated waitlist and wishlist records. When erasure is requested, those records are permanently deleted.
My theme doesn't show the nav count badge. Why?
The badge is injected into menus rendered by wp_nav_menu(). If your theme renders navigation differently (for example using a custom block or a page builder widget), the automatic injection won't apply. In that case, place [wpwing_wishlist_count] manually wherever you want the badge to appear.