-
Notifications
You must be signed in to change notification settings - Fork 0
TrackingControl
Two independent switches control whether the SDK sends outbound tracking events: a global config switch and a per-call override. Use them to honor consent without losing your experiment logic — bucketing, rule evaluation, and sticky persistence keep working regardless of the tracking state. Only the outbound network enqueue is silenced.
Set tracking: false at ConvertSdk.create to disable all outbound event tracking for the client:
CONVERT_SDK = ConvertSdk.create(
sdk_key: ENV.fetch("CONVERT_SDK_KEY"),
tracking: false # default is true
)When tracking is false:
-
Decisioning still runs.
run_experience/run_featuresetc. still bucket the visitor and return real results. - Sticky StoreData still persists. Variation assignments and visitor properties are still written to the store.
-
The outbound event enqueue is suppressed. No
bucketingevent is enqueued for delivery, and adebugline records each suppression (tracking disabled, event suppressed).
track_conversion checks the global switch before the dedup-and-mark step. So when tracking is false a conversion is neither enqueued nor marked as deduplicated — meaning a subsequent same-goal call stays unblocked once tracking is re-enabled. The return value is unchanged (self); no sentinel:
context.track_conversion("purchase")
# tracking: false -> nothing enqueued, goal NOT marked, debug line emitted, returns selfSuppress the event for a single decision call by putting enable_tracking: false in the per-call attributes hash (symbol or string key both work — the public boundary accepts both):
variation = context.run_experience("homepage-test", { enable_tracking: false })
context.run_experiences({ enable_tracking: false })When enable_tracking: false, bucketing, sticky persistence, audience rules, and the internal bucketing lifecycle event still fire — only the outbound enqueue is skipped (a debug line records the suppression: tracking suppressed for call). Absent or any non-false value leaves tracking on; only an explicit false suppresses.
Neither tracking switch touches the
bucketinglifecycle event — it is decisioning observability, not tracking, so a host listener can react to the decision even under consent denial. Only the outbound enqueue is gated by the tracking switches. (An active preview is the one thing that does silence the lifecycle event — see below.)
The verdict for whether an event is enqueued is the composition of both switches. The global switch is dominant: a global tracking: false suppresses delivery regardless of a per-call enable_tracking: true.
Global tracking
|
Per-call enable_tracking
|
Event enqueued? |
|---|---|---|
true |
true (default) |
Yes |
true |
false |
No |
false |
true |
No (global-off wins) |
false |
false |
No |
Context#set_preview is not a consent switch, but it is the strongest suppression in the SDK, so it belongs in the same mental model. While a preview is active on a context, that context records nothing — and unlike the tracking switches, this covers persistence and the lifecycle events too:
| Surface | Under a tracking switch (global tracking: false or per-call enable_tracking: false) |
Under an active preview |
|---|---|---|
| Decisioning (bucketing, rules, features, segment matching) | Runs | Runs — only the previewed experience is forced |
| Sticky StoreData write | Persists | Skipped |
bucketing lifecycle event |
Fires | Does not fire |
| Outbound event enqueue | Suppressed | Suppressed |
track_conversion |
The global switch suppresses the whole call before the dedup mark, so no conversion event fires either; there is no per-call switch on this method |
Full no-op — nothing enqueued, no conversion event, no dedup mark |
update_visitor_properties |
Persists | In-memory merge only, store write skipped |
set_default_segments / run_custom_segments
|
Persists | Matching runs, store write skipped |
This applies to every experience and feature evaluated on that context, not only the previewed one — so a page under preview still renders coherently while recording nothing. Preview state is per-Context: another context on the same client tracks normally.
See Code Examples for the wiring and QA & Preview for the preview-link workflow.
| Scenario | What to do |
|---|---|
| Consent denied for the whole client |
ConvertSdk.create(..., tracking: false). Decisions and stickiness still work; nothing is delivered. |
| Consent denied for a specific call only | Keep the global tracking: true and pass enable_tracking: false on the calls you want silent. |
| Diagnosing "events vanish" | Confirm tracking is not disabled — a tracking disabled, event suppressed / tracking suppressed for call debug line is the signal. See the missing-events decision tree. |
-
Configuration Options — the
trackingconfig option -
Code Examples — per-call suppression and
set_previewin context - QA & Preview — the preview-link and debug-token workflow
- Tracking Conversions — the shared conversion concept doc
Copyrights © 2026 All Rights Reserved by Convert Insights, Inc.
Getting Started
Ruby SDK
- Quickstart
- Installation
- Initialization
- Configuration
- Return Types & Sentinels
- Code Examples
- Fork Safety & Runtime Recipes
- Tracking Control
Core Concepts
- Experiences & Variations
- Feature Flags
- Bucketing Algorithm
- Rule Evaluation
- Segments
- Data Management
- Event System
- API Communication
How-To Guides
- Running Experiences
- Running Features
- Tracking Conversions
- Visitor Context
- Persistent DataStore
- Troubleshooting
- Direct Tracking Endpoint
- Server-Side Experimentation
- From Tracking Script to SDK
- QA & Preview
- Mutually Exclusive Experiments
- Split URL Tests
Contributing