> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecharlie.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Product Rules

> Prioritize fulfillment locations based on what products are in the cart

Product rules let you prioritize locations based on **what's in the cart**. When a customer orders specific products, you can control which locations should be preferred for fulfillment.

<Info>
  Unlike [fulfillment constraints](/constraints/product-rules) which **block** locations, product routing rules **prioritize** locations. If the preferred location is out of stock, Shopify automatically falls back to the next available location.
</Info>

## Constraints vs Routing

|                                       | Fulfillment Constraints                          | Order Routing Rules                                              |
| ------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------- |
| **Effect**                            | Blocks locations entirely                        | Ranks locations by preference                                    |
| **If no stock at preferred location** | Checkout blocked                                 | Falls back to next priority                                      |
| **Configured in**                     | Charlie app                                      | Shopify Order Routing settings                                   |
| **Use case**                          | "Fragile items can NEVER ship from small stores" | "Prefer warehouse for fragile items, but allow stores as backup" |

## How product routing rules work

A product routing rule has two parts:

1. **When** (condition): Which products trigger the rule
2. **Then** (groups): How to rank locations when triggered

```mermaid theme={"system"}
flowchart LR
    A[Customer adds<br/>product to cart] --> B{Product matches<br/>rule condition?}
    B -->|No| C[Default routing<br/>applies]
    B -->|Yes| D[Apply location<br/>group ranking]
    D --> E[Try Group 1 first]
    E --> F{Stock<br/>available?}
    F -->|Yes| G[✅ Fulfill from Group 1]
    F -->|No| H[Try Group 2]
    H --> I[Continue to next group...]
```

## Configure a product routing rule

<Steps>
  <Step title="Access order routing settings">
    Go to **Charlie → Settings → Order routing** or **Shopify → Settings → Shipping and delivery → Order routing**.
  </Step>

  <Step title="Add the Product Rules rule">
    Find Charlie's **Product Rules** and add it to your routing strategy.
  </Step>

  <Step title="Configure the condition (When)">
    Set up which products trigger this rule:

    <Frame>
      <img src="https://mintcdn.com/charlie-6278c0d1/zIZXpEfAUH7cQkz5/images/order-routing-product-condition.png?fit=max&auto=format&n=zIZXpEfAUH7cQkz5&q=85&s=ddb2e3e512cdca997dc175fe286ea0a4" alt="Product rule condition configuration with Product is and Is one of dropdowns" width="1336" height="1130" data-path="images/order-routing-product-condition.png" />
    </Frame>

    | Field         | Options                       |
    | ------------- | ----------------------------- |
    | **Condition** | Product is                    |
    | **Operator**  | Is one of / Is not one of     |
    | **Value**     | Enter one or more product IDs |
  </Step>

  <Step title="Configure location groups (Then)">
    Create ranked groups of locations. Group 1 has highest priority, Group 2 is the fallback, and so on.

    For each group, click **Add selector** and choose how to select locations:

    | Selector type          | Description                          |
    | ---------------------- | ------------------------------------ |
    | **Specific locations** | Choose individual locations manually |
    | **Location type**      | All Warehouses or all Stores         |
    | **Location tag**       | Locations with specific tags         |

    <Tip>
      Locations that don't match any group will be ranked last, as shown in the interface: "All locations that do not match any of the groups will be ranked last."
    </Tip>
  </Step>

  <Step title="Enable the rule">
    Toggle the rule to **Enabled** when you're ready to apply it to live orders.
  </Step>
</Steps>

## Condition options

<Tabs>
  <Tab title="Is one of">
    Rule triggers when the cart contains **any** of the specified products.

    **Example:** Cart contains Product A OR Product B → Apply ranking

    **Use case:** Premium products that should prefer flagship stores.
  </Tab>

  <Tab title="Is not one of">
    Rule triggers when the cart does **not** contain the specified products.

    **Example:** Cart does NOT contain Product A → Apply ranking

    **Use case:** Route standard products away from specialty locations.
  </Tab>
</Tabs>

## Examples

### Premium products prefer flagship stores

A fashion brand wants premium items to be fulfilled from flagship stores when possible, with warehouses as backup.

