# Upload a large file

Chunked transfer, progress, and completion feedback.

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

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

Select a file and upload it. Use the preview’s **Simulate upload failure** option to compare success with a retryable error.

### 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/upload.astro

```astro title="src/pages/upload.astro"
---
import { type BigFile, BButton, Bind, BindForm, FormErrors, UploadBigFile, UploadBigFileProgress } from '@astro-utils/forms/forms.js';

import Layout from '../layouts/Layout.astro';

type UploadForm = {
    file: BigFile;
};

const bind = Bind<UploadForm>();
let message = '';

async function saveFile() {
    message = `${bind.file.name} is ready.`;
}
---

<Layout>
<span slot="title">Upload a large file</span>
<BindForm {bind}>
    <FormErrors />
    {message && <p role="status">{message}</p>}

    <label for="file">Project archive</label>
    <UploadBigFile id="document" name="file" required />
    <UploadBigFileProgress for="file" />
    
    <BButton onClick={saveFile} whenFormOK>Upload file</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 uploads the selected file and reports its metadata. Add your application processing in `saveFile`. The embedded preview simulates transfer progress and never sends your file to a server.

`UploadBigFileProgress for="file"` matches the upload control’s `name="file"`, even when its HTML ID is `document`. Every `BButton` submits its containing form, so put actions that must not upload the selected file outside that form. See [upload limits and failure handling](https://withastro-utils.github.io/docs/reference/forms/upload-big-file/index.md#configure-upload-limits).

## Continue

Review [Forms configuration](https://withastro-utils.github.io/docs/reference/forms/configuration/index.md).
