Version:

Server-side cookies in JavaScript SDK

Use server-side cookies for effective tracking, session management, and personalized user experiences.

As the user privacy measures evolve, modern web browsers, particularly Safari, have introduced Intelligent Tracking Prevention (ITP) to limit user tracking through cookies. This poses serious challenges for businesses relying on cookies for authentication, personalization, and analytics.

To address these limitations, the JavaScript SDK offers a server-side cookie management solution to ensure data tracking without compromising the user privacy. This approach allows you to set RudderStack’s cookies on the server, providing full control over attributes like expiration and extending cookie lifespans unaffected by ITP’s restrictions.

What is ITP?

Intelligent Tracking Prevention (ITP) is a privacy feature introduced in Safari in 2017 to prevent advertisers from tracking users across websites. It restricts third-party cookies and may significantly shorten the lifespan of first-party cookies if they appear to be used for cross-site tracking.

ITP also affects how developers can use cookies for:

  • User authentication
  • Content personalization
  • Analytics and cross-site tracking
  • Session management and user experience continuity

The JavaScript SDK traditionally uses client-side cookies. With the introduction of ITP, it also implements server-side cookies to achieve:

  • Extended lifespan than the client-managed cookies.
  • Consistent and uniform experience across all the browsers.

Enable server-side cookies

Set the useServerSideCookies configuration option to true while loading the JavaScript SDK, as shown:

rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  useServerSideCookies: true // Default is false
});

Once enabled, the SDK makes network requests to the website’s server to set cookies via the response headers.

To ensure that the cookies are set successfully, you must make the request only to the website’s domain (or parent domain) server. RudderStack supports the following use cases:

WebsiteServerCookies
Parent domain websiteParent domain serverCookies are created for the parent domain.
Sub-domain websiteSub-domain serverCookies are created for the sub-domain.
Sub-domain websiteParent domain serverCookies are created for the parent domain.
warning

For sub-domain websites to set cookies for the parent domain, secure and sameSite cookie attributes are set to true and None respectively.

Otherwise, the browser will not set the server-side cookies.

A sample request flow is illustrated below:

The JavaScript SDK makes explicit POST requests to the server to set cookies via the /rsaRequest endpoint:

The response includes Set-Cookie headers which set the rl_anonymous_id cookie (user’s anonymousId value which is persisted through the server-side cookie).

Configure cookies

All the configuration parameters for client-side cookies are applicable for server-side cookies as well.

Additionally, there are two parameters which determine the cookies’ domain and the request URL:

ParameterDescription
sameDomainCookiesOnlySets the cookies’ domain exactly the same as the website’s domain. The created cookies are not shared with any of its sub-domain sites.
storage.cookie.domainSpecifies the domain of the cookies.

Sample behavior

Let’s assume there are two websites where the server-side cookies feature is enabled in the JavaScript SDK, namely https://example.com (parent website) and https://sub.example.com (sub-domain website).

The following are the possible combinations of the configuration options and cookie domains:

  • Parent domain website - https://example.com
DomainExpected behavior
Default
  • Request URL: Default endpoint (https://example.com/rsaRequest)
  • Cookie domain: .example.com
  • Shared with sub-domain websites? Yes, for example https://sub.example.com
Same domain cookies
(sameDomainCookiesOnly must be set to true)
  • Request URL: Default endpoint (https://example.com/rsaRequest)
  • Cookie domain: example.com (without leading .)
  • Shared with sub-domain websites? No
Custom domain
  • Since this is already the parent domain website, the server-side cookies cannot be created for any domain other than the current one.
  • If you set the value of storage.cookie.domain to any value other than example.com or .example.com, the browser will not set any cookies.
  • Sub-domain website - https://sub.example.com
DomainExpected behavior
Default
  • Request URL: Default endpoint (https://example.com/rsaRequest)
  • Cookie domain: .example.com
  • Shared with sub-domain websites? Yes, with the parent and any of its peer sub-domain websites, for example https://sub2.example.com
Same domain cookies
(sameDomainCookiesOnly must be set to true)
  • Request URL: https://sub.example.com/rsaRequest
  • Cookie domain: sub.example.com (without leading .)
  • Shared with sub-domain websites? No
Custom domain
(storage.cookie.domain set to .sub.example.com.)
  • Request URL: https://sub.example.com/rsaRequest
  • Cookie domain: .sub.example.com
  • Shared with sub-domain websites? Yes, with all of its sub-domain websites, for example https://level2.sub.example.com

Implementation

If you have implemented a different endpoint than the default (rsaRequest), update your instrumentation as follows:

rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  useServerSideCookies: true, // Default: false
  dataServiceEndpoint: <custom_endpoint>
  ...
});

The JavaScript SDK can successfully manage cookies if your website’s server is proficient to handle these requests and responds with the appropriate cookie headers. You can ensure this by using any of the following methods:

Proxy

info
RudderStack’s data plane can handle these cookie requests out of the box.

This method involves setting up a proxy between the RudderStack data plane and the website to handle the cookie requests from the SDK.

Depending on the existing setup of your website, you can implement proxy as follows:

CDN

If your website is served via CDN, you can update it to support the cookie requests endpoint.

The following steps outline how to configure AWS CloudFront to proxy the requests to data plane. The configuration process is more or less similar for the other tools.

  1. Create a custom origin
SettingDescription
Origin DomainEnter the data plane URL from your RudderStack dashboard.
NameProvide a unique name for this origin.
  1. Create behavior for /rsaRequest endpoint
SettingDescription
Path PatternEnter /rsaRequest.
Origin and origin groupsSelect the Name created in the previous step.
Viewer Protocol PolicySet to HTTPS Only or Redirect HTTP to HTTPS, as required.
Allowed HTTP MethodsSelect GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE.
  1. Edit the origin request policy
SettingDescription
NameEnter the name of custom origin request policy, for example Custom-Origin-Request-Policy.
HeadersSelect headers as shown below, allowing even the sub-domain sites to make cookie requests. Otherwise, you will face CORS errors for the OPTION requests.
  1. Enter the following settings
SettingDescription
Cache key and origin requestsSelect Cache policy and origin policy (recommended)
Cache PolicySelect CachingDisabled as these are POST requests.
Origin Request PolicySelect the name of custom origin request policy created in the previous step.

By following the above steps, you can configure CloudFront to proxy specific requests to a different origin using behaviours and custom cache policies.

You can also enable logging in CloudFront to monitor requests and troubleshoot any issues. See AWS CloudFront documentation for more information.

Reverse proxy

This method outlines the changes to the reverse proxy configuration to handle the cookie requests from the SDK.

The following sample snippet is for Nginx but the implementation is similar for other proxies like Apache or HAProxy.

daemon off;
events {
}
http {
    server {
        listen 8080;
        location /rsaRequest/ {
            proxy_pass <DATA_PLANE_URL>$request_uri;
        }
    }
}
info
Ensure that the request and response headers are not stripped off in the Nginx proxy configuration.

Custom implementation

If you have another custom implementation of your website, contact the RudderStack team to share a sample implementation for your endpoint to handle the cookie requests from the JavaScript SDK.

Sample snippets

FAQ

Are the server-side cookies applicable for device mode integrations as well?

No, RudderStack does not control the cookies set by any integration platform.


Questions? Contact us by email or on Slack