# Data collection

Learn how to collect information for personalization.

This guide provides practical examples of using the JavaScript SDK to enrich user profiles and sessions with information relevant to your business.

## User data

You can persist user-related information in one of the two ways described below depending on whether it is related to the user's profile or their current session.

### Profile data

You can enrich user profiles with details collected via forms, surveys, or other means.

These pieces of information, called *attributes*, are categorized as *standard* or *custom* depending on whether it is generic or specific to your organization.

#### Standard attributes

These are [predefined attributes](/reference/user/standard-attributes) that are common most businesses, such as the user's name, email, and interests.

You can set standard attributes using the [`user.edit`](api/user/edit) method:

**Updating user profiles**

**JavaScript**

```js
import croct from '@croct/plug';

async function onSignup(name, email) {
  await croct.user.edit()
    .set('name', name)
    .set('email', email)
    .save();

    alert('User profile updated!');
}

onSignup('John Doe', 'john@croct.com');
```

**TypeScript**

```ts
import croct from '@croct/plug';

async function onSignup(name: string, email: string): Promise<void> {
  await croct.user.edit()
    .set('name', name)
    .set('email', email)
    .save();

    alert('User profile updated!');
}

onSignup('John Doe', 'john@croct.com');
```

**HTML**

```html
<!DOCTYPE html>
<html>
<head>
  <title>My awesome application</title>
  <script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
  <script>croct.plug({appId: 'APPLICATION_ID'});</script>
</head>
<body>
  <script>
      function onSignup(name, email) {
        croct.user.edit()
          .set('name', name)
          .set('email', email)
          .save();
      }
  </script>
  <form onSubmit="onSignup(this.name.value, this.email.value); return false;">
    <input type="text" name="name" placeholder="Name">
    <input type="email" name="email" placeholder="Email">
    <button type="submit">Sign up</button>
  </form>
</body>
</html>
```

The [`user.edit`](api/user/edit) method returns a [`Patch`](api/patch) instance that allows you to chain multiple operations together.

You could alternatively write:

**Alternative syntax**

**JavaScript**

```js
import croct from '@croct/plug';

async function onSignup(name, email) {
  const patch = croct.user.edit();

  patch.set('name', name);
  patch.set('email', email);

  await patch.save();

  alert('User profile updated!');
}

onSignup('John Doe', 'john@croct.com');
```

**TypeScript**

```ts
import croct from '@croct/plug';

async function onSignup(name: string, email: string): Promise<void> {
  const patch = croct.user.edit();

  patch.set('name', name);
  patch.set('email', email);

  await patch.save();

  alert('User profile updated!');
}

onSignup('John Doe', 'john@croct.com');
```

**HTML**

```html
<!DOCTYPE html>
<html>
<head>
  <title>My awesome application</title>
  <script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
  <script>croct.plug({appId: 'APPLICATION_ID'});</script>
</head>
<body>
  <script>
      function onSignup(name, email) {
        const patch = croct.user.edit();

        patch.set('name', name);
        patch.set('email', email);

        await patch.save();

        alert('User profile updated!');
      }
  </script>
  <form onSubmit="onSignup(this.name.value, this.email.value); return false;">
    <input type="text" name="name" placeholder="Name">
    <input type="email" name="email" placeholder="Email">
    <button type="submit">Sign up</button>
  </form>
</body>
</html>
```

When you call [`save`](api/patch/save), it saves changes to the user profile and returns a promise that confirms the operation.

You can then access standard attributes in your queries using the [`user`](/reference/cql/context#user) variable:

```cql
user's email ends with "@croct.com"
```

For a complete list of attributes, see [User profile reference](/reference/cql/data-types/user/user).

#### Custom attributes

In addition to the standard attributes, you can add [custom attributes](/reference/user/custom-attributes) to enrich user profiles with information relevant to your business.

For example, let's say you have a SaaS application and you want to ask your users about their area of expertise so you can personalize the onboarding experience.

This is what it would look like:

**Setting custom attributes**

**JavaScript**

```js
import croct from '@croct/plug';

async function onExpertiseInformed(area) {
  await croct.user.edit()
    .set('custom.expertise', area)
    .save();

    alert('User profile updated!');
}

onExpertiseInformed('Engineering');
```

**TypeScript**

```ts
import croct from '@croct/plug';

async function onExpertiseInformed(area: string): Promise<void> {
  await croct.user.edit()
    .set('custom.expertise', area)
    .save();

  alert('User profile updated!');
}

onExpertiseInformed('Engineering');
```

**HTML**

```html
<!DOCTYPE html>
<html>
<head>
  <title>My awesome application</title>
  <script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
  <script>croct.plug({appId: 'APPLICATION_ID'});</script>
</head>
<body>
  <script>
    async function onExpertiseInformed(area) {
      await croct.user.edit()
        .set('custom.expertise', area)
        .save();

      alert('User profile updated!');
    }
  </script>
  <select onChange="onExpertiseInformed(this.value)">
    <option value="engineering">Engineering</option>
    <option value="design">Design</option>
    <option value="marketing">Marketing</option>
  </select>
</body>
</html>
```

Note that custom attributes are prefixed with `custom` to avoid conflicts with standard attributes. However, you do not need to include the prefix in your queries:

```cql
user's expertise is "Engineering"
```

### Session data

Besides user profiles, you can also store information relevant to the user's current session.

Storing session information can help you keep track of important the user's current session that may not be relevant to their profile. For example, you can store the plan the user selected on the pricing page, or any other information you want to record during the user's visit.

To store session information, use the [`session.edit`](api/session/edit) method:

**Saving session data**

**JavaScript**

```js
import croct from '@croct/plug';

async function onPlanSelected(plan) {
  await croct.session.edit()
    .set('plan', plan)
    .save();

  alert('Session updated!');
}

onPlanSelected('premium');
```

**TypeScript**

```ts
import croct from '@croct/plug';

async function onPlanSelected(plan: string): Promise<void> {
  await croct.session.edit()
    .set('plan', plan)
    .save();

  alert('Session updated!');
}

onPlanSelected('premium');
```

**HTML**

```html
<!DOCTYPE html>
<html>
<head>
  <title>My awesome application</title>
  <script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
  <script>croct.plug({appId: 'APPLICATION_ID'});</script>
</head>
<body>
  <script>
    async function onPlanSelected(plan) {
      await croct.session.edit()
        .set('plan', plan)
        .save();

      alert('Session updated!');
    }
  </script>
  <select onChange="onPlanSelected(this.value)">
    <option value="basic">Basic</option>
    <option value="premium">Premium</option>
    <option value="enterprise">Enterprise</option>
  </select>
</body>
</html>
```

In the same way as with user profiles, the [`session.edit`](api/session/edit) method returns a [`Patch`](api/patch) instance that allows you to chain multiple operations together.

**Alternative syntax**

**JavaScript**

```js
import croct from '@croct/plug';

async function onPlanSelected(plan) {
  const patch = croct.session.edit();

  patch.set('plan', plan);

  await patch.save();

  alert('Session updated!');
}

onPlanSelected('premium');
```

**TypeScript**

```ts
import croct from '@croct/plug';

async function onPlanSelected(plan: string): Promise<void> {
  const patch = croct.session.edit();

  patch.set('plan', plan);

  await patch.save();

  alert('Session updated!');
}

onPlanSelected('premium');
```

**HTML**

```html
<!DOCTYPE html>
<html>
<head>
  <title>My awesome application</title>
  <script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
  <script>croct.plug({appId: 'APPLICATION_ID'});</script>
</head>
<body>
  <script>
    async function onPlanSelected(plan) {
      const patch = croct.session.edit();

      patch.set('plan', plan);

      await patch.save();

      alert('Session updated!');
    }
  </script>
  <select onChange="onPlanSelected(this.value)">
    <option value="basic">Basic</option>
    <option value="premium">Premium</option>
    <option value="enterprise">Enterprise</option>
  </select>
</body>
</html>
```

When you call [`save`](api/patch/save), it saves changes to the session and returns a promise that confirms the operation. You can then access session information in your queries using the [`session`](/reference/cql/context#session) variable:

```cql
session's plan is "premium"
```

For a complete list of attributes, see [Session reference](/reference/cql/data-types/session/web-session).

## User identity

When a user registers or logs in, you may want to associate their profile with an identifier that is meaningful to your business, so that you can recognize them when they return.

You can use any identifier that is meaningful to your business, such as an email address, a username, or a customer ID provided it is unique.

To associate a user profile with an identifier, use the [`identify`](api/plug/identify) method:

```js
croct.identify('0e8f3b9e-8b5a-4f5c-9b8a-0e8f3b9e8b5a');
```

You usually call `identify` when the user logs in or registers. In the same way, you can call [`anonymize`](api/plug/anonymize) when the user logs out:

```js
croct.anonymize();
```

During the initialization of the SDK, it is important to specify whether the user is anonymous or identified:

```js
croct.plug({
  // ...
  userId: 'john-doe', // or null if the user is anonymous
});
```

This will prevent the SDK from sending anonymous events before you call [`identify`](api/plug/identify) or [`anonymize`](api/plug/anonymize) resulting in two sessions — one anonymous and one identified. For more information, see the [`userId`](api/plug/plug#configuration-userid-prop) documentation.

## Explore

- [Audiences](/explanation/audience): Understand how to delivery content to specific groups of users.
- [CQL](/reference/cql/syntax): Get the basics on how to write conditions to define audiences.
