> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Anonymous Sessions Use Cases

> Learn about anonymous sessions use cases with Actions.

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "Beta",
    "ea": "Early Access"
  };
  const stageText = stageTextMap[stage] || "a product release stage";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>This feature is available for {linkify(`${plans} plans`, "https://auth0.com/pricing")}. </>}
            {contact && "To participate, contact " + contact + ". "}
            {terms && <>By using this feature, you agree to the applicable Free Trial terms in Okta's {linkify("Master Subscription Agreement", "https://www.okta.com/legal")}.</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>The {feature} feature is in {linkify(stageText, prsLink)}.</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

<ReleaseStageNotice feature="Anonymous Sessions" stage="beta" terms="true" contact="Auth0 Support" />

When a user authenticates in your application, anonymous sessions and [Actions](/docs/customize/actions/actions-overview) allow you to transfer anonymous session data, such as shopping cart contents, preferences, and browsing history, to their authenticated user profile.

You can reference the `event.anonymous_session` object in Actions:

```typescript theme={null} theme={null}
{
  user_id: string;     // anonymous user id 
  session_id: string;  // anonymous session token id
  created_at: number;  // anonymous session creation timestamp
  expires_at: number;  // anonymous session expiration timestamp
  metadata: {          // anonymous session metadata object
    [key: string]: string
  };
}
```

## Anonymous sessions and Actions use cases

### Save anonymous session metadata to a new user

You can use a [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) Action trigger to copy anonymous metadata into the new user profile when they sign up:

```javascript wrap lines theme={null}
exports.onExecutePreUserRegistration = async (event, api) => {
  if (event.anonymous_session) {
    // Store reference to the anonymous session
    api.user.setAppMetadata(
      'linked_anonymous_id',
      event.anonymous_session.user_id
    );

    // Migrate cart data
    if (event.anonymous_session.metadata.cart) {
      api.user.setAppMetadata(
        'migrated_cart',
        event.anonymous_session.metadata.cart
      );
    }

    // Copy preferences to user metadata
    if (event.anonymous_session.metadata.preferences) {
      api.user.setUserMetadata(
        'preferences',
        event.anonymous_session.metadata.preferences
      );
    }
  }
};
```

### Save anonymous session metadata to an existing user

You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to save anonymous metadata to existing users when they log in:

```javascript wrap lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  if (event.anonymous_session) {
    // Store last anonymous session reference
    api.user.setAppMetadata(
      'last_anonymous_session',
      event.anonymous_session.user_id
    );

    // Add anonymous cart to access token for your API to process
    api.accessToken.setCustomClaim(
      'anonymous_cart',
      event.anonymous_session.metadata.cart
    );

    // Track all linked sessions (optional)
    const linkedSessions =
      event.user.app_metadata?.linked_sessions || [];
    if (!linkedSessions.includes(event.anonymous_session.user_id)) {
      api.user.setAppMetadata('linked_sessions', [
        ...linkedSessions,
        event.anonymous_session.user_id,
      ]);
    }
  }
};
```

### Merge user metadata with anonymous metadata

You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to merge anonymous metadata to an existing user metadata, such as a cart information, when they log in:

```javascript wrap lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  if (!event.anonymous_session?.metadata?.cart) {
    return; // No anonymous cart to merge
  }

  const anonymousCart = event.anonymous_session.metadata.cart;
  const existingCart = event.user.app_metadata?.cart || { items: [] };

  // Merge cart items, combining quantities for matching SKUs
  const mergedItems = [...existingCart.items];
  for (const anonItem of anonymousCart.items) {
    const existingIndex = mergedItems.findIndex(
      (item) => item.sku === anonItem.sku
    );
    if (existingIndex >= 0) {
      mergedItems[existingIndex].qty += anonItem.qty;
    } else {
      mergedItems.push(anonItem);
    }
  }

  api.user.setAppMetadata('cart', { items: mergedItems });
  api.accessToken.setCustomClaim('cart', { items: mergedItems });
};
```

### Handle multiple anonymous sessions

You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to manage anonymous session metadata from different devices, when the user logs in:

```javascript wrap lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  if (!event.anonymous_session) return;

  const linkedSessions =
    event.user.app_metadata?.linked_sessions || [];

  // Option 1: Keep all linked sessions
  api.user.setAppMetadata('linked_sessions', [
    ...linkedSessions,
    {
      user_id: event.anonymous_session.user_id,
      linked_at: new Date().toISOString(),
      device: event.request.user_agent,
    },
  ]);

  // Option 2: Keep only the most recent
  api.user.setAppMetadata('last_anonymous_session', {
    user_id: event.anonymous_session.user_id,
    metadata: event.anonymous_session.metadata,
  });
};
```

## Learn more

* [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions) Learn how to configure anonymous sessions.
* [Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions) Learn about anonymous sessions.
