Skip to content

Strapi Media Upload — Admin Upload, Allowed Types, and Size Limits

DodaTech Updated 2026-06-28 8 min read

In this tutorial, you will learn how to handle media uploads in Strapi — from uploading images through the admin panel and API, to configuring allowed file types, size limits, and organizing files in the Media Library.

What You'll Learn

  • How to upload files through the admin panel Media Library
  • How to upload files programmatically through the API
  • How to configure allowed file types and size limits
  • How to organize files with folders
  • How files are stored and referenced in content entries
  • How to handle file validation errors

Why It Matters

Media files are central to most content management systems. Articles need images, products need photos, user profiles need avatars. Understanding how Strapi handles uploads ensures your media is stored securely, organized logically, and accessible through the API in a predictable way.

Real-World Use

A recipe site stores thousands of food photos. Authors upload images through a form in the frontend. The images are validated (JPEG/PNG only, max 5MB), stored in folders organized by recipe ID, and automatically referenced in the recipe content entry. The frontend displays the images using Strapi's API URLs.

Learning Path

flowchart LR
  A["Advanced Auth"] --> B["Media Upload
-- You are here"]:::current B --> C["Upload Providers"] C --> D["Image Optimization"] D --> E["File Management"] classDef current fill:#4945ff,color:#fff,stroke-width:2px

Admin Panel Upload

The Media Library in the admin panel provides a user-friendly interface for uploading files.

Media Library
-- Upload button
--   Select files from computer
--   Or drag and drop files
-- Files appear in the grid after upload
-- Click a file to view details and edit metadata

To upload from the admin panel:

  1. Go to Media Library in the left sidebar
  2. Click the "Upload" button
  3. Select files from your computer or drag them into the upload area
  4. Files are uploaded and appear in the grid

After uploading, you can:

  • View file details (name, URL, dimensions, size, MIME type)
  • Edit the file name and alternative text
  • Replace the file with a new version
  • Move the file to a folder
  • Copy the file URL for use in content

API Upload

Upload files programmatically through the upload API:

// POST /api/upload
// Content-Type: multipart/form-data
// Body: FormData with file(s)

// Frontend upload example:
async function uploadImage(file) {
  const jwt = localStorage.getItem("strapi_jwt");
  const formData = new FormData();
  formData.append("files", file);

  const response = await fetch("http://localhost:1337/api/upload", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${jwt}`,
    },
    body: formData,
  });

  const uploadedFiles = await response.json();
  // Returns array of uploaded file objects
  return uploadedFiles;
}

// Response:
[
  {
    "id": 1,
    "name": "pizza.jpg",
    "alternativeText": null,
    "caption": null,
    "width": 1920,
    "height": 1080,
    "formats": {
      "thumbnail": { "url": "/uploads/thumbnail_pizza.jpg", ... },
      "small": { "url": "/uploads/small_pizza.jpg", ... },
      "medium": { "url": "/uploads/medium_pizza.jpg", ... }
    },
    "hash": "pizza_c4d3f2b1e5",
    "ext": ".jpg",
    "mime": "image/jpeg",
    "size": 2048576,
    "url": "/uploads/pizza_c4d3f2b1e5.jpg",
    "provider": "local"
  }
]

The upload response includes the file's ID, which you can use to associate the file with a content entry.

Associating Files with Content

Media fields on content types store a reference to uploaded files. You can upload a file and immediately associate it with a content entry.

// Upload and assign to an article in one request:
// POST /api/upload
// FormData:
//   files: [the image file]
//   data: JSON.stringify({
//     ref: "api::article.article",
//     refId: 1,
//     field: "cover_image"
//   })

// Or upload first, then associate:
// Step 1: Upload file, get file ID
const [uploadedFile] = await uploadImage(file);
const fileId = uploadedFile.id;

// Step 2: Update the article with the file ID
await fetch("http://localhost:1337/api/articles/1", {
  method: "PUT",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${jwt}`,
  },
  body: JSON.stringify({
    data: {
      cover_image: fileId,
    },
  }),
});

Configuring Allowed Types

Restrict which file types users can upload:

// config/plugins.js
module.exports = {
  upload: {
    config: {
      sizeLimit: 5 * 1024 * 1024,  // 5MB in bytes
      breakpoints: {
        large: 1000,
        medium: 750,
        small: 500,
      },
    },
  },
};

For more granular control, configure allowed MIME types:

// src/extensions/upload/config.js
module.exports = {
  // Only allow images and PDFs
  allowedTypes: ["image/jpeg", "image/png", "image/webp", "application/pdf"],

  // Or use categories
  allowedTypes: ["images", "files"],  // videos and audios excluded
};

The MIME type restriction applies to both admin panel and API uploads. Invalid file types return a 400 error.

Size Limits

Control upload size limits at multiple levels:

// 1. Strapi upload plugin configuration
// config/plugins.js
module.exports = {
  upload: {
    config: {
      sizeLimit: 10 * 1024 * 1024,  // 10MB
    },
  },
};

