# Data collection

Learn how to collect information for personalization.

This guide explains how to associate the visitor with a user from your application, 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 views with the [`@croct`](/reference/sdk/laravel/api/blade) Blade directive.

## Identity \[#identity]

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

### Automatic reconciliation

When you use [Laravel's authentication](https://laravel.com/docs/authentication), the package reconciles the visitor with the authenticated user on every request, using the user identifier 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 package uses the authenticated user's primary key. To reconcile with a different identifier, such as the email or a UUID, implement the [identity resolver](/reference/sdk/php/api/resolvers/identity-resolver) interface:

**app/Croct/AuthIdentityResolver.php**

```php
<?php

namespace App\Croct;

use App\Models\User;
use Croct\Plug\IdentityResolver;
use Illuminate\Contracts\Auth\Factory as AuthFactory;

final class AuthIdentityResolver implements IdentityResolver
{
    private AuthFactory $auth;

    public function __construct(AuthFactory $auth)
    {
        $this->auth = $auth;
    }

    public function getUserId(): ?string
    {
        $user = $this->auth->guard()->user();

        return $user instanceof User ? (string) $user->email : null;
    }
}
```

Then bind it to the interface in a service provider so the package uses it instead of the default:

**app/Providers/AppServiceProvider.php**

```php
use App\Croct\AuthIdentityResolver;
use Croct\Plug\IdentityResolver;

public function register(): void
{
    $this->app->singleton(IdentityResolver::class, AuthIdentityResolver::class);
}
```

### Without authentication

If you do not use Laravel's authentication, implement the same [identity resolver](/reference/sdk/php/api/resolvers/identity-resolver) interface to return your own user ID, for example from the session or a token. Returning `null` keeps the visitor anonymous.

The injected [`Plug`](/reference/sdk/php/api/core/plug) service also exposes [`identify`](/reference/sdk/php/api/core/plug/identify) and [`anonymize`](/reference/sdk/php/api/core/plug/anonymize) for imperative control when you manage the session lifecycle yourself.

## 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 views with the [`@croct`](/reference/sdk/laravel/api/blade) Blade directive, passing server-side values through Blade.

### Profile data

Profile attributes describe the user across visits, such as their name, email, or interests. For example, to sync the signed-in user's details into their profile:

**resources/views/layouts/app.blade.php**

```blade
<!DOCTYPE html>
<html>
    <head>
        <title>My application</title>
    </head>
    <body>
        @yield('content')

        @auth
            @croct
                croct.user.edit()
                    .set('name', @json(auth()->user()->name))
                    .set('email', @json(auth()->user()->email))
                    .save();
            @endcroct
        @endauth
    </body>
</html>
```

### Session data

Session attributes describe the current visit, such as the plan a user is considering on the pricing page:

**resources/views/pricing.blade.php**

```blade
@extends('layouts.app')

@section('content')
    <select id="plan-selector">
        <option value="basic">Basic</option>
        <option value="premium">Premium</option>
        <option value="enterprise">Enterprise</option>
    </select>

    @croct
        const selector = document.getElementById('plan-selector');

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

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

## Locale detection \[#locale]

The package detects the visitor locale from the [application locale](https://laravel.com/docs/localization) automatically and forwards it as the preferred locale, so content is returned in the matching language out of the box. This is enabled by default, controlled by the [`locale.enabled`](/reference/sdk/laravel/api/configuration#locale-prop) option.

To pin a fixed locale or set a fallback when detection is disabled, use the [`locale.default`](/reference/sdk/laravel/api/configuration#locale-prop) option:

**config/croct.php**

```php
'locale' => [
    'default' => 'en-us',
],
```

For full control, implement the [locale resolver](/reference/sdk/php/api/resolvers/locale-resolver) interface and bind it the same way as a custom identity resolver:

**app/Providers/AppServiceProvider.php**

```php
$this->app->singleton(LocaleResolver::class, AccountLocaleResolver::class);
```

## 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.
