# Upload
Thanks to the plugin Upload
, you can upload any kind of file on your server or external providers such as AWS S3.
# Configuration
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
(opens new window), and it uses the node-formidable
(opens new window) library to process files.
You can pass configuration to the middleware directly by setting it in the body
middleware configuration in ./config/middleware.js
:
// path: ./config/middlewares.js
module.exports = {
// ...
{
name: "strapi::body",
config: {
formLimit: "256mb", // modify form body
jsonLimit: "256mb", // modify JSON body
textLimit: "256mb", // modify text body
formidable: {
maxFileSize: 200 * 1024 * 1024, // multipart data, modify here limit of uploaded file size
},
},
},
// ...
};
# 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 |
---|---|
large | 1000px |
medium | 750px |
small | 500px |
These sizes can be overridden in ./config/plugins.js
:
// path: ./config/plugins.js
module.exports = ({ env }) => ({
upload: {
config: {
breakpoints: {
xlarge: 1920,
large: 1000,
medium: 750,
small: 500,
xsmall: 64
},
},
},
});
✋ CAUTION
Breakpoint changes will only apply to new images, existing images will not be resized or have new sizes generated.
# Endpoints
Method | Path | Description |
---|---|---|
GET | /api/upload/files | Get a list of files |
GET | /api/upload/files/:id | Get a specific file |
POST | /api/upload | Upload files |
DELETE | /api/upload/files/:id | Delete a file |
# Upload files
To upload files into your application.
# Parameters
files
: The file(s) to upload. The value(s) can be a Buffer or Stream.
# Code example
<form>
<!-- Can be multiple files -->
<input type="file" name="files" />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const formElement = document.querySelector('form');
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const request = new XMLHttpRequest();
request.open('POST', '/upload');
request.send(new FormData(formElement));
});
</script>
✋ CAUTION
You have to send FormData in your request body.
# Upload files related to an entry
To upload files that will be linked to a specific entry.
# Request parameters
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).refId
: The ID of the entry which the file(s) will be linked to.ref
: The name of the model which the file(s) will be linked to (see more below).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:
// path: ./src/api/restaurant/content-types/restaurant/schema.json
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false,
}
}
// ...
}
Code
<form>
<!-- Can be multiple files if you setup "collection" instead of "model" -->
<input type="file" name="files" />
<input type="text" name="ref" value="restaurant" />
<input type="text" name="refId" value="5c126648c7415f0c0ef1bccd" />
<input type="text" name="field" value="cover" />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const formElement = document.querySelector('form');
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const request = new XMLHttpRequest();
request.open('POST', '/upload');
request.send(new FormData(formElement));
});
</script>
✋ CAUTION
You have to send FormData in your request body.
# Upload file during entry creation
You can also add files during your entry creation.
# Examples
The Restaurant
model attributes:
// path: ./src/api/restaurant/content-types/restaurant/schema.json
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false,
}
}
// ...
}
Code
<form>
<!-- Can be multiple files if you setup "collection" instead of "model" -->
<input type="text" name="name" />
<input type="file" name="cover" />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const formElement = document.querySelector('form');
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const request = new XMLHttpRequest();
const formData = new FormData();
const formElements = formElement.elements;
const data = {};
for (let i = 0; i < formElements.length; i++) {
const currentElement = formElements[i];
if (!['submit', 'file'].includes(currentElement.type)) {
data[currentElement.name] = currentElement.value;
} else if (currentElement.type === 'file') {
for (let i = 0; i < currentElement.files.length; i++) {
const file = currentElement.files[i];
formData.append(`files.${currentElement.name}`, file, file.name);
}
}
}
formData.append('data', JSON.stringify(data));
request.open('POST', `${HOST}/restaurants`);
request.send(formData);
});
</script>
Your entry data has to be contained in a data
key. You have to JSON.stringify
your data object.
And for your files, they have to be prefixed by files
.
Example here with 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
✋ CAUTION
You have to send FormData in your request body.
# Models definition
Adding a file attribute to a model (or the model of another plugin) is like adding a new association.
In the first example below, you will be able to upload and attach one file to the avatar attribute.
// path: ./src/api/restaurant/content-types/restaurant/schema.json
{
// ...
{
"attributes": {
"pseudo": {
"type": "string",
"required": true
},
"email": {
"type": "email",
"required": true,
"unique": true
},
"avatar": {
"type": "media",
"multiple": false,
}
}
}
// ...
}
In our second example, you can upload and attach multiple pictures to the restaurant.
// path: ./src/api/restaurant/content-types/restaurant/schema.json
{
// ...
{
"attributes": {
"name": {
"type": "string",
"required": true
},
"covers": {
"type": "media",
"multiple": true,
}
}
}
// ...
}
# 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 (opens new window)
- Cloudinary (opens new window)
- Local (opens new window)
- Rackspace (opens new window)
You can also find additional community maintained providers on NPM (opens new window).
To install a new provider run:
# Local server
By default Strapi accepts localServer
configurations for locally uploaded files. They will be passed as the options for koa-static (opens new window).
You can provide them by create or edit the file at ./config/plugins.js
. The example below set max-age
header.
//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
💡 TIP
When using community providers, you need to pass the full package name to the provider
key, only Strapi maintained providers can use the short-code eg: provider: 'strapi-provider-upload-google-cloud-storage'
//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 middleare documentation 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 (opens new window).
Your provider need to export the following interface:
module.exports = {
init(providerOptions) {
// init your provider if necessary
return {
upload(file) {
// upload the file in the provider
},
delete(file) {
// delete the file in the provider
},
};
},
};
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:
- Create a
./providers/strapi-provider-upload-{provider-name}
folder in your root application folder. - Create your provider as explained in the documentation above.
- Then update your
package.json
to link yourstrapi-provider-upload-{provider-name}
dependency to point to the local path (opens new window) of your provider.
//path: ./package.json
{
...
"dependencies": {
...
"strapi-provider-upload-{provider-name}": "file:providers/strapi-provider-upload-{provider-name}"
...
}
}
- Finally, run
yarn install
ornpm install
to install your new custom provider.