---
title: "Recipe: back in stock, publish again"
description: "Hide products that are sold out and bring them back when stock returns: two templates that work as a pair, using the back in stock change trigger."
canonical: "https://docs.workflow-suite.app/recipe-back-in-stock-republish"
---

# Recipe: back in stock, publish again

**Goal:** a product that sells out is set to draft, and it becomes active again by itself when stock returns. But only if the workflow hid it: products you set to draft yourself stay drafts.

**Templates:** Hide products that are sold out, and Bring hidden products back when stock returns (category Inventory). They work as a pair. **Needs:** access to inventory and to products, and a secret `SLACK_WEBHOOK_URL`.

## The idea: a mark

The first workflow sets the product to draft and adds the tag `auto-hidden`. The second workflow only acts on products that carry this tag, and removes it again. The tag is how the two workflows talk to each other.

## Create both

1. Create the secret `SLACK_WEBHOOK_URL`. See [Secrets](https://docs.workflow-suite.app/secrets.md).
2. In **Browse templates**, use **Hide products that are sold out**.
3. Then use **Bring hidden products back when stock returns**.

## How the second one is built

| Step | Setting |
| --- | --- |
| Trigger | **Back in stock at location**: the available quantity of an item at one location rises above zero again |
| Look up the product (Shopify query) | Reads the inventory item with its variant and product: id, title, status, tags |
| Condition: It was hidden by the workflow | `steps.item.output.inventoryItem.variants.nodes.0.product.tags` **contains** `auto-hidden` |
| Then: **Set product status** | **Product id** from the query step, **Status** Active |
| **Remove product tags** | **Tags** `auto-hidden` |
| **Send Slack message** | The product's title, and that it is active again |

The lookup is needed because the inventory event carries ids only. Its **Variables (JSON)**:

```liquid
{ "id": "gid://shopify/InventoryItem/{{ event.payload.inventory_item_id }}" }
```

The product id for the actions:

```liquid
{{ steps.item.output.inventoryItem.variants.nodes[0].product.id }}
```

## Test and turn on

1. In each workflow, run a **Test** as a preview. The query runs for real, the status change and the tags are previewed. With the sample event the query finds nothing in your store; paste the numeric `inventory_item_id` of a real item into the **Event (JSON)** to see real data.
2. **Save** and **Turn on** both.

When you turn them on, the app reads your current inventory levels in the background, so that the next change of an item already counts. Until that has reached an item, its first change only sets the starting point. See [Change triggers with before and after values](https://docs.workflow-suite.app/change-triggers.md).

> [!WARNING]
> **Several locations, several variants**
> The triggers work per item and location. A product with three variants is hidden as soon as ONE variant sells out at ONE location, unless you check more. The sold-out template therefore looks at the product's total inventory in its condition before it hides anything. Keep that check, and adjust it if you sell from several locations or let customers buy when out of stock.

## Ideas to extend it

- Replace the status change with **Unpublish product from a sales channel** and **Publish product to a sales channel**, to take the product off the online store only. See [Ready-made Shopify actions](https://docs.workflow-suite.app/shopify-actions.md).
- Only tag instead of hiding: the templates **Tag products that are sold out** and **Remove the sold-out tag when stock is back**.
- Tell a waiting list. **Announce items that are back in stock** posts to Slack; a Send email step can write to addresses you keep elsewhere.

Changing a product's status makes Shopify report a product update. Neither workflow starts on product updates, so they do not trigger themselves. See [Loop protection](https://docs.workflow-suite.app/loop-protection.md).
