# Edit profile settings

Text, select, and textarea fields in one form.

Source: https://withastro-utils.github.io/docs/examples/settings/

Complete the [Forms setup](https://withastro-utils.github.io/docs/guides/forms/getting-started/index.md) first, or use the configuration, middleware, and layout files in the sidebar. Install `@astro-utils/forms` and `@astrojs/node` in an existing Astro project.

## Try the interaction

Change the name, language, and bio, then save. In your own project, reload the page to see the session-backed values restored.

### src/layouts/Layout.astro

```astro title="src/layouts/Layout.astro"
---
import { WebForms } from '@astro-utils/forms/forms.js';
---
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width" />
        <title><slot name="title" /></title>
    </head>
    <body>
        <WebForms>
            <slot />
        </WebForms>
    </body>
</html>
```

### src/pages/settings.astro

```astro title="src/pages/settings.astro"
---
import { BButton, BInput, BOption, BSelect, BTextarea, Bind, BindForm, FormErrors } from '@astro-utils/forms/forms.js';
import Layout from '../layouts/Layout.astro';

type Preferences = { name: string; locale: string; bio: string };

const bind = Bind<Preferences>(Astro.locals.session.preferences ?? { name: 'Ari Chen', locale: 'en', bio: '' });
let saved = false;

function savePreferences() {
    Astro.locals.session.preferences = { name: bind.name, locale: bind.locale, bio: bind.bio };
    saved = true;
}
---
<Layout>
    <span slot="title">Edit profile settings</span>
    <BindForm {bind}>
        <FormErrors />

        {saved && <p role="status">Preferences saved.</p>}

        <label for="name">Display name</label>
        <BInput id="name" name="name" maxlength={40} required />

        <label for="locale">Language</label>
        <BSelect id="locale" name="locale">
            <BOption value="en">English</BOption>
            <BOption value="es">Spanish</BOption>
            <BOption value="fr">French</BOption>
        </BSelect>

        <label for="bio">Bio</label>
        <BTextarea id="bio" name="bio" maxlength={180} />
        
        <BButton onClick={savePreferences} whenFormOK>Save changes</BButton>
    </BindForm>
</Layout>
```

### src/middleware.ts

```ts title="src/middleware.ts"
import forms from '@astro-utils/forms';

export const onRequest = forms();
```

### astro.config.mjs

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
import forms from '@astro-utils/forms/dist/integration.js';

export default defineConfig({
    output: 'server',
    adapter: node({ mode: 'standalone' }),
    integrations: [forms]
});
```

## How it works

The source reads and writes a small preferences object through `Astro.locals.session`. The embedded preview only demonstrates the controls and save feedback. Use application storage for preferences that must survive session expiry or work across devices.

## Continue

Explore the [input component reference](https://withastro-utils.github.io/docs/reference/forms/basic-form-components/index.md).
