Targeting rules
Read time: 5 minutes. Who it's for: Merchants narrowing who sees the quote button and who can submit a quote.
QuotWay separates product-side targeting ("which products show the quote button?") from customer-side targeting ("which buyers can submit?"). Both run as a chain of rules - each rule either allows or denies; the first matching rule wins.
The two scopes
| Scope | Asks | Default if no rule |
|---|---|---|
| PRODUCTS | "Should the quote button show on this product?" | Deny - button hidden. |
| CUSTOMERS | "Should this buyer be allowed to submit?" | Deny - submission rejected. |
The default is "deny-all" on purpose. If you have no rules, no buyer sees the button. Onboarding creates a baseline ALL_PRODUCTS + ALL_CUSTOMERS rule for you so you start out with the button visible to everyone.
Rule types
Product-side
- ALL_PRODUCTS - every product shows the button.
- COLLECTION - show only on products in a specific collection.
- PRODUCT_TAG - show only on products with a specific tag (e.g.,
wholesale). Supports ANY (match any tag) or ALL (match all tags). - PRODUCT_TYPE - match by Shopify product type.
- VENDOR - match by Shopify product vendor.
Customer-side
- ALL_CUSTOMERS - every buyer can submit.
- CUSTOMER_TAG - match by Shopify customer tag (e.g.,
vip). ANY or ALL. - B2B_COMPANY - on B2B-capable stores (Enterprise plan). Match by company GID.
- COMPANY_LOCATION - on B2B-capable stores (Enterprise plan). Match by company location.
- GUEST - explicitly allow guest (logged-out) buyers.
Rule order + priority
Each rule has a priority (lower = higher priority). When QuotWay evaluates whether to show the button:
- Sort rules by
priorityascending. - Walk the list. The first rule whose conditions match the product + buyer wins.
- If no rule matches → deny.
Rules can be enabled (active) or disabled (preserved for later but ignored). The Targeting editor at /app/quote-button/targeting has toggles for both states.
Editing rules
The dedicated editor at /app/quote-button/targeting shows all rules across both scopes. Each row has:
- Name + scope badge (PRODUCTS / CUSTOMERS).
- Rule type.
- Conditions (e.g.,
tags: ["wholesale"], operator: ANY). - Enabled toggle.
- Priority.
Click any rule to open the condition editor.
Worked example - Wholesale-tagged products, B2B-tagged customers
Say you sell to wholesalers via specially-tagged products + you have a wholesale-customer tag on your trusted buyer customer accounts. You want the quote button to appear ONLY when both match.
Rules:
| # | Scope | Type | Conditions | Priority | Enabled |
|---|---|---|---|---|---|
| 1 | PRODUCTS | PRODUCT_TAG | tags: ["wholesale"], operator: ANY |
100 | ✓ |
| 2 | CUSTOMERS | CUSTOMER_TAG | tags: ["wholesale-customer"], operator: ANY |
100 | ✓ |
That's it. Two rules. The button shows when the product has the wholesale tag AND the buyer has the wholesale-customer tag.
Worked example - Guest buyers + tagged products
If you want even logged-out buyers to be able to submit quotes (common for first-touch B2B inquiries):
| # | Scope | Type | Conditions | Priority | Enabled |
|---|---|---|---|---|---|
| 1 | PRODUCTS | PRODUCT_TAG | tags: ["wholesale"], operator: ANY |
100 | ✓ |
| 2 | CUSTOMERS | GUEST | (none) | 100 | ✓ |
| 3 | CUSTOMERS | ALL_CUSTOMERS | (none) | 200 | ✓ |
Rule 2 explicitly allows guests; rule 3 catches logged-in customers.
Performance + caching
Targeting rules are read on every storefront page load. To keep latency low, QuotWay caches the rule list per shop for 5 minutes.
- When you create / update / delete a rule, the cache invalidates immediately on that shop.
- The cache is in-memory per Vercel function instance, so traffic scales linearly without per-shop database hits.
You should NOT see stale rules in normal use. If you do, the debugging procedure is at Troubleshooting common issues.
Common gotchas
- Button doesn't show even though my product has the tag. Tag matching is case-sensitive ("wholesale" ≠ "Wholesale"). The Shopify catalog sometimes inconsistent casing on legacy tags - pick one casing and stick with it.
- PRODUCT_TAG rule with
operator: ALLand 2 tags - works on some products but not others. Verify that each product actually has BOTH tags. The operator must be exact-match-all. - B2B company rule doesn't match. Use the company GID (
gid://shopify/Company/12345), not the company name. The editor's autocomplete prevents this, but if you paste a name from elsewhere, the rule silently fails to match. - Rules from a deleted plan tier still show. Disabling a rule preserves it. Use the Delete action to remove it.
Related articles
- Approval workflows - what happens AFTER a quote gets submitted.
- Partial acceptance and split conversion - how acceptance interacts with conversion.
Still need a hand? The team is happy to help.