Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 55 additions & 193 deletions docs/developer-docs/latest/plugins/upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,50 @@ canonicalUrl: https://docs.strapi.io/developer-docs/latest/plugins/upload.html

# Upload
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: should we mention in the TOC something like "Upload (Media Library)"? Just to make sure that when users scroll down the TOC to look for a Media Library documentation, they know that this is the right file? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea to me :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this isn't Media Library documentation - where that is a component of the admin panel it is properly documented in the User Guide, which is where users would/should look for such content. If they are in the Developer docs, the naming should reflect what exists in code, hence upload plugin.


The `Upload` plugin is used to implement the Media Library available in the admin panel. With it you can upload any kind of file on your server or external providers such as **AWS S3**.
The Upload plugin is the backend powering the [Media Library](../../../user-docs/latest/media-library/introduction-to-media-library.md) plugin available by default in the Strapi admin panel. Using either the Media Library from the admin panel or the upload API directly, you can upload any kind of file for use in your Strapi application.

By default Strapi provides a [provider](../development/using-providers.md) that uploads files to a local directory. Additional providers are available should you want to upload your files to another location.

The providers maintained by Strapi include:

- [Amazon S3](https://www.npmjs.com/package/@strapi/provider-upload-aws-s3)
- [Cloudinary](https://www.npmjs.com/package/@strapi/provider-upload-cloudinary)
- [Local](https://www.npmjs.com/package/@strapi/provider-upload-local)
- [Rackspace](https://www.npmjs.com/package/@strapi/provider-upload-rackspace)

## Configuration

Currently the Strapi middleware in charge of parsing requests needs to be configured to support file sizes larger than the default of **200MB**.
This section details configuration options for the default upload provider. If using another provider (e.g. AWS S3 or Rackspace), see the available configuration parameters in that provider's documentation.

### Local server

By default Strapi accepts `localServer` configurations for locally uploaded files. These will be passed as the options for [koa-static](https://github.com/koajs/static).

You can provide them by creating or editing the `./config/plugins.js` file. The following example sets the `max-age` header.

```js
// path: ./config/plugins.js

module.exports = ({ env })=>({
upload: {
config: {
providerOptions: {
localServer: {
maxage: 300000
},
},
},
},
});
```

### Max file size

Currently the Strapi middleware in charge of parsing requests needs to be configured to support file sizes larger than the default of 200MB.

The library we use is [`koa-body`](https://github.com/dlau/koa-body), and it uses the [`node-formidable`](https://github.com/felixge/node-formidable) library to process files.

You can pass configuration to the middleware directly by setting it in the `body` middleware configuration in `./config/middlewares.js`:
You can pass configuration to the middleware directly by setting it in the [`body` middleware](/developer-docs/latest/setup-deployment-guides/configurations/required/middlewares.md#internal-middlewares-configuration-reference) configuration in `./config/middlewares.js`:

```js
// path: ./config/middlewares.js
Expand All @@ -36,7 +71,7 @@ module.exports = {
};
```

### Responsive Images
### Responsive images

When the `Enable responsive friendly upload` setting is enabled in the settings panel the plugin will generate the following responsive image sizes:
| Name | Largest Dimension |
Expand Down Expand Up @@ -105,11 +140,13 @@ module.exports = ({ env }) => ({

</div>

## Upload files
## Examples
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would review that whole "Examples" section to be honest. I don't think the content is just examples, all those configuration options for files imported via the Media Library should be integrated/explained properly in the Upload plugin documentation. Happy to discuss that with you!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. Happy to join the discussion if you need me 🤗


### Upload files

To upload files to your application.
Upload one or more files to your application.

### Parameters
The following parameters are accepted:

- `files`: The file(s) to upload. The value(s) can be a Buffer or Stream.

Expand Down Expand Up @@ -166,11 +203,11 @@ const response = await fetch('http://localhost:1337/api/upload', {
You have to send FormData in your request body.
:::

## Upload files related to an entry
### Upload entry files

To upload files that will be linked to a specific entry.
Upload one or more files that will be linked to a specific entry.

### Request parameters
The following parameters are accepted:

- `files`: The file(s) to upload. The value(s) can be a Buffer or Stream.
- `path` (optional): The folder where the file(s) will be uploaded to (only supported on strapi-provider-upload-aws-s3).
Expand All @@ -179,9 +216,7 @@ To upload files that will be linked to a specific entry.
- `source` (optional): The name of the plugin where the model is located.
- `field`: The field of the entry which the file(s) will be precisely linked to.

### Examples

The `Restaurant` model attributes:
For example, given the `Restaurant` model attributes:

```json
// path: ./src/api/restaurant/content-types/restaurant/schema.json
Expand All @@ -201,7 +236,7 @@ The `Restaurant` model attributes:
}
```

Code
The corresponding code would be:

```html
<form>
Expand Down Expand Up @@ -231,13 +266,11 @@ Code
You have to send FormData in your request body.
:::

## Upload file during entry creation
### Upload files at entry creation

You can also add files during your entry creation.

### Examples

The `Restaurant` model attributes:
For example, given the `Restaurant` model attributes:

```json
// path: ./src/api/restaurant/content-types/restaurant/schema.json
Expand All @@ -255,10 +288,9 @@ The `Restaurant` model attributes:
}
// ...
}

```

Code
The corresponding code would be:

```html
<form>
Expand Down Expand Up @@ -298,18 +330,17 @@ Code
</script>
```

Your entry data has to be contained in a `data` key and you need to `JSON.stringify` this object. The keys for files, need to be prefixed with `files` (example with a cover attribute: `files.cover`).
Your entry data has to be contained in a `data` key and you need to `JSON.stringify` this object. The keys for files need to be prefixed with `files` (e.g. for a cover attribute: `files.cover`).

::: tip
If you want to upload files for a component, you will have to specify the index of the item you want to add the file to.
Example `files.my_component_name[the_index].attribute_name`
If you want to upload files for a component, you will have to specify the index of the item you want to add the file to: `files.my_component_name[the_index].attribute_name`
:::

:::caution
You have to send FormData in your request body.
:::

## Models definition
### Models definition

Adding a file attribute to a model (or the model of another plugin) is like adding a new association.

Expand Down Expand Up @@ -364,172 +395,3 @@ In our second example, you can upload and attach multiple pictures to the restau
// ...
}
```

## Using a provider

By default Strapi provides a provider that uploads files to a local directory. You might want to upload your files to another provider like AWS S3.

Below are the providers maintained by the Strapi team:

- [Amazon S3](https://www.npmjs.com/package/@strapi/provider-upload-aws-s3)
- [Cloudinary](https://www.npmjs.com/package/@strapi/provider-upload-cloudinary)
- [Local](https://www.npmjs.com/package/@strapi/provider-upload-local)
- [Rackspace](https://www.npmjs.com/package/@strapi/provider-upload-rackspace)

You can also find additional community maintained providers on [NPM](https://www.npmjs.com/).

To install a new provider run:

<code-group>

<code-block title="NPM">
```sh
npm install @strapi/provider-upload-aws-s3 --save
```
</code-block>

<code-block title="YARN">
```sh
yarn add @strapi/provider-upload-aws-s3
```
</code-block>

</code-group>

### Local server

By default Strapi accepts `localServer` configurations for locally uploaded files. They will be passed as the options for [koa-static](https://github.com/koajs/static).

You can provide them by create or edit the file at `./config/plugins.js`. The example below set `max-age` header.

```js
// path: ./config/plugins.js

module.exports = ({ env })=>({
upload: {
config: {
providerOptions: {
localServer: {
maxage: 300000
},
},
},
},
});
```

### Enabling the provider

To enable the provider, create or edit the file at `./config/plugins.js`

::: note
When using community providers, pass the full package name to the `provider` key (e.g. `provider: 'strapi-provider-upload-google-cloud-storage'`). Only Strapi-maintained providers can use the shortcode format (e.g. `provider: 'aws-s3'`).
:::

```js
// path: ./config/plugins.js

module.exports = ({ env }) => ({
// ...
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_ACCESS_SECRET'),
region: env('AWS_REGION'),
params: {
Bucket: env('AWS_BUCKET'),
},
},
},
},
// ...
});
```

Make sure to read the provider's `README` to know what are the possible parameters.

:::caution
Strapi has a default Security Middleware that has a very strict `contentSecurityPolicy` that limits loading images and media to `"'self'"` only, see the example configuration on the provider page or take a look at our [middleware documentation](/developer-docs/latest/setup-deployment-guides/configurations/required/middlewares.md#loading-order) for more information.
:::

### Configuration per environment

When configuring your upload provider you might want to change the configuration based on the `NODE_ENV` environment variable or use environment specific credentials.

You can set a specific configuration in the `./config/env/{env}/plugins.js` configuration file and it will be used to overwrite the one in the default configuration.

## Create providers

You can create a Node.js module to implement a custom provider. Read the official documentation [here](https://docs.npmjs.com/creating-node-js-modules).

Your provider needs to export the following interface:

```js
module.exports = {
init(providerOptions) {
// init your provider if necessary

return {
upload(file) {
// upload the file in the provider
// file content is accessible by `file.buffer`
},
uploadStream(file) {
// upload the file in the provider
// file content is accessible by `file.stream`
},
delete(file) {
// delete the file in the provider
},
};
},
};
```

:::tip
For performance reasons, the upload plugin will only use the `uploadStream` function if it exists, otherwise it will fallback on the `upload` function.
:::

You can then publish it to make it available to the community.

### Create a local provider

If you want to create your own provider without publishing it on **npm** you can follow these steps:

1. Create a `./providers/upload-{provider-name}` folder in your root application folder.
2. Create your provider as explained in the [documentation](#create-providers) above.
3. Update your `package.json` to link your `upload-{provider-name}` dependency to point to the [local path](https://docs.npmjs.com/files/package.json#local-paths) of your provider:

```json
// path: ./package.json

{
...
"dependencies": {
...
"@strapi/provider-upload-{provider-name}": "file:providers/upload-{provider-name}"
...
}
}
```

4. Update the Upload plugin configuration:

```js
// path: ./config/plugins.js

module.exports = ({ env }) => ({
// ...
upload: {
config: {
provider: '{provider-name}',
providerOptions: {},
},
},
// ...
});
```

5. Run `yarn install` or `npm install` to install your new custom provider.