Storage

Storage Image Transformations

Transform images with Storage

Supabase Storage offers the functionality to optimize and resize images on the fly. Any image stored in your buckets can be transformed and optimized for fast delivery.

Get a public URL for a transformed image

Our client libraries methods like getPublicUrl and createSignedUrl support the transform option. This returns the URL that serves the transformed image.


_10
supabase.storage.from('bucket').getPublicUrl('image.jpg', {
_10
transform: {
_10
width: 500,
_10
height: 600,
_10
},
_10
})

An example URL could look like this:

https://project_id.supabase.co/storage/v1/render/image/public/bucket/image.jpg?width=500&height=600

Signing URLs with transformation options

To share a transformed image in a private bucket for a fixed amount of time, provide the transform option when you create the signed URL:


_10
supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, {
_10
transform: {
_10
width: 200,
_10
height: 200,
_10
},
_10
})

The transformation options are embedded into the token attached to the URL — they cannot be changed once signed.

Downloading images

To download a transformed image, pass the transform option to the download function.


_10
supabase.storage.from('bucket').download('image.jpg', {
_10
transform: {
_10
width: 800,
_10
height: 300,
_10
},
_10
})

Automatic image optimization (WebP)

When using the image transformation API, Storage will automatically find the best format supported by the client and return that to the client, without any code change. For instance, if you use Chrome when viewing a jpeg image and using transformation options, you'll see that images are automatically optimized as webp images.

As a result, this will lower the bandwidth that you send to your users and your application will load much faster.

Disabling automatic optimization:

In case you'd like to return the original format of the image and opt-out from the automatic image optimization detection, you can pass the format=origin parameter when requesting a transformed image, this is also supported in the JavaScript SDK starting from v2.2.0


_10
await supabase.storage.from('bucket').download('image.jpeg', {
_10
transform: {
_10
width: 200,
_10
height: 200,
_10
format: 'origin',
_10
},
_10
})

Next.js loader

You can use Supabase Image Transformation to optimize your Next.js images using a custom Loader.

To get started, create a supabase-image-loader.js file in your Next.js project which exports a default function:


_10
const projectId = '' // your supabase project id
_10
_10
export default function supabaseLoader({ src, width, quality }) {
_10
return `https://${projectId}.supabase.co/storage/v1/render/image/public/${src}?width=${width}&quality=${quality || 75}`
_10
}

In your nextjs.config.js file add the following configuration to instruct Next.js to use our custom loader


_10
module.exports = {
_10
images: {
_10
loader: 'custom',
_10
loaderFile: './supabase-image-loader.js',
_10
},
_10
}

At this point you are ready to use the Image component provided by Next.js


_10
import Image from 'next/image'
_10
_10
const MyImage = (props) => {
_10
return <Image src="bucket/image.png" alt="Picture of the author" width={500} height={500} />
_10
}

Transformation options

We currently support a few transformation options focusing on optimizing, resizing, and cropping images.

Optimizing

You can set the quality of the returned image by passing a value from 20 to 100 (with 100 being the highest quality) to the quality parameter. This parameter defaults to 80.

Example:


_10
supabase.storage.from('bucket').download('image.jpg', {
_10
transform: {
_10
quality: 50,
_10
},
_10
})

Resizing

You can use width and height parameters to resize an image to a specific dimension. If only one parameter is specified, the image will be resized and cropped, maintaining the aspect ratio.

Modes

You can use different resizing modes to fit your needs, each of them uses a different approach to resize the image:

Use the resize parameter with one of the following values:

  • cover : resizes the image while keeping the aspect ratio to fill a given size and crops projecting parts. (default)

  • contain : resizes the image while keeping the aspect ratio to fit a given size.

  • fill : resizes the image without keeping the aspect ratio.

Example:


_10
supabase.storage.from('bucket').download('image.jpg', {
_10
transform: {
_10
width: 800,
_10
height: 300,
_10
resize: 'contain', // 'cover' | 'fill'
_10
},
_10
})

Limits

  • Width and height must be an integer value between 1-2500.
  • The image size cannot exceed 25MB.
  • The image resolution cannot exceed 50MP.

Supported image formats

FormatExtensionSourceResult
PNGpng☑️☑️
JPEGjpg☑️☑️
WebPwebp☑️☑️
AVIFavif☑️☑️
GIFgif☑️☑️
ICOico☑️☑️
SVGsvg☑️☑️
HEICheic☑️
BMPbmp☑️☑️
TIFFtiff☑️☑️

Self hosting

Our solution to image resizing and optimization can be self-hosted as with any other Supabase product. Under the hood we use Imgproxy

Imgproxy configuration:

Simply deploy an imgproxy container with the following configuration:


_10
imgproxy:
_10
image: darthsim/imgproxy
_10
environment:
_10
- IMGPROXY_ENABLE_WEBP_DETECTION=true
_10
- IMGPROXY_JPEG_PROGRESSIVE=true

Note: make sure that this service can only be reachable within an internal network and not exposed to the public internet

Storage API configuration:

Once Imgproxy is deployed we need to configure a couple of environment variables in your self-hosted storage-api service as follows:


_10
ENABLE_IMAGE_TRANSFORMATION=true
_10
IMGPROXY_URL=yourinternalimgproxyurl.internal.com