---
title: "Initializing tracking, events, and personalization in the Content SDK"
slug: "initializing-tracking,-events,-and-personalization-in-the-content-sdk"
abstract: "How Content SDK implements tracking, events, and personalization through the use of plugins and adapters."
---
# Initializing tracking, events, and personalization in the Content SDK

The Content SDK has undergone a major architectural transformation to include functionality from the Sitecore Cloud SDK. This also moves from an older initialization pattern to a modern [plugin](https://doc.sitecore.com/sai/en/developers/content-sdk/20/plugins.html "Plugins")\-based architecture providing better modularity, type safety, and a unified approach to browser and server-side implementations.

## Changes to initialization

The earlier initialization chained the required functionality using the dot (.) operator. See examples below for browser and server implementations.

::::tabs
:::tab{title="Browser initialization (old)"}
{ .notintoc }

```csharp
'use client';

import { useEffect } from 'react';
import { CloudSDK } from '@sitecore-cloudsdk/core/browser';
import '@sitecore-cloudsdk/events/browser';
import '@sitecore-cloudsdk/personalize/browser';

export default function Home() {
  useEffect(() => {
    CloudSDK({
      sitecoreEdgeContextId: '<YOUR_CONTEXT_ID>',
      siteName: '<YOUR_SITE_NAME>',
      enableBrowserCookie: true,
    })
      .addEvents()
      .addPersonalize({
        enablePersonalizeCookie: true,
        webPersonalization: true,
      })
      .addSearch()
      .initialize();
  }, []);

  return <></>;
}
```

:::
:::tab{title="Server initialization (old)"}
{ .notintoc }

```csharp
import type { NextRequest, NextResponse } from 'next/server';
import { CloudSDK } from '@sitecore-cloudsdk/core/server';
import '@sitecore-cloudsdk/events/server';
import '@sitecore-cloudsdk/personalize/server';

export async function middleware(request: NextRequest) {
  const response = NextResponse.next();

  await CloudSDK(request, response, {
    sitecoreEdgeContextId: '<YOUR_CONTEXT_ID>',
    siteName: '<YOUR_SITE_NAME>',
    enableServerCookie: true,
  })
    .addEvents()
    .addPersonalize({ enablePersonalizeCookie: true })
    .addSearch()
    .initialize();

  return response;
}
```

:::
::::

The new initialization method uses a combination of [plugins](https://doc.sitecore.com/sai/en/developers/content-sdk/20/plugins.html "Plugins") to determine the functionality and [adapters](https://doc.sitecore.com/sai/en/developers/content-sdk/20/adapters.html "Adapters") to determine the environment. The initialization function (`initContentSdk`) accepts a config object (`contextId`, `siteName`), and a plugins array, where analytics, events, and personalization are all plugins. Environment differences (browser vs proxy/server) are handled through the chosen adapter. The `analyticsPlugin` is always present if you use events or personalize.

::::tabs
:::tab{title="Browser initialization (new)"}
{ .notintoc }

```csharp
'use client';

import { useEffect } from 'react';
import { initContentSdk } from '@sitecore-content-sdk/core';
import { analyticsPlugin, analyticsBrowserAdapter } from '@sitecore-content-sdk/analytics-core';
import { eventsPlugin } from '@sitecore-content-sdk/events';
import { personalizeBrowserPlugin, personalizeBrowserAdapter } from '@sitecore-content-sdk/personalize';

export default function Home() {
  useEffect(() => {
    initContentSdk({
      config: {
        contextId: '<YOUR_CONTEXT_ID>',
        siteName: '<YOUR_SITE_NAME>',
      },
      plugins: [
        analyticsPlugin({
          options: { enableCookie: true },
          adapter: analyticsBrowserAdapter(),
        }),
        eventsPlugin(),
        personalizeBrowserPlugin({
          options: { enablePersonalizeCookie: true },
          adapter: personalizeBrowserAdapter(),
        }),
      ],
    });
  }, []);

  return <></>;
}
```

:::
:::tab{title="Server initialization (new)"}
{ .notintoc }

```csharp
import type { NextRequest, NextResponse } from 'next/server';
import { initContentSdk } from '@sitecore-content-sdk/core';
import { analyticsPlugin } from '@sitecore-content-sdk/analytics-core';
import { eventsPlugin } from '@sitecore-content-sdk/events';
import { personalizeServerPlugin } from '@sitecore-content-sdk/personalize';
import { analyticsProxyAdapter, personalizeProxyAdapter } from '@sitecore-content-sdk/nextjs';

export async function proxy(request: NextRequest) {
  const response = NextResponse.next();

  await initContentSdk({
    config: {
      contextId: '<YOUR_CONTEXT_ID>',
      siteName: '<YOUR_SITE_NAME>',
    },
    plugins: [
      analyticsPlugin({
        options: { enableCookie: true },
        adapter: analyticsProxyAdapter(request, response),
      }),
      eventsPlugin(),
      personalizeServerPlugin({
        options: { enablePersonalizeCookie: true },
        adapter: personalizeProxyAdapter(request, response),
      }),
    ],
  });

  return response;
}
```

:::
::::

### Isomorphic functions

The new architecture makes use of isomorphic functions that allows event tracking and other SDK functions to be used identically on both client and server with the same import and function signature. Isomorphic functions provides benefits like using a single import path instead of `/browser` and `/server` paths, a consistent API, and type safety across environments.

See the following examples for browser and server environments for the `pageView` function.

```javascript
// Browser
import { pageView } from '@sitecore-cloudsdk/events/browser';

// Server
import { pageView } from '@sitecore-cloudsdk/events/server';
```

Using the isomorphic version in Content SDK 2.0, you can import it without the `/browser` or `/server` in the import path:

```text
import { pageView } from '@sitecore-content-sdk/events';
```

## Changes to packages and modules

Since the Cloud SDK packages have now been integrated into the Content SDK, the following paths have changed:

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Old (Cloud SDK)</p></th><th class="th"><p>New (Content SDK)</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">@sitecore-cloudsdk/core</code></p></td><td class="td"><p><code class="code">@sitecore-content-sdk/analytics-core</code></p></td></tr><tr><td class="td"><p><code class="code">@sitecore-cloudsdk/events</code></p></td><td class="td"><p><code class="code">@sitecore-content-sdk/events</code></p></td></tr><tr><td class="td"><p><code class="code">@sitecore-cloudsdk/personalize</code></p></td><td class="td"><p><code class="code">@sitecore-content-sdk/personalize</code></p></td></tr></tbody></table>

All packages now use a single entry point with environment-specific behavior controlled through adapters. This allows you to use the base import path instead of using `/browser` or `/server`.

> [!note]
> To use the queue functionality, you must still use the full import path. For example:
>
> ```text
> import { addToEventQueue, processEventQueue, clearEventQueue } from '@sitecore-content-sdk/events/browser';
> ```

## Changes to settings

Several settings have been simplified by renaming them and moving them into their specific plugins. See the following table for more information:

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Old property</p></th><th class="th"><p>New property</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">sitecoreEdgeContextId</code></p></td><td class="td"><p><code class="code">contextId</code></p></td><td class="td"><p>Simplified name but the same value.</p></td></tr><tr><td class="td"><p><code class="code">sitecoreEdgeUrl</code></p></td><td class="td"><p><code class="code">edgeUrl</code></p></td><td class="td"><p>Optional. Can be provided in the initialization <code class="code">config</code> object. Defaults to the production edge URL.</p></td></tr><tr><td class="td"><p><code class="code">siteName</code></p></td><td class="td"><p><code class="code">siteName</code></p></td><td class="td"><p>Unchanged</p></td></tr><tr><td class="td"><p><code class="code">enableBrowserCookie</code></p></td><td class="td"><p>Moved to plugin options</p></td><td class="td"><p>Renamed to <code class="code">options.enableCookie</code> and now part of an <code class="code">options</code> object passed to a plugin.</p></td></tr><tr><td class="td"><p><code class="code">enableServerCookie</code></p></td><td class="td"><p>Moved to plugin options</p></td><td class="td"><p>Renamed to <code class="code">options.enableCookie</code> and now part of an <code class="code">options</code> object passed to a plugin.</p></td></tr><tr><td class="td"><p><code class="code">enablePersonalizeCookie</code></p></td><td class="td"><p>Moved to plugin options</p></td><td class="td"><p>Plugin-specific option.</p><p>For browser:</p><pre class="programlisting" id="UUID-eda25897-f87c-6a48-c778-ae37485a85a1_programlisting-id135473107377952" data-language="csharp"><code class="language-csharp" data-language="csharp">personalizeBrowserPlugin({
    adapter: personalizeBrowserAdapter(),
    options: { enablePersonalizeCookie: true },
}),</code></pre><p>For server:</p><pre class="programlisting" id="UUID-eda25897-f87c-6a48-c778-ae37485a85a1_programlisting-id135473106037166" data-language="csharp"><code class="language-csharp" data-language="csharp">personalizeServerPlugin({
    adapter: personalizeServerAdapter(request as any, response),
    options: { enablePersonalizeCookie: true },
}),</code></pre></td></tr></tbody></table>

