# Data collection

Learn how to collect information for personalization.

This guide explains how to associate the visitor with a user from your site, enrich their profile, and detect their locale, so you can deliver personalized experiences.

Identity and locale are resolved on the server. Profile and session attributes are collected in the browser, which you trigger from your templates with the [`croct`](/reference/sdk/symfony/api/twig/croct-filter) Twig filter.

## Identity \[#identity]

When your site has authenticated users, you can link the visitor session with the logged-in user so you can recognize them when they return.

### Automatic reconciliation

The module reconciles the visitor with the authenticated [Drupal user](https://www.drupal.org/docs/user_guide/en/user-concept.html) on every request, using the user ID as the [user ID](/reference/cql/context#user). This is enabled by default and requires no code.

You can then recognize identified users in your queries using the [`user`](/reference/cql/context#user) variable:

```cql
user is identified
```

### Custom identifier

By default, the module uses the Drupal user ID. To reconcile with a different identifier, such as the email, implement the [identity resolver](/reference/sdk/php/api/resolvers/identity-resolver) interface:

**web/modules/custom/my\_module/src/EmailIdentityResolver.php**

```php
<?php

declare(strict_types=1);

namespace Drupal\my_module;

use Croct\Plug\IdentityResolver;
use Drupal\Core\Session\AccountInterface;

final class EmailIdentityResolver implements IdentityResolver
{
    private AccountInterface $account;

    public function __construct(AccountInterface $account)
    {
        $this->account = $account;
    }

    public function getUserId(): ?string
    {
        return $this->account->isAnonymous() ? null : $this->account->getEmail();
    }
}
```

Then override the resolver service to use your class in your module's `*.services.yml`:

**web/modules/custom/my\_module/my\_module.services.yml**

```yaml
services:
    Drupal\croct\AccountIdentityResolver:
        class: Drupal\my_module\EmailIdentityResolver
        arguments: ['@current_user']
```

## Profile and session attributes \[#attributes]

Besides identity, you can enrich the visitor's profile and session with information relevant to your business. These calls run in the browser, so you trigger them from your templates with the [`croct`](/reference/sdk/symfony/api/twig/croct-filter) Twig filter.

For example, to record the plan a user is considering on the pricing page:

```twig
{% apply croct %}
    const selector = document.getElementById('plan-selector');

    selector.addEventListener('change', () => {
        croct.session.edit()
            .set('plan', selector.value)
            .save();
    });
{% endapply %}
```

See [Data collection](/reference/sdk/javascript/data-collection) for the full client-side API.

## Locale detection \[#locale]

The module detects the visitor locale from [Drupal's language negotiation](https://www.drupal.org/docs/8/multilingual) automatically and forwards it as the preferred locale, so content is returned in the matching language out of the box.

For full control, implement the [locale resolver](/reference/sdk/php/api/resolvers/locale-resolver) interface. For example, to serve content in each user's preferred language instead of the negotiated one:

**web/modules/custom/my\_module/src/AccountLocaleResolver.php**

```php
<?php

declare(strict_types=1);

namespace Drupal\my_module;

use Croct\Plug\LocaleResolver;
use Drupal\Core\Session\AccountInterface;

final class AccountLocaleResolver implements LocaleResolver
{
    private AccountInterface $account;

    public function __construct(AccountInterface $account)
    {
        $this->account = $account;
    }

    public function getLocale(): ?string
    {
        return $this->account->getPreferredLangcode() ?: null;
    }
}
```

Then override the resolver service to use your class in your module's `*.services.yml`:

**web/modules/custom/my\_module/my\_module.services.yml**

```yaml
services:
    Drupal\croct\LanguageManagerLocaleResolver:
        class: Drupal\my_module\AccountLocaleResolver
        arguments: ['@current_user']
```

## Explore

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