<Steps>
  <Step title="Identify premium product IDs">
    Get the product IDs for your premium items from Shopify.
  </Step>

  <Step title="Create the rule">
    * **Condition:** Product is
    * **Operator:** Is one of
    * **Value:** \[Premium product IDs]
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location tag = `flagship`
    * **Group 2:** Location type = Warehouse
    * **Group 3:** Location type = Store
  </Step>
</Steps>

**Result:** Premium products prefer flagship stores first. If out of stock, warehouses are tried, then other stores. No checkout blocking.

***

### Heavy items prefer warehouse

A furniture retailer wants heavy items to ship from warehouses with freight capabilities, but allows store fulfillment as backup.

<Steps>
  <Step title="Tag your warehouses">
    Add the tag `freight-capable` to warehouses with shipping equipment.
  </Step>

  <Step title="Create the rule">
    * **Condition:** Product is
    * **Operator:** Is one of
    * **Value:** \[Heavy furniture product IDs]
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location tag = `freight-capable`
    * **Group 2:** Location type = Warehouse
    * **Group 3:** Location type = Store
  </Step>
</Steps>

**Result:** Heavy items prefer freight-capable locations, but can still be fulfilled from stores if needed.

***

### Standard products avoid specialty locations

Keep specialty locations (like those with engraving equipment) available for orders that need them.

<Steps>
  <Step title="Identify specialty products">
    Get the product IDs for items that require specialty equipment.
  </Step>

  <Step title="Create the rule">
    * **Condition:** Product is
    * **Operator:** Is not one of
    * **Value:** \[Specialty product IDs]
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location type = Warehouse
    * **Group 2:** Location tag = `standard-store`
    * **Group 3:** Location tag = `specialty`
  </Step>
</Steps>

**Result:** Standard products try warehouses and regular stores first, leaving specialty locations available for products that need them.

## Combining with constraints

For maximum control, combine routing rules with constraints:

| Rule type        | Purpose                                        |
| ---------------- | ---------------------------------------------- |
| **Constraint**   | Block locations that absolutely cannot fulfill |
| **Routing rule** | Prioritize among remaining eligible locations  |

**Example: Fragile items strategy**

1. **Fulfillment Constraint:** Exclude locations tagged `no-fragile-handling` → Small stores are **blocked**
2. **Product Routing Rule:** Prefer locations tagged `fragile-certified` → Certified locations are **preferred**, but others can still fulfill

**Result:** Fragile items never ship from incapable locations (constraint), and prefer specialized locations when available (routing).

## Best practices

<CardGroup cols={2}>
  <Card title="Use routing for optimization" icon="arrow-trend-up">
    Use routing rules when you have preferences but can accept alternatives. Reserve constraints for hard requirements.
  </Card>

  <Card title="Group products by handling needs" icon="layer-group">
    Instead of listing individual products, consider using collections in your constraint rules and product tags for common patterns.
  </Card>

  <Card title="Combine with other rules" icon="diagram-project">
    Product rules work well with Inventory Rules (prefer locations with more stock of the specific product).
  </Card>

  <Card title="Test before peak seasons" icon="calendar">
    Verify your routing with test orders before high-volume periods.
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Products not routing to expected locations">
    **Check:**

    1. Is the rule **enabled**?
    2. Are the product IDs correct? (Check in Shopify Admin → Products)
    3. Does the preferred location have stock?
    4. Are there constraint rules blocking the location?
    5. Is another routing rule with higher priority overriding this one?
  </Accordion>

  <Accordion title="Rule not triggering at all">
    **Check:**

    1. Is the operator correct? ("Is one of" vs "Is not one of")
    2. Are the product IDs in the correct format?
    3. Is the rule placed correctly in the routing order?
  </Accordion>

  <Accordion title="Wrong group being selected">
    Remember: Shopify tries groups in order and uses the first one with available stock. If Group 1 is out of stock, it moves to Group 2 automatically.

    Verify stock levels at each location for the products in question.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Product Constraints" icon="ban" href="/constraints/product-rules">
    Block locations based on products (hard rules)
  </Card>

  <Card title="Ranked Location Groups" icon="layer-group" href="/order-routing/ranked-location-groups">
    Create default location priorities
  </Card>

  <Card title="Inventory Rules" icon="warehouse" href="/order-routing/inventory-rules">
    Prioritize by stock availability
  </Card>

  <Card title="Location Tags" icon="tags" href="/locations/tags">
    Set up tags for flexible grouping
  </Card>
</CardGroup>
