Routing rules and A/B testing
Author per-link routing, run A/B experiments with full lifecycle control, and set up deep links.
What routing rules do
By default, every short link sends all visitors to a single destination. Routing rules let you break that one-to-one relationship. With routing rules, you can:
- Send visitors to different destinations based on where they are, what device they're using, or what time it is.
- Run A/B experiments that split traffic across multiple destinations and track engagement by variant.
- Route mobile visitors directly into your native iOS or Android app via deep links.
Prerequisites
- An active workspace with routing rules enabled (plan-gated).
- For deep links: a verified, ready, account-exclusive custom branded domain.
How the redirect decision works
Every click on a short link triggers Nimriz's evaluation chain. Routing rules are only reached after earlier checks pass:
| Priority | Check | What happens if triggered |
|---|---|---|
| 1 | Reserved paths (/_health, /.well-known/*, /api/*) | Handled as system paths, never reach routing. |
| 2 | Domain readiness | Unready domains serve a fallback; routing does not run. |
| 3 | Pending account deletion | Not-found landing; routing does not run. |
| 4 | Missing slug | Not-found fallback; routing does not run. |
| 5 | Link expired | Expired landing; routing does not run. |
| 6 | Password gate | Password prompt; routing does not run until unlocked. |
| 7 | Link disabled or flagged | Fallback behavior; routing does not run. |
| 8 | Routing rule evaluation | First matching enabled rule wins. |
| 9 | Deep link action resolution | Applied to the winner or default destination. |
| 10 | Query forwarding / merge | Applied after final destination is chosen. |
| 11 | Click analytics | Recorded before the final redirect response. |
| 12 | Redirect response | Visitor reaches the destination. |
Routing conditions
Each rule can match visitors based on any combination of these conditions. All conditions on a rule must match simultaneously (AND logic).
| Condition | Values | Notes |
|---|---|---|
| Country | ISO 2-letter code (US, DE, GB, etc.) | One or more countries. |
| Device OS | ios, android, windows, macos, linux | Use the Nimriz-normalized taxonomy. |
| Device type | mobile, tablet, desktop | Derived from User-Agent. |
| Time window | A date/time range | Evaluated in UTC. |
A rule with no conditions is a catch-all-it matches every visitor. Catch-all rules belong at the bottom of your list.
Rule evaluation order
Rules are evaluated in strict top-to-bottom order. The first enabled rule that matches wins. Subsequent rules are not evaluated.
This means:
- Put your most specific rules (e.g., Country=US AND DeviceOS=ios) near the top.
- Put broader rules (e.g., Country=US) below more specific ones.
- A catch-all rule at the top intercepts all traffic before any specific rules below it.
Use the routing simulator to verify order before publishing.
Setting up routing rules
- Open the link's detail page.
- Navigate to the Routing tab.
- Click Add rule.
- Set conditions (or leave empty for a catch-all).
- Set the destination URL for this rule.
- Click Save rule.
- Repeat for additional rules.
- Drag to reorder rules. Order matters-the first matching rule wins.
- Save the full ruleset.
A/B testing with Experiments
Experiments let you split traffic across multiple destination variants and compare performance.
Step-by-step: setting up an A/B experiment
- On the link's Routing tab, click Add experiment.
- Give the experiment a name (for your reference).
- Add variants:
- Each variant has a destination URL and a traffic weight (percentage).
- Weights must total 100%.
- Example: Variant A (50%,
https://example.com/v1), Variant B (50%,https://example.com/v2).
- Optionally add targeting conditions (same condition types as regular routes). This limits the experiment to visitors matching those conditions.
- Optionally set a schedule: a start date/time and/or an end date/time (both in UTC).
- Click Save.
- Click Launch when you are ready for traffic to flow. The experiment starts splitting traffic immediately.
Experiment lifecycle
Experiments move through explicit states. Understanding the states helps you manage experiments correctly.
| State | What it means | How to get here |
|---|---|---|
| Draft | Created but not yet live. Traffic is not split. | Default after creation. |
| Scheduled | Will automatically start at the configured starts_at time. | After launch with a future start date. |
| Running | Live. Traffic is being split across variants. | After launching or at the scheduled start time. |
| Paused | Stopped temporarily. Traffic is not split; visitors reach the first enabled non-experiment rule or default destination. | Manual pause action. Historical data preserved. |
| Completed | Stopped manually or at the scheduled ends_at time. No longer active. | Manual stop, or automatic at ends_at. |
| Promoted | A winning variant was chosen. A permanent route was created. The experiment is now read-only history. | After promoting a winner. |
State transition rules:
Draft → RunningorScheduled: via Launch.Running → Paused: via Pause. Can be resumed.Paused → Running: via Resume. If the experiment definition has changed materially, resuming starts a fresh run.Running → Completed: via Stop or automatic atends_at.Completed → Promoted: via Promote (choose a winning variant).
Sticky variant assignment
Once a visitor is assigned to a variant, they always see the same variant on subsequent visits. This stickiness ensures consistent user experience during the experiment.
Stickiness is cookie-backed and per browser/device:
- A visitor on their laptop always sees Variant A (if assigned to A).
- The same visitor on their phone starts fresh and may be assigned to a different variant.
- Clearing cookies resets the assignment.
Scheduling experiments
You can pre-schedule an experiment to start and end automatically:
starts_at: The experiment enters Scheduled state after Launch and automatically transitions to Running at this time.ends_at: The experiment automatically moves to Completed at this time.
Scheduling is optional. You can also start and stop manually.
Promoting a winner
After your experiment has run and you are satisfied with the results:
- Click Promote on the experiment panel.
- Select the winning variant.
- Confirm.
What happens when you promote:
- Nimriz creates a new permanent route using the winning variant's destination URL. This route immediately takes effect for all future visitors.
- The experiment moves to Promoted state and becomes read-only. Historical data is preserved.
- You can edit the promoted route later (it is now a regular route, not an experiment).
Important: Nimriz does not automatically select a winner or calculate statistical significance. All promotion decisions are manual.
Analytics by variant
When an A/B experiment is running, click analytics are attributed to stable variant keys-internal identifiers that never change, even if you rename the variant's display label.
In the link's analytics:
- Clicks are broken down by variant key.
- The current variant label is shown next to each key where known.
- If you renamed a variant, historical clicks are still attributed to the original key-not the new name.
- If you promoted a winner, historical experiment clicks remain under their original keys. The new permanent route's clicks appear separately.
Deep links
Deep links route mobile visitors directly into your native iOS or Android app, bypassing the browser.
Eligibility requirements
| Requirement | Why |
|---|---|
| Custom branded domain | App association files must uniquely represent one brand. |
| Domain is account-exclusive | Shared domains cannot serve app association files for multiple brands. |
| Domain is verified and Ready | App association files are served from the live domain. |
| Full app metadata configured | iOS bundle ID + Team ID, and/or Android package name + SHA-256 fingerprint, in domain settings. |
Deep link fallback sequence
Nimriz uses a deterministic three-step sequence for every deep-link action:
- App target-attempt to open the configured mobile app.
- Store fallback-if configured and the app is not installed, go to the App Store (iOS) or Google Play (Android).
- Web fallback-if no app or store target applies, go to the configured web URL.
Setting up deep links
- Ensure your custom domain meets all eligibility requirements.
- Configure your domain's deep-link settings (in domain settings → Mobile app):
- For iOS: App Bundle ID and Apple Team ID.
- For Android: Package name and SHA-256 signing key fingerprint.
- Wait for the domain's deep-link readiness indicator to show Ready.
- On a link's Routing tab, add a rule with a deep-link action and configure the app target, store fallback, and web fallback URLs.
Routing preview (simulator)
The routing simulator lets you test your configured rules without generating real traffic.
How to use it
- Open the link's Routing tab.
- Click Preview or Simulate.
- Set the simulation inputs:
- Country (ISO 2-letter code)
- Device OS
- Device type
- UTC timestamp (for time-window rules)
- Run the preview.
The simulator evaluates your current draft rules exactly as they would run in production and shows:
- Which rule matched (or "default destination" if no rule matched).
- The winning destination URL.
- The match reason.
What the preview cannot simulate
- App installation-the simulator shows which deep-link target Nimriz would choose, but cannot confirm whether the visitor's device has the app installed.
- Sticky A/B assignment-the simulator uses a first-visit posture. It does not replay historical cookie-based sticky assignments.
Troubleshooting
Traffic is reaching the wrong destination
- Check rule order-open the routing panel and review the ordered list. A broad catch-all rule above specific rules intercepts all traffic before the specific rules fire. Reorder so specific rules are above broad ones.
- Check that rules are enabled-disabled rules are stored but skipped. Verify the rule you want active is not greyed out.
- Use the simulator-simulate the visitor's exact context (country, OS, device type) to see which rule Nimriz applies.
A/B experiment is not splitting traffic
- Confirm the experiment is in Running state (not Draft or Scheduled).
- If you test from the same browser, you will consistently see the same variant due to sticky assignment. Test from a different browser or use a private window to simulate a fresh visitor.
Deep links are not opening the app
- Check the domain readiness indicator-it must show Ready, not Ineligible or Unconfigured.
- Verify the app is configured to handle Universal Links (iOS) or App Links (Android) for your domain-this is an in-app developer configuration outside Nimriz.
- Test on a real device. Emulators and browser-based testing cannot simulate deep link behavior accurately.
- Visit
https://yourdomain.com/apple-app-site-associationandhttps://yourdomain.com/.well-known/assetlinks.json-these must return valid JSON, not 404.