Cross-domain and cross-subdomain tracking
Keep one visitor identity when traffic moves between domains, automatic for subdomains, one config line for different root domains. Works for the script tag and the SDK.
On this page
When a visitor moves from one site to another (marketing to app), you want SourceLoop to treat them as one person, not two strangers. How you do that depends on whether you are crossing subdomains or different root domains.
First, which case are you in?
| Going from → to | Example | What you need |
|---|---|---|
| Subdomain → subdomain (same root domain) | www.yoursite.com → app.yoursite.com | Nothing. Automatic. |
| Domain → different root domain | yourbrand.com → yourapp.io | One config line (and SourceLoop on both sites). |
The reason: SourceLoop stores the visitor id (_sl_aid) in a cookie on your root domain (e.g. .yoursite.com). Cookies are shared across subdomains, so www. and app. already see the same id. They are not shared across different root domains, so those need an explicit hand-off.
Requirement for any cross-site setup: SourceLoop must be installed on both sites using the same
websiteId. If the two sites have different website ids, they can never be the same visitor.
Case 1, subdomains (automatic, nothing to do)
www.yoursite.com and app.yoursite.com (or marketing., dashboard., etc.) share identity automatically as long as both have the SourceLoop script/SDK with the same websiteId. No crossDomains, no special links. This is the common SaaS setup and it just works.
Verify: load www.yoursite.com, note the _sl_aid cookie value (DevTools, Application, Cookies), then go to app.yoursite.com, the _sl_aid value is the same.
Case 2, different root domains
Example: marketing site on yourbrand.com (Webflow), app on yourapp.io (Next.js). Because the cookie cannot cross root domains, SourceLoop passes the id in the URL when the visitor clicks through, and the destination adopts it on arrival.
You configure a list of other domains you own (crossDomains). When a visitor clicks a link from your site to one of those domains, SourceLoop appends identity params (?sl_id=...&sl_sid=...&sl_ts=...) to the link. The destination site (also running SourceLoop with the same websiteId) reads those params on load, adopts the same visitor id, and strips the params from the URL.
2a. Script tag (Webflow, WordPress, no-code)
Add crossDomains to the config on both sites, listing the other domain. Replace YOUR_WEBSITE_ID with the same id on both.
On yourbrand.com (marketing):
<script>
window.SourceLoopConfig = {
websiteId: 'YOUR_WEBSITE_ID',
crossDomains: ['yourapp.io'], // the app domain you link to
};
</script>
<script async src="https://app.sourceloop.ai/tracking-v3.js"></script>
On yourapp.io (app):
<script>
window.SourceLoopConfig = {
websiteId: 'YOUR_WEBSITE_ID',
crossDomains: ['yourbrand.com'], // link back to marketing
};
</script>
<script async src="https://app.sourceloop.ai/tracking-v3.js"></script>
That is it. Now when someone clicks a normal link on yourbrand.com that points to yourapp.io (e.g. your “Start free trial” button), SourceLoop automatically appends the identity params, and yourapp.io adopts them. You do not change your links, this happens on click.
You can list multiple domains: crossDomains: ['yourapp.io', 'docs.yourbrand.io', 'community.yourbrand.com'].
2b. Coded app / SDK
With the SDK, link-click decoration also works, configure crossDomains when bundling the tracker (via the same SourceLoopConfig or your init). In addition, the SDK gives you two helpers for cases the click-listener cannot catch, programmatic navigation (JS redirects, window.location, or <form action> to another domain):
import { getTrackingParams, buildCrossDomainUrl } from '@sourceloop-analytics/sdk';
// Easiest: build a ready-to-use URL with the params appended.
window.location.href = buildCrossDomainUrl('https://yourapp.io/signup');
// → https://yourapp.io/signup?sl_id=...&sl_sid=...&sl_ts=...
// Or get the raw params to attach yourself (e.g. as hidden form fields):
const params = getTrackingParams();
// → { sl_id: '...', sl_sid: '...', sl_ts: '...' }
The destination (yourapp.io) must be running SourceLoop with the same websiteId; it adopts the params automatically on page load, no code needed there.
How the hand-off works (so you can reason about it)
- Visitor on
yourbrand.comclicks a link toyourapp.io(a configured cross-domain). - SourceLoop appends
?sl_id=<visitorId>&sl_sid=<sessionId>&sl_ts=<timestamp>to the destination URL. - On
yourapp.io, SourceLoop reads those params before computing identity, adopts the samesl_idas the visitor id, and removes the params from the address bar. - Both domains now report the same visitor, so the marketing source carries through to the app.
Built-in safety: the timestamp (sl_ts) must be within about 5 minutes, so stale/shared links cannot hijack an identity, and only valid id formats are accepted.
Common mistakes
- Different
websiteIdon the two sites. They can never merge. Use the same id everywhere. crossDomainson only one site. Put it on both, and make sure the destination has SourceLoop installed so it can adopt the params.- Expecting subdomains to need
crossDomains. They do not. Only different root domains do. AddingcrossDomainsfor subdomains is unnecessary (harmless, but not needed). - Programmatic redirects without
buildCrossDomainUrl. The automatic decoration only fires on real<a>clicks. Forwindow.location = ...,router.pushto another domain, or form posts, usebuildCrossDomainUrl()/getTrackingParams(). - Listing a domain you do not control.
crossDomainsshould only be your own properties; the destination must run SourceLoop to adopt the id.
Verify
- On
yourbrand.com, note the_sl_aidcookie value. - Click your link to
yourapp.io. The destination URL should briefly contain?sl_id=...(then SourceLoop cleans it). - On
yourapp.io, check the_sl_aidcookie, it should now match the value fromyourbrand.com. - In the SourceLoop dashboard, the journey shows as a single visitor spanning both domains, with the marketing source preserved.
Frequently asked questions
-
Do subdomains need any cross-domain setup?
No. www.yoursite.com and app.yoursite.com share identity automatically as long as both run SourceLoop with the same websiteId. The visitor id cookie (_sl_aid) is stored on your root domain, and cookies are shared across subdomains, so nothing extra is needed. Adding crossDomains for subdomains is unnecessary (harmless, but not needed).
-
How do I keep one identity across two different root domains?
Install SourceLoop on both sites with the same websiteId, then add a crossDomains list to the config on each site naming the other domain. When a visitor clicks a link from one site to the other, SourceLoop appends identity params to the URL and the destination adopts them on load. Put crossDomains on both sites, not just one.
-
My redirect is a JS redirect or a form post, not a normal link. Does decoration still work?
The automatic decoration only fires on real anchor clicks. For programmatic navigation (window.location, router.push to another domain, or a form action to another domain), use buildCrossDomainUrl(url) to get a ready URL with the params appended, or getTrackingParams() to attach them yourself as hidden fields.
-
Can a shared or stale link hijack someone's identity?
No. The handoff includes a timestamp (sl_ts) that must be within about 5 minutes, and only valid id formats are accepted, so stale or shared links cannot adopt an identity.