# Custom attributes

Define additional attributes specific to your business.

In addition to the [standard attributes](/reference/user/standard-attributes), the user profile supports custom attributes. Use them to track information specific to your business needs, such as preferences, categories, or internal classifications.

## Implementation

Here is an example of how to set a custom attribute:

**JavaScript**

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

await croct.user.edit()
.set('custom.expertise', "Engineering")
.save();
```

**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>
    const update = () => croct.user.edit()
      .set('custom.expertise', "Engineering")
      .save();
  </script>
  <button onclick="update()">Update</button>
</body>
</html>
```

**React — JavaScript**

```jsx
import {useCroct} from '@croct/plug-react';

export function Example() {
const croct = useCroct();

const update = () => croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save();

return (<button onClick={update}>Update</button>);
}
```

**React — TypeScript**

```typescript
import {useCroct} from '@croct/plug-react';
import type {ReactElement} from 'react';

export function Example(): ReactElement {
const croct = useCroct();

const update = () => croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save();

return (<button onClick={update}>Update</button>);
}
```

**Next — JavaScript**

```jsx
import {useCroct} from '@croct/plug-next';

export function Example() {
const croct = useCroct();

const update = () => croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save();

return (<button onClick={update}>Update</button>);
}
```

**Next — TypeScript**

```tsx
import {useCroct} from '@croct/plug-next';
import type {ReactElement} from 'react';

export function Example(): ReactElement {
const croct = useCroct();

const update = () => croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save();

return (<button onClick={update}>Update</button>);
}
```

**Vue — JavaScript**

```vue
<script setup>
import {useCroct} from '@croct/plug-vue'

const croct = useCroct()

const update = () => croct.user.edit()
.set('custom.expertise', "Engineering")
.save()
</script>

<template>
  <button @click="update">Update</button>
</template>
```

**Vue — TypeScript**

```vue
<script setup lang="ts">
import {useCroct} from '@croct/plug-vue'

const croct = useCroct()

const update = (): void => {
croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save()
}
</script>

<template>
  <button @click="update">Update</button>
</template>
```

**Nuxt — JavaScript**

```vue
<script setup>
const croct = useCroct()

const update = () => croct.user.edit()
.set('custom.expertise', "Engineering")
.save()
</script>

<template>
  <button @click="update">Update</button>
</template>
```

**Nuxt — TypeScript**

```vue
<script setup lang="ts">
const croct = useCroct()

const update = (): void => {
croct.user.edit()
  .set('custom.expertise', "Engineering")
  .save()
}
</script>

<template>
  <button @click="update">Update</button>
</template>
```

## Attributes

- `custom.*`: `string|number|boolean|array|object|null`

  A custom attribute, where `*` is the name of the attribute, such as `custom.pets` or `custom.loyaltyNumber`.

> **Best practice**
>
> Use descriptive camel case names like `pets`, `favoriteColor`, and `loyaltyNumber` for custom attributes to improve readability and consistency with standard attributes.

## Restrictions

The following restrictions apply to custom attributes:

- Profiles support up to 10 custom attributes.
- Attribute names must be strings up to 20 characters, starting with a letter or underscore, followed by letters, digits, or underscores.
- Attributes can be primitives (strings, numbers, booleans, null) or collections (lists, maps).
- Strings can be up to 100 characters long.
- Lists can contain up to 10 elements, including primitives, lists of primitives, or maps of primitives.
- Maps can contain up to 10 elements, including primitives, lists of primitives, or maps of primitives.
- Map keys must be strings up to 50 characters long.

Attribute names are case-insensitive, so `loyaltyNumber` and `loyaltynumber` are treated as the same attribute and will override each other.

## Explore

- [Standard attributes](/reference/user/standard-attributes): Browse the predefined attributes available on every user profile.
- [Audiences](/explanation/audience): Understand how to deliver content to specific groups of users.
