Moving Merchandising Logic Into Algolia Query Rules: A Practical Pattern
Move merchandising logic (pinning, banners, redirects) into Algolia Query Rules so marketing can iterate via dashboard while engineers keep version control. Worked seasonal-banner example, AI re-ranking composition, and six practical limits included.
24 Feb 2026, 12:42 UTC

The Problem: Merchandising Changes Require Code Deploys
Most search implementations start with hardcoded merchandising: pinning a product for "black friday" queries, redirecting "support" to a help page, boosting high-margin items in the "electronics" category. Every time marketing wants a new banner, a redirect, or a seasonal boost, a developer has to modify application code, run tests, and deploy. The feedback loop stretches from minutes to days.
Takeaway: Algolia Query Rules let you express that same logic — pinning, boosting, redirects, facet filters, custom userData — inside the search engine itself. Marketing can iterate via the dashboard or API without a code deploy, while engineers retain version control and CI/CD gates.
What Query Rules Actually Do
A Query Rule is an if-this-then-that evaluated at query time. The condition matches on query text, ruleContexts (arbitrary strings you send with the search request), or filter state. The consequence can:
- Promote/hide specific objectIDs (pinning)
- Replace the query string (synonyms on steroids)
- Inject filter/facet constraints (e.g., force
brand:Applewhen query matches "iphone") - Return a custom
userDataobject (any JSON your front-end understands) - Redirect (return a URL in
userDatafor the client to navigate)
Rules execute in priority order (lower number = higher priority). The first matching rule wins unless its stopProcessing is false, allowing layered logic: a global redirect rule at priority 1, then category-specific pinning at priority 10, then a catch-all boost at priority 100.
Each index supports up to 10,000 rules. Beyond that, you split logic across replica indices or consolidate patterns using the condition's pattern field (anchored, contains, or regex-like matching on query words).
Worked Example: Seasonal Banner Without a Separate CMS Call
Scenario: Marketing wants a promotional banner on any search containing "sale", "black friday", or "cyber monday". They want to swap creative assets weekly without engineering involvement.
Step 1: Define the Rule in the Dashboard (or API)
{
"objectID": "seasonal-banner-2024-q4",
"condition": {
"pattern": "sale",
"anchoring": "contains"
},
"consequence": {
"userData": {
"banner": {
"id": "bf-hero-2024",
"imageUrl": "https://cdn.example.com/banners/black-friday-hero.jpg",
"ctaText": "Shop Black Friday Deals",
"ctaLink": "/collections/black-friday"
}
},
"stopProcessing": false
}
}
Add two more rules with pattern "black friday" and "cyber monday" pointing to the same userData structure (or different ones per campaign). Set stopProcessing: false so downstream rules (pinning, boosting) still apply.
Step 2: Front-End Renders hit.__userData (or results.userData)
In an InstantSearch implementation, the hits widget receives results.userData when any rule matches. A minimal React snippet:
import { useInstantSearch } from 'react-instantsearch-hooks-web';
function SeasonalBanner() {
const { results } = useInstantSearch();
const banner = results?.userData?.[0]?.banner; // first matching rule's userData
if (!banner) return null;
return (
{banner.ctaText}
);
}
Marketing updates the imageUrl, ctaText, or ctaLink in the Algolia dashboard. No front-end deploy. The rule triggers on the next search request.
How Rules Compose: Priority, StopProcessing, and AI Re-Ranking
Rules apply before Dynamic Re-Ranking (Algolia's AI personalization layer). This matters: if you pin a product at position 1 via a Rule, the AI re-ranks the remaining results. Your merchandising override stays intact while personalization optimizes the long tail.
Layering pattern that works in practice:
- Priority 1-10: Global redirects ("support" → help center URL via
userData.redirect) - Priority 20-50: Category/seasonal pinning ("sale" → pin top 3 clearance SKUs)
- Priority 100+: Contextual boosts ("ruleContexts": ["vip"] → boost
tier:premiumproducts)
Set stopProcessing: false on all but the redirect rule. The redirect should have stopProcessing: true so the search terminates early and the client navigates.
Limits You'll Hit (and How to Plan Around Them)
1. Hidden Business Logic Becomes Hard to Debug
Rules are "hidden" from application code. A developer searching for why "iphone" results only show Apple products won't find brand:Apple in the repo — it's injected by a Rule. Mitigation: export rules to version control via algolia rules browse <index> > rules.json in CI, and require PR reviews for rule changes.
2. Dashboard Simulation Doesn't Replicate A/B Tests or Personalization
The Test Rules simulator uses the current index state. It won't show how a rule behaves inside an A/B test variant or under a specific user's Dynamic Re-Ranking profile. Verify in production with Analytics > Query Rules (trigger counts, CTR on pinned items, conversion impact over 7-14 days).
3. Pinning Too Many Results Degrades Relevance
Pinning >20 results per query inflates response size and pushes organic matches off the first page. Monitor processingTime and hitsPerPage in the dashboard; keep pinned sets small (3-5) and specific.
4. Injected Filters Bypass User Facet Selections
A Rule that injects brand:Apple overrides the user's facet checkbox for "Samsung". The UI still shows "Samsung" as selected, but results are Apple-only. Communicate this in the UI (e.g., a banner: "Showing Apple results for 'iphone'") or avoid filter injection for user-facing facet fields.
5. No Native Geolocation Conditions
Rules can't match on user location. Use aroundLatLng or insideBoundingBox search parameters instead, or send a ruleContext like "region:us-west" from your application layer.
6. Bulk API Updates Replace the Entire Rule Set Atomically
There's no partial update endpoint. Your deployment script must fetch current rules, modify the array, and re-send the full payload. Make it idempotent: generate the desired rule set from a declarative source (YAML/JSON in repo) and push the whole thing each deploy.
Actionable Next Steps
- Create a test index in your Algolia dashboard. Add 3-4 rules: a pin, a redirect, a filter injection, and a
userDatabanner. Use the Test Rules simulator with queries that match and don't match. - Export to version control:
algolia rules browse your_index > rules.json. Validate the JSON schema against the official documentation. - Build a minimal InstantSearch demo with a
configurewidget sendingruleContextsand ahitswidget renderinghit.__userData. Confirm the banner appears only on matching queries. - Load-test: send 100 QPS with mixed rule-matching and non-matching queries using the Algolia search client. Verify p99 latency increase stays under 5 ms vs. baseline.
- Enable Analytics > Query Rules on your production index. Let it run 7-14 days, then review trigger rates and conversion lift before expanding.
Query Rules aren't a replacement for all application logic — keep loops, external API calls, and transactional guarantees in your code. But for the merchandising layer that changes weekly, they move the iteration speed from "deploy cycle" to "dashboard save."
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.