How conversion tracking works
Rebrandly's conversion tracking uses a click-based, last-touch attribution model. When a visitor clicks a branded link, the SDK captures a unique click identifier from the destination URL and stores it locally. Every subsequent rbly.convert() or rbly.track() call reads that stored identifier and includes it in the event payload, attributing the event to the original click.
rbly.convert() records actions you want to measure as conversions — purchases, signups, form submissions. These appear in Event Breakdown and Path Analysis reports and can include revenue data.
rbly.track() records custom behavioral events that aren't conversions — clicks, interactions, engagement signals. These are tracked separately from conversion data.
How click attribution works
When a visitor clicks a Rebrandly branded link, the redirect appends rbly_click_id as a query parameter to the destination URL. On page load, the SDK reads rbly_click_id from the URL and writes its value to localStorage under the key rbly_click_id. That stored value is then sent automatically with every rbly.convert() or rbly.track() call.
UTM parameters are stored separately under rbly_utm_params and merged into event properties on each rbly.convert() or rbly.track() call. Parameters captured via data-custom-utm-params are included in this merge. See Script configuration for how to configure which UTM parameters the SDK captures.
All localStorage reads and writes are wrapped in try/catch. If an operation fails, the SDK logs a warning to the console and returns null or false silently — it does not throw. If localStorage is unavailable, rbly_click_id is never persisted and both methods short-circuit with { success: false, error: 'no_click_id' }. There is no fallback mechanism.
Multi-click journeys
Last click wins. If a visitor clicks more than one Rebrandly branded link before converting, each page load checks for rbly_click_id in the URL. When the incoming value differs from the stored value, the SDK overwrites it. The conversion is attributed to whichever branded link the visitor clicked most recently.
Edge cases
| Scenario | What happens |
|---|---|
localStorage blocked (Safari ITP, Firefox strict tracking protection, incognito mode) | rbly_click_id is never persisted. Both methods return { success: false, error: 'no_click_id' }. No conversion is recorded and there is no fallback. |
Ad blocker strips rbly_click_id from the URL | The query parameter never reaches the SDK. The SDK initializes with no click ID and both methods return { success: false, error: 'no_click_id' }. No conversion is recorded. |
| Cross-domain conversion flow | localStorage is scoped to an origin. If the branded link lands on one domain and the conversion fires on a different domain, the stored rbly_click_id is not available on the second domain. The conversion will not be recorded. |
| Conversion fires after the attribution window expires | The attribution window is configurable in Settings > Conversion tracking > Configure tracking and defaults to 30 days. Events received after the window expires are not recorded as conversions. |
Silent failuresThe
localStorage-blocked and ad-blocker scenarios fail silently from the visitor's perspective — no error is surfaced in the UI. Both result in{ success: false, error: 'no_click_id' }from either method. If you are checking the return value, this is the signal that attribution was not possible. See Custom events for response handling.
Privacy
Conversion tracking uses localStorage, which is origin-scoped. No cross-site tracking occurs and no third-party cookies are set. The SDK makes no calls to third-party domains at runtime — all requests go to the configured apiBase.
Click metadata is enriched at redirect time on Rebrandly's infrastructure. The rbly_click_id written to localStorage contains no personally identifiable information.
Next steps
- Quickstart — Install the SDK and fire your first event
- Script configuration — Configure UTM capture, deduplication, and SPA behavior
- Custom events —
rbly.convert()andrbly.track()parameters, response shapes, and examples
Updated 4 days ago
