> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# File Upload

BFF combined with runtime framework provides file upload capabilities, supporting integrated calls and pure function manual calls.

### BFF Function

First, create the `api/lambda/upload.ts` file:

```ts title="api/lambda/upload.ts"
export const post = async ({ formData }: { formData: Record<string, any> }) => {
  console.info('formData:', formData);
  // do somethings
  return {
    data: {
      code: 0,
    },
  };
};
```

:::tip
The `formData` parameter in the interface processing function can access files uploaded from the client side. It is an `Object` where the keys correspond to the field names used during the upload.
:::

### Integrated Calling

Next, directly import and call the function in `src/routes/upload/page.tsx`:

```tsx title="routes/upload/page.tsx"
import { post } from '@api/upload';
import React, { type JSX } from 'react';

export default (): JSX.Element => {
  const [file, setFile] = React.useState<FileList | null>();

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFile(e.target.files);
  };

  const handleSubmit = async (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    const formData = new FormData();
    if (file) {
      for (let i = 0; i < file.length; i++) {
        formData.append('images', file[i]);
      }
      post({
        formData,
      });
    }
  };

  return (
    <div>
      <input multiple type="file" onChange={handleChange} />
      <button onClick={handleSubmit}>upload</button>
    </div>
  );
};
```

:::tip
Note: The input parameter type must be `{ formData: FormData }` for the upload to succeed.
:::

### Manual Calling

You can manually upload files using the `fetch API`, when calling `fetch`, set the `body` as `FormData` type and submit a post request.

```tsx title="routes/upload/page.tsx"
import React from 'react';

export default (): JSX.Element => {
  const [file, setFile] = React.useState<FileList | null>();

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFile(e.target.files);
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData();
    if (file) {
      for (let i = 0; i < file.length; i++) {
        formData.append('images', file[i]);
      }
      await fetch('/api/upload', {
        method: 'POST',
        body: formData,
      });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input multiple type="file" onChange={handleChange} />
      <button type="submit">upload</button>
    </form>
  );
};
```
