By Ali Shaikh
Azure Blob Storage provider for Strapi with clean URLs
released August 25, 2025
npm install strapi-provider-upload-azure-cleanAzure Blob Storage provider for Strapi with smart URL handling - clean URLs for public containers, authenticated URLs for private containers.
npm install strapi-provider-upload-azure-clean| Option | Type | Required | Default | Description |
|---|---|---|---|---|
account | string | Yes | Your Azure storage account name | |
accountKey | string | Conditional | Your Azure storage account key. Required if sasToken is not provided | |
sasToken | string | Conditional | Shared Access Signature token for your storage account. Required if accountKey is not provided | |
containerName | string | Yes | The name of the Blob container where files will be stored | |
defaultPath | string | No | 'uploads' | The default path inside the container where files will be uploaded |
cdnBaseURL | string | No | If you're using a CDN or custom domain, specify the base URL here | |
serviceBaseURL | string | No | Custom base URL for the Azure Blob service (e.g., if using a sovereign cloud) | |
defaultCacheControl | string | No | Set the Cache-Control header for uploaded files | |
removeCN | string | No | Set to 'true' to remove the container name from the file URL | |
publicContainer | string | No | Set to 'true' for public containers with clean URLs |
Create or update the config/plugins.js or config/plugins.ts file in your Strapi project:
// config/plugins.js
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'strapi-provider-upload-azure-clean',
providerOptions: {
account: env('AZURE_ACCOUNT_NAME'),
accountKey: env('AZURE_ACCOUNT_KEY'),
sasToken: env('AZURE_SAS_TOKEN'),
containerName: env('AZURE_CONTAINER_NAME'),
defaultPath: env('AZURE_DEFAULT_PATH', 'uploads'),
cdnBaseURL: env('AZURE_CDN_BASE_URL'),
serviceBaseURL: env('AZURE_SERVICE_BASE_URL'),
defaultCacheControl: env('AZURE_DEFAULT_CACHE_CONTROL'),
removeCN: env('AZURE_REMOVE_CN'),
publicContainer: env('AZURE_PUBLIC_CONTAINER'),
},
},
},
});Create or update your .env file at the root of your Strapi project:
# Azure Storage Account Credentials
AZURE_ACCOUNT_NAME=your_account_name
AZURE_ACCOUNT_KEY=your_account_key
# Optional: SAS Token (if not using account key)
AZURE_SAS_TOKEN=your_sas_token
# Azure Blob Storage Configuration
AZURE_CONTAINER_NAME=your_container_name
AZURE_DEFAULT_PATH=uploads
# Optional: CDN Base URL
AZURE_CDN_BASE_URL=https://cdn.yourdomain.com
# Optional: Custom Service Base URL
AZURE_SERVICE_BASE_URL=https://your_custom_service_base_url
# Optional: Cache Control Header
AZURE_DEFAULT_CACHE_CONTROL=public, max-age=31536000, immutable
# Optional: Remove Container Name from URL
AZURE_REMOVE_CN=true
# Optional: Public Container (for clean URLs)
AZURE_PUBLIC_CONTAINER=trueDue to the default settings in the Strapi Security Middleware, you need to modify the contentSecurityPolicy settings to properly see thumbnail previews in the Media Library. Replace the "strapi::security" string with the object below, as explained in the middleware configuration documentation.
To allow the Azure storage content to be displayed, edit the file at ./config/middlewares.js. Replace the "strapi::security" string with the following object:
// ./config/middlewares.js
module.exports = [
// ...
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"connect-src": ["'self'", "https:"],
"img-src": [
"'self'",
"data:",
"blob:",
"dl.airtable.com", // Required for Strapi < 4.10.6; you can remove it otherwise
"https://market-assets.strapi.io", // Required for Strapi >= 4.10.6; you can remove it otherwise
/**
* Note: If using a STORAGE_URL, replace `https://${process.env.AZURE_ACCOUNT_NAME}.blob.core.windows.net` with `process.env.STORAGE_URL`.
* If using a CDN URL, make sure to include that URL in the CSP headers, e.g., `process.env.AZURE_CDN_BASE_URL`.
*/
`https://${process.env.AZURE_ACCOUNT_NAME}.blob.core.windows.net`,
],
"media-src": [
"'self'",
"data:",
"blob:",
"dl.airtable.com", // Required for Strapi < 4.10.6; you can remove it otherwise
/**
* Note: If using a STORAGE_URL, replace `https://${process.env.AZURE_ACCOUNT_NAME}.blob.core.windows.net` with `process.env.STORAGE_URL`.
* If using a CDN URL, make sure to include that URL in the CSP headers, e.g., `process.env.AZURE_CDN_BASE_URL`.
*/
`https://${process.env.AZURE_ACCOUNT_NAME}.blob.core.windows.net`,
],
upgradeInsecureRequests: null,
},
},
},
},
// ...
];serviceBaseURL (optional): Useful when connecting to Azure Storage API compatible services, like the official emulator Azurite. The serviceBaseURL would then look like http://localhost:10000/your-storage-account-name. When serviceBaseURL is not provided, the default https://${account}.blob.core.windows.net will be used.
cdnBaseURL (optional): Useful when using a CDN in front of your storage account. Images will be returned with the CDN URL instead of the storage account URL.
defaultCacheControl (optional): Useful when you want to allow clients to use a cached version of the file. Azure Storage will return this value in the Cache-Control HTTP header of the response.
removeCN (optional): Some Azure account configurations exclude the 'container name' from the URL where data is saved. By default, it's set to false. If you want to remove the container name from the URL, set it to 'true'.
publicContainer (optional): Set to 'true' for public containers to generate clean URLs without SAS token parameters.
// config/plugins.js
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'strapi-provider-upload-azure-clean',
providerOptions: {
account: 'mystorageaccount',
sasToken: 'sv=2022-11-02&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2024-12-31T23:59:59Z&st=2024-01-01T00:00:00Z&spr=https&sig=...',
containerName: 'uploads',
defaultPath: 'media',
},
},
},
});Result URLs (Private Container): https://mystorageaccount.blob.core.windows.net/uploads/media/image.jpg?sv=2022-11-02&ss=bfqt...
// config/plugins.js
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'strapi-provider-upload-azure-clean',
providerOptions: {
account: 'mystorageaccount',
sasToken: 'sv=2022-11-02&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2024-12-31T23:59:59Z&st=2024-01-01T00:00:00Z&spr=https&sig=...',
containerName: 'public-uploads',
publicContainer: 'true', // This enables clean URLs
defaultPath: 'images',
},
},
},
});Result URLs (Public Container): https://mystorageaccount.blob.core.windows.net/public-uploads/images/image.jpg
This provider intelligently handles URLs based on container privacy:
For Public Containers (publicContainer: 'true'):
https://account.blob.core.windows.net/container/file.jpgFor Private Containers (default):
https://account.blob.core.windows.net/container/file.jpg?sv=...&sr=...The provider uses authentication in this order:
publicContainer: 'true' → Anonymous accesssasToken provided → SAS token authenticationaccountKey provided → Account key authenticationBased on strapi-provider-upload-azure-sa by c1sar, with modifications to provide clean URLs without SAS token parameters.
MIT - See LICENSE file for details
Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.
Submit
