# File paths

By default this addon will give every upload a unique key in your S3 bucket. If you would like to customize the key you can do so by configuring the API route.

```js
// pages/api/s3-upload.js
import { APIRoute } from "next-s3-upload";

export default APIRoute.configure({
  key(req, filename) {
    return `my/uploads/path/${filename}`;
  }
});
```

The key function can return a promise if you need to do something async.

```js
// pages/api/s3-upload.js
import { APIRoute } from "next-s3-upload";

export default APIRoute.configure({
  async key(req, filename) {
    let path = await getPath();
    return `${path}/${filename}`;
  }
});
```

## File names

The [AWS guidelines](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html) recommend using a specific subset of characters for key names. This library has a `sanitizeKey()` function to remove any characters that could cause problems when stored on S3.

```js
// pages/api/s3-upload.js
import { APIRoute, sanitizeKey } from "next-s3-upload";

export default APIRoute.configure({
  key(req, filename) {
    return `safe-file-name/${sanitizeKey(filename)}`;
  }
});
```

This function is useful if you are accepting uploads for non-english filenames.

## File extensions

If you set up your IAM user to only upload [specific file extensions](https://next-s3-upload.codingvalue.com/setup#iam-user) then your key function must return a path ending with one of your allowed extensions.

If the key function returns a path that does not include an allowed extension then your upload will fail with an access denied error.

## Data from React

You can pass data from your React app to the key function using `uploadToS3` options.

In the example below, we pass a `projectId` from the frontend using the `endpoint.request.body` option.

```js
// Frontend component
function Component() {
  let { uploadToS3 } = useS3Upload();

  let handleSubmit = async () => {
    // You can pass extra data using `endpoint.request.body`

    await uploadToS3(file, {
      endpoint: {
        request: {
          body: {
            projectId: 123
          }
        }
      }
    });
  };
}
```

Now the key function can read the passed `projectId` from `req.body.projectId`.

```js
// pages/api/s3-upload.js
import { APIRoute } from "next-s3-upload";

export default APIRoute.configure({
  async key(req, filename) {
    let projectId = req.body.projectId; // 123

    return `projects/${projectId}/${filename}`;
  }
});
```

All data that needs to be passed from the frontend should be sent under the `endpoint.request.body` object, since that data will get serialized into the request's body.

You can pass any data you'd like here, as long as it's serializable into JSON.

## Headers

The `uploadToS3` function can also add request headers that can be used by the key function.

```js
// Frontend component
function Component() {
  let { user } = useAuth();
  let { uploadToS3 } = useS3Upload();

  let handleSubmit = async () => {
    let authToken = await user.getAuthToken();

    await uploadToS3(file, {
      endpoint: {
        request: {
          headers: {
            authorization: authToken
          }
        }
      }
    });
  };
}
```

And the authorization header can be read using `req.headers.authorization`.

```js
// pages/api/s3-upload.js
import { APIRoute } from "next-s3-upload";

export default APIRoute.configure({
  async key(req, filename) {
    let user = await getUserFromAuthToken(req.headers.authorization);

    return `users/${user.id}/${filename}`;
  }
});
```