## Changes to cookies

The following cookies have been renamed:

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Old name</p></th><th class="th"><p>New name</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">sc_{sitecoreEdgeContextId}</code></p></td><td class="td"><p><code class="code">sc_cid</code></p></td></tr><tr><td class="td"><p><code class="code">sc_{sitecoreEdgeContextId}_personalize</code></p></td><td class="td"><p><code class="code">sc_cid_personalize</code></p></td></tr></tbody></table>

## Changes to the `window` object

Content SDK injects a global `scContentSDK` variable into the `window` object when either of the built-in plugins is used with a browser adapter (server and proxy adapters will not add it). `window.scContentSDK` provides access to the current analytics configuration, the client ID, and library version for diagnostics and debugging purposes, without requiring you to import or directly access any plugin instances.

This replaces the older `window.scCloudSDK['analytics-core']` structure from the Cloud SDK, but gives the same stable debugging surface for analytics without coupling your code to the plugins API. The global variable is also resilient to multiple SDK initializations: any new properties introduced by extra plugins will be added to the properties that already exist in the `scContentSDK` object.

For example, when the SDK is initialized as shown:

```csharp
initContentSdk({
  config: {
    contextId: "<YOUR_CONTEXT_ID>",
    siteName: "<YOUR_SITE_NAME>",
  },
  plugins: [
    analyticsPlugin({
      options: { enableCookie: true },
      adapter: analyticsBrowserAdapter(),
    }),
  ],
});
```

The browser adapter (`analyticsBrowserAdapter()`) in the analytics plugin creates the global variable during the `init` phase. It contains an `analytics_core` property with three members:

- `getClientId` - a function that returns the current client ID.
- `options` - an object with the site name, context ID, and edge URL from your SDK configuration.
- `version` - a string describing the version of the `analytics‑core` library used.