// 2. Server-level limit (Koa body parser)
// config/middlewares.js
{
  name: "strapi::body",
  config: {
    multipart: true,
    includeUnparsed: true,
    formLimit: "56kb",
    jsonLimit: "1mb",
    textLimit: "1mb",
    formidable: {
      maxFileSize: 10 * 1024 * 1024,  // 10MB
    },
  },
}

// 3. Reverse proxy level (nginx, Cloudflare)
// nginx config:
// client_max_body_size 10M;

The most restrictive limit wins. If Strapi allows 10MB but nginx allows 5MB, uploads over 5MB are rejected by nginx.

File Validation

Strapi validates uploaded files against the content type's field configuration:

// Media field configuration in Content-Type Builder
{
  "type": "media",
  "allowedTypes": ["images"],  // Only images allowed
  "multiple": false            // Single file, not gallery
}

// Multiple: true — allows multiple files
// Multiple: false — allows one file per field
// allowedTypes options:
//   "images" — JPEG, PNG, WebP, GIF, SVG, AVIF
//   "files" — PDF, DOC, XLS, ZIP, TXT
//   "videos" — MP4, MOV, AVI, WebM
//   "audios" — MP3, WAV, OGG, AAC

Folder Organization

Organize files with folders in the Media Library:

// Create folders via admin panel:
// Media Library > Add New Folder
// Structure:
//   /images
//     /articles
//     /authors
//     /categories
//   /documents
//   /videos

// Upload directly to a folder via API:
const formData = new FormData();
formData.append("files", file);
formData.append("folder", 5);  // Folder ID

await fetch("http://localhost:1337/api/upload", {
  method: "POST",
  headers: { Authorization: `Bearer ${jwt}` },
  body: formData,
});

Organizing files in folders from the start prevents the Media Library from becoming an unmanageable mess as you accumulate thousands of files.

Common Mistakes

  1. Uploading files without size limits. Without size limits, users can upload multi-GB files that exhaust server disk space and cause upload timeouts. Always set reasonable size limits.

  2. Not validating file types on the client side. Server-side validation is essential, but client-side validation improves user experience. Validate file types and sizes before sending the upload request.

  3. Using local storage in production without backup. Strapi's default local upload provider stores files on the server's filesystem. If the server is replaced or the disk fails, all uploads are lost. Use cloud storage providers in production.

  4. Uploading files without associating them with content. Uploaded files that are not linked to any content entry become orphaned. They take up storage space but are never displayed.

  5. Not setting alternative text on images. Accessibility requires alt text on images. Make alternative text a required field in your media field configuration.

Practice Questions

  1. What is the API endpoint for uploading a file to Strapi? Answer: POST /api/upload with Content-Type: multipart/form-data and the file in the files field of the FormData.

  2. How do you restrict uploads to only image files? Answer: In the Content-Type Builder, set the media field's allowedTypes to ["images"]. You can also configure the upload plugin to restrict by MIME types.

  3. What happens if you upload a file larger than the configured size limit? Answer: Strapi returns a 400 error with a message indicating the file exceeds the maximum allowed size. The file is not saved.

  4. Challenge: Build a complete image upload system: (1) Configure Strapi with a 10MB size limit and image-only MIME types, (2) Create a frontend upload form with drag-and-drop that validates file type and size before uploading, (3) Upload the file and associate it with a specific content entry, (4) Display the uploaded image on a page, (5) Implement folder organization: upload article images to /images/articles and author images to /images/authors.

FAQ

What is the default maximum upload size in Strapi?

The default maximum upload size is 1 GB, configured in the upload plugin's sizeLimit setting. However, server-level limits (Koa body parser, reverse proxy) may be more restrictive.

Can users upload files without authentication?

By default, file upload requires authentication. You can enable public upload by giving the Public role permission to use the upload controller. This is not recommended for production.

How are uploaded files named?

Strapi generates a unique hash-based filename for each upload to prevent name collisions. The original filename is stored in the database but the actual file uses the hash (e.g., pizza_c4d3f2b1e5.jpg).

Can I upload files through the GraphQL API?

Yes, Strapi's GraphQL plugin supports file upload through the Upload scalar type. You send a multipart request with the query and the file. The REST upload endpoint is more straightforward for most use cases.

How do I delete unused uploaded files?

Strapi does not automatically delete orphaned files. You can use the Media Library to manually delete files, or create a custom script that finds files not referenced by any content entry and deletes them.

Mini Project

Your task: Build a complete media management workflow.

  1. Configure upload settings: 5MB max size, allow images only (JPEG, PNG, WebP).
  2. Create folder structure in the Media Library: images/products/, images/blog/, documents/.
  3. Create a content type "Product" with fields: name, description, price, and a media field "photos" (multiple images allowed).
  4. Write a frontend upload form that:
    • Validates file type and size before uploading
    • Uploads files to the API
    • Associates uploaded files with a new product
    • Displays the uploaded images
  5. Test with valid files (should succeed) and invalid files (wrong type, too large — should fail with clear error messages).

What's Next

Now that you understand media upload, proceed to Upload Providers to learn how to configure cloud storage with Amazon S3, Cloudinary, and Cloudflare R2 instead of the default local filesystem storage. After that, explore Image Optimization for responsive images and compression.

Related lessons:

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro