From b71fb0f12df7006ee233040e96f061636a2426b2 Mon Sep 17 00:00:00 2001 From: fenos Date: Tue, 6 Dec 2022 10:16:18 +0000 Subject: [PATCH 1/7] docs: image resizing guide --- .../Navigation/Navigation.constants.ts | 1 + .../pages/guides/storage-image-resizing.mdx | 136 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 apps/docs/pages/guides/storage-image-resizing.mdx diff --git a/apps/docs/components/Navigation/Navigation.constants.ts b/apps/docs/components/Navigation/Navigation.constants.ts index 3c407085da2..29212056fdb 100644 --- a/apps/docs/components/Navigation/Navigation.constants.ts +++ b/apps/docs/components/Navigation/Navigation.constants.ts @@ -246,6 +246,7 @@ export const menuItems: NavMenu = { items: [ { name: 'Overview', url: '/guides/storage', items: [] }, { name: 'CDN', url: '/guides/storage-cdn', items: [] }, + { name: 'Image Resizing', url: '/guides/storage-image-resizing', items: [] }, ], }, { diff --git a/apps/docs/pages/guides/storage-image-resizing.mdx b/apps/docs/pages/guides/storage-image-resizing.mdx new file mode 100644 index 00000000000..dc9cffb9aac --- /dev/null +++ b/apps/docs/pages/guides/storage-image-resizing.mdx @@ -0,0 +1,136 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'storage-image-resizing', + title: 'Storage Image Resizing', + description: 'Resize images with Storage', + sidebar_label: 'Image Transformation', +} + +Storage offers the functionality to transform and resize images on the fly. +Any image stored in your buckets can be transformed and optimized for fast delivery. + +To get started with image resizing you can pass a `transform` option to the functions you are currently using to interact with your objects. + +Image Resizing is enabled for PRO tiers and above + +### Get a public URL - With transformation options + +```ts +storage.from('bucket').getPublicUrl('image.jpg', { + transform: { + width: 500, + height: 600, + } +}) +``` + +This will return the public URL with the formatted transformation parameters. +Once visited you’ll be served with the resized image + +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 + +You can sign the URLs for private buckets in the same way. +If you are signing an image and you’d like to share a transformed version, you’ll need to provide the transform options to the signing URL function + +```ts +storage.from('bucket').createSignedUrl('image.jpg', 60000, { + transform: { + width: 200, + height: 200, + } +}) +``` + +The transformation options are embedded into the token, they cannot be changed once signed. + +### Downloading Images + +We introduced 2 new recommended methods for downloading a file. +`publicDownload` and `authenticatedDownload` + +These new methods allow you to add transformation options and be able to download a modified image instead of the original. + +Use `publicDownload` when downloading an object from a **public** bucket. +Use `authenticatedDownload` when downloading an object from a **private** bucket. + +```ts +// Download from a public bucket +storage.from('bucket').publicDownload('image.jpg', { + transform: { + width: 800, + height: 300, + } +}) + +// Download from a private bucket +storage.from('bucket').authenticatedDownload('image.jpg', { + transform: { + width: 800, + height: 300, + } +}) +``` + +The existing `download` method is deprecated but will still work. +We recommend migrating to the new methods `publicDownload` and `authenticatedDownload` + +as `download` will be removed in the next major release + + +### Transformation options + +We currently support a few transformation options focusing on resizing & cropping. +We have plans to increase the transformation type available in a later release. + +### Resizing + +You can use `width` and `height` parameters to resize the image to a specific dimension. + +Alternatively, you can omit one of the above parameters and 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. + +### Limits + +Width / Height: + +- **type**: int +- **min**: 1 +- **max**: 2500 + +The image size cannot exceed 25MB +The image resolution cannot exceed 50MP + +### Supported Image Format + +| Format | Extension | Source | Result | +| -------|-----------|--------|--------| +| PNG | `png` | Yes | Yes | +| JPEG | `jpg` | Yes | Yes | +| WebP | `webp` | Yes | Yes | +| AVIF | `avif` | Yes | Yes | +| GIF | `gif` | Yes | Yes | +| ICO | `ico` | Yes | Yes | +| SVG | `svg` | Yes | Yes | +| HEIC | `heic` | Yes | No | +| BMP | `bmp` | Yes | Yes | +| TIFF | `tiff` | Yes | Yes | + +export const Page = ({ children }) => + +export default Page From 54bd2516b379c28067d1e57613a5323c2e0feb84 Mon Sep 17 00:00:00 2001 From: fenos Date: Mon, 12 Dec 2022 11:50:00 +0000 Subject: [PATCH 2/7] docs: smart cdn caching docs --- apps/docs/pages/guides/storage-cdn.mdx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/docs/pages/guides/storage-cdn.mdx b/apps/docs/pages/guides/storage-cdn.mdx index 4c11ca8fe64..a93ab8b2f09 100644 --- a/apps/docs/pages/guides/storage-cdn.mdx +++ b/apps/docs/pages/guides/storage-cdn.mdx @@ -31,6 +31,31 @@ Note that CDNs might still evict your object from their cache if it has not been The cache status of a particular request is sent in the `cf-cache-status` header. A cache status of `MISS` indicates that the CDN node did not have the object in its cache and had to ping the origin to get it. A cache status of `HIT` indicates that the object was sent directly from the CDN. + +## Smart CDN Caching + +With Smart CDN caching enabled, we are synchronizing the asset metadata (not the content) that live in your database to the edge. +By doing this we are able to automatically revalidate the cache when the content of an asset changes or gets deleted. + +On top of automatic revalidation, you will also benefit from a much greater Cache HIT ratio, since we are able to shield the origin server when +requesting an asset that hasn't changed with a different query string url. + +### Cache duration + +When using Smart CDN, we will control the CDN cache duration on the server and caching it for as long as possible. +However, you are still in control of the browser caching TTL which you can set by using the [cacheControl](/docs/reference/javascript/storage-from-upload) option while uploading the file. + +When a file is updated or deleted, we will automatically invalidate the CDN cache to reflect the change as well as to all derivatives (transformed images). +Keep in mind that the invalidation can take up to 60 seconds to be propagated across all the data-centers across the globe. + +When we invalidate an asset at the CDN level, it can't, doesn't, affect browser caching. +If you don't see the reflected changes make sure the browser cache has been updated. + +If your asset is updated frequently we recommend setting a low browser ttl value using the `cacheControl` option when using smart cdn caching. + +Smart CDN caching works with all types of operations including signed urls. + + ## Public vs Private Buckets Objects in public buckets do not require any Authorization to access objects. This leads to a better cache hit rate compared to private buckets. For private buckets, permissions for accessing each object is checked on a per user level. For example, if two different users access the same object in a private bucket from the same region, it results in a cache miss for both the users since they might have different security policies attached to them. On the other hand, if two different users access the same object in a public bucket from the same region, it results in a cache hit for the second user. From d8fb46dd6548f2050076f182e25aee1f29dd9556 Mon Sep 17 00:00:00 2001 From: fenos Date: Mon, 12 Dec 2022 11:50:13 +0000 Subject: [PATCH 3/7] docs: update image-resizing guide --- .../Navigation/Navigation.constants.ts | 2 +- .../{ => storage}/storage-image-resizing.mdx | 76 ++++++++----------- 2 files changed, 31 insertions(+), 47 deletions(-) rename apps/docs/pages/guides/{ => storage}/storage-image-resizing.mdx (51%) diff --git a/apps/docs/components/Navigation/Navigation.constants.ts b/apps/docs/components/Navigation/Navigation.constants.ts index 29212056fdb..8af16004887 100644 --- a/apps/docs/components/Navigation/Navigation.constants.ts +++ b/apps/docs/components/Navigation/Navigation.constants.ts @@ -246,7 +246,7 @@ export const menuItems: NavMenu = { items: [ { name: 'Overview', url: '/guides/storage', items: [] }, { name: 'CDN', url: '/guides/storage-cdn', items: [] }, - { name: 'Image Resizing', url: '/guides/storage-image-resizing', items: [] }, + { name: 'Image Resizing', url: '/guides/storage/image-resizing', items: [] }, ], }, { diff --git a/apps/docs/pages/guides/storage-image-resizing.mdx b/apps/docs/pages/guides/storage/storage-image-resizing.mdx similarity index 51% rename from apps/docs/pages/guides/storage-image-resizing.mdx rename to apps/docs/pages/guides/storage/storage-image-resizing.mdx index dc9cffb9aac..be5219d2ea8 100644 --- a/apps/docs/pages/guides/storage-image-resizing.mdx +++ b/apps/docs/pages/guides/storage/storage-image-resizing.mdx @@ -7,17 +7,18 @@ export const meta = { sidebar_label: 'Image Transformation', } -Storage offers the functionality to transform and resize images on the fly. -Any image stored in your buckets can be transformed and optimized for fast delivery. +Supabase Storage offers the functionality to transform and resize images dynamically. Any image stored in your buckets can be transformed and optimized for fast delivery. -To get started with image resizing you can pass a `transform` option to the functions you are currently using to interact with your objects. + + Image Resizing is enabled for PRO tiers and above + -Image Resizing is enabled for PRO tiers and above +### Get a public URL for a Transformed image -### Get a public URL - With transformation options +You can pass a `transform` option to the functions you are currently using to interact with your objects. This returns the public URL that serves the resized image. ```ts -storage.from('bucket').getPublicUrl('image.jpg', { +supabase.storage.from('bucket').getPublicUrl('image.jpg', { transform: { width: 500, height: 600, @@ -34,11 +35,10 @@ An example URL could look like this: ### Signing URLs - With transformation options -You can sign the URLs for private buckets in the same way. -If you are signing an image and you’d like to share a transformed version, you’ll need to provide the transform options to the signing URL function +To share a transformed image for a fixed amount of time, provide the transform options when you create the signed URL: ```ts -storage.from('bucket').createSignedUrl('image.jpg', 60000, { +supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, { transform: { width: 200, height: 200, @@ -48,27 +48,12 @@ storage.from('bucket').createSignedUrl('image.jpg', 60000, { The transformation options are embedded into the token, they cannot be changed once signed. -### Downloading Images +## Downloading Images -We introduced 2 new recommended methods for downloading a file. -`publicDownload` and `authenticatedDownload` - -These new methods allow you to add transformation options and be able to download a modified image instead of the original. - -Use `publicDownload` when downloading an object from a **public** bucket. -Use `authenticatedDownload` when downloading an object from a **private** bucket. +To download a transformed image, pass the `transform` option to the `download` function ```ts -// Download from a public bucket -storage.from('bucket').publicDownload('image.jpg', { - transform: { - width: 800, - height: 300, - } -}) - -// Download from a private bucket -storage.from('bucket').authenticatedDownload('image.jpg', { +supabase.storage.from('bucket').download('image.jpg', { transform: { width: 800, height: 300, @@ -76,22 +61,14 @@ storage.from('bucket').authenticatedDownload('image.jpg', { }) ``` -The existing `download` method is deprecated but will still work. -We recommend migrating to the new methods `publicDownload` and `authenticatedDownload` - -as `download` will be removed in the next major release - - ### Transformation options We currently support a few transformation options focusing on resizing & cropping. -We have plans to increase the transformation type available in a later release. +We have plans to increase the transformation types available in a later release. ### Resizing -You can use `width` and `height` parameters to resize the image to a specific dimension. - -Alternatively, you can omit one of the above parameters and the image will be resized and cropped maintaining the aspect ratio. +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 @@ -105,18 +82,25 @@ Use the `resize` parameter with one of the following values: - `fill` : resizes the image without keeping the aspect ratio. +Example: + +```ts +supabase.storage.from('bucket').download('image.jpg', { + transform: { + width: 800, + height: 300, + resize: 'contain' // 'cover' | 'fill' + } +}) +``` + ### Limits -Width / Height: +- Width and height must be an integer value between 1-2500. +- The image size cannot exceed 25MB. +- The image resolution cannot exceed 50MP. -- **type**: int -- **min**: 1 -- **max**: 2500 - -The image size cannot exceed 25MB -The image resolution cannot exceed 50MP - -### Supported Image Format +### Supported Image Formats | Format | Extension | Source | Result | | -------|-----------|--------|--------| From 4f68a0d383717f630224be707b6673ee2aa16b94 Mon Sep 17 00:00:00 2001 From: Francisco Mazzoni Date: Mon, 12 Dec 2022 16:24:26 -0300 Subject: [PATCH 4/7] links to new guides for storage --- apps/www/pages/storage/Storage.tsx | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/www/pages/storage/Storage.tsx b/apps/www/pages/storage/Storage.tsx index f9934a488b3..15ba7dab12e 100644 --- a/apps/www/pages/storage/Storage.tsx +++ b/apps/www/pages/storage/Storage.tsx @@ -187,6 +187,17 @@ function StoragePage() { title="CDN" text="Serve from the edge to reduce latency." /> + + +
- New + + +
, ]} From df3ae19cb92555ee35a5d82925277337dc25cb2b Mon Sep 17 00:00:00 2001 From: dng Date: Mon, 12 Dec 2022 16:50:52 -0800 Subject: [PATCH 5/7] Apply suggestions from code review --- apps/docs/pages/guides/storage/cdn.mdx | 38 ++++++++----------- .../pages/guides/storage/image-resizing.mdx | 23 ++++++----- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/apps/docs/pages/guides/storage/cdn.mdx b/apps/docs/pages/guides/storage/cdn.mdx index d850051e9cb..e54a8d3df4e 100644 --- a/apps/docs/pages/guides/storage/cdn.mdx +++ b/apps/docs/pages/guides/storage/cdn.mdx @@ -15,22 +15,20 @@ All assets uploaded to Supabase Storage are cached on a Content Delivery Network Let’s walk through an example of how a CDN helps with performance. -A new bucket is created for a Supabase project launched in Singapore. All requests to the Supabase Storage API first hit the CDN. +A new bucket is created for a Supabase project launched in Singapore. All requests to the Supabase Storage API are routed to the CDN first. A user from the United States requests an object and is routed to the U.S. CDN. At this point, that CDN node does not have the object in its cache and pings the origin server in Singapore. Another user, also in the United States, requests the same object and is served directly from the CDN cache in the United States instead of routing the request back to Singapore. ### Cache duration -By default, assets are cached both in the CDN and in the user's browser for 1 hour. - -After this, the CDN nodes ping the storage server to see if an object has been updated. You can modify this cache time when you are [uploading](/docs/reference/javascript/storage-from-upload) or [updating](/docs/reference/javascript/storage-from-update) an object by modifying the `cacheControl` parameter. +By default, assets are cached both in the CDN and in the user's browser for 1 hour. After this, the CDN nodes ping the storage server to see if an object has been updated. You can modify this cache time when you are [uploading](/docs/reference/javascript/storage-from-upload) or [updating](/docs/reference/javascript/storage-from-update) an object by modifying the `cacheControl` parameter. If you expect the object to not change at a given URL, setting a longer cache duration is preferable. -If you need to update the version of the object stored in the CDN, there are various cache-busting techniques you can use.
The most common way to do this is to add a version query parameter in the URL. +If you need to update the version of the object stored in the CDN, there are various cache-busting techniques you can use. The most common way to do this is to add a version query parameter in the URL. For example, you can use a URL like `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=1` in your applications and set a long cache time of 1 year. -When you want to update the cat picture, you can increment the version query parameter in the URL. The CDN will treat `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=2` as a new object and pings the origin for the updated version. +When you want to update the cat picture, you can increment the version query parameter in the URL. The CDN treats `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=2` as a new object and pings the origin for the updated version. Note that CDNs might still evict your object from their cache if it has not been requested for a while from a specific region. For example, if no user from United States requests your object, it will be removed from the CDN cache even if you set a very long cache control duration. @@ -39,30 +37,24 @@ The cache status of a particular request is sent in the `cf-cache-status` header ## Smart CDN Caching -With Smart CDN caching enabled, we are synchronizing the asset metadata (not the content) that live in your database to the edge. -By doing this we are able to automatically revalidate the cache when the content of an asset changes or gets deleted. - -On top of automatic revalidation, you will also benefit from a much greater Cache HIT ratio, since we are able to shield the origin server when -requesting an asset that hasn't changed when using different query string url. - - Smart CDN caching is enabled for PRO tiers and above + Smart CDN caching is enabled for [PRO tiers and above](https://supabase.com/pricing). +With Smart CDN caching enabled, the asset metadata (not the content) in your database is synchronized to the edge. This automatically revalidates the cache when the content of an asset is changed or deleted. + +Additionally, the cache HIT ratio is increased as the origin server is shielded from asset requests that haven't changed when using a different query string URL. + ### Cache duration -When using Smart CDN, we will control the CDN cache duration on the server and caching it for as long as possible. -However, you are still in control of the browser caching TTL which you can set by using the [cacheControl](/docs/reference/javascript/storage-from-upload) option while uploading the file. +The Smart CDN cache duration is controlled on the server and cached for as long as possible. However, you can still control the browser caching TTL using the [cacheControl](/docs/reference/javascript/storage-from-upload) option when uploading a file. Smart CDN caching works with all types of operations including signed URLs. -When a file is updated or deleted, we will automatically invalidate the CDN cache to reflect the change as well as to all derivatives (transformed images). -Keep in mind that the invalidation can take up to 60 seconds to be propagated across all the data-centers across the globe. +When a file is updated or deleted, the CDN cache is automatically invalidated to reflect the change (including transformed images). +It can take **up to 60 seconds** for the CDN cache to be invalidated as it has to propagate across all the data-centers around the globe. -When we invalidate an asset at the CDN level, it can't, doesn't, affect browser caching. -If you don't see the reflected changes make sure the browser cache has been updated. - -If your asset is updated frequently we recommend setting a low browser ttl value using the `cacheControl` option when using smart cdn caching. - -Smart CDN caching works with all types of operations including signed urls. +When an asset is invalidated at the CDN level, it doesn't affect browser caching. +If you don't see the changes, make sure the browser cache has been updated. +If your asset is updated frequently, we recommend setting a low browser TTL value using the `cacheControl` option when using smart CDN caching. ## Public vs Private Buckets diff --git a/apps/docs/pages/guides/storage/image-resizing.mdx b/apps/docs/pages/guides/storage/image-resizing.mdx index 31c28cbe364..10a1c1be266 100644 --- a/apps/docs/pages/guides/storage/image-resizing.mdx +++ b/apps/docs/pages/guides/storage/image-resizing.mdx @@ -10,10 +10,10 @@ export const meta = { Supabase Storage offers the functionality to transform and resize images dynamically. Any image stored in your buckets can be transformed and optimized for fast delivery. - Image Resizing is currently in beta and enabled for PRO tiers and above + Image Resizing is currently in beta and enabled for [PRO tiers and above](https://supabase.com/pricing). -### Get a public URL for a Transformed image +### Get a public URL for a transformed image You can pass a `transform` option to the functions you are currently using to interact with your objects. This returns the public URL that serves the resized image. @@ -44,11 +44,11 @@ supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, { }) ``` -The transformation options are embedded into the token, they cannot be changed once signed. +The transformation options are embedded into the token—they cannot be changed once signed. -### Downloading Images +### Downloading images -To download a transformed image, pass the `transform` option to the `download` function +To download a transformed image, pass the `transform` option to the `download` function. ```ts supabase.storage.from('bucket').download('image.jpg', { @@ -61,8 +61,7 @@ supabase.storage.from('bucket').download('image.jpg', { ## Transformation options -We currently support a few transformation options focusing on resizing & cropping. -We have plans to increase the transformation types available in a later release. +We currently support a few transformation options focusing on resizing and cropping images. ### Resizing @@ -84,11 +83,11 @@ Example: ```ts supabase.storage.from('bucket').download('image.jpg', { - transform: { - width: 800, - height: 300, - resize: 'contain' // 'cover' | 'fill' - } + transform: { + width: 800, + height: 300, + resize: 'contain' // 'cover' | 'fill' + } }) ``` From 7dd2c56a70b6937c2798a76d485527babd409744 Mon Sep 17 00:00:00 2001 From: dng Date: Mon, 12 Dec 2022 16:54:46 -0800 Subject: [PATCH 6/7] Fix indentation --- .../pages/guides/storage/image-resizing.mdx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/docs/pages/guides/storage/image-resizing.mdx b/apps/docs/pages/guides/storage/image-resizing.mdx index 10a1c1be266..4df9c95b582 100644 --- a/apps/docs/pages/guides/storage/image-resizing.mdx +++ b/apps/docs/pages/guides/storage/image-resizing.mdx @@ -19,10 +19,10 @@ You can pass a `transform` option to the functions you are currently using to in ```ts supabase.storage.from('bucket').getPublicUrl('image.jpg', { - transform: { - width: 500, - height: 600, - } + transform: { + width: 500, + height: 600, + } }) ``` @@ -37,10 +37,10 @@ To share a transformed image for a fixed amount of time, provide the transform o ```ts supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, { - transform: { - width: 200, - height: 200, - } + transform: { + width: 200, + height: 200, + } }) ``` @@ -52,10 +52,10 @@ To download a transformed image, pass the `transform` option to the `download` f ```ts supabase.storage.from('bucket').download('image.jpg', { - transform: { - width: 800, - height: 300, - } + transform: { + width: 800, + height: 300, + } }) ``` From 81552002503b6df652e7f6aa695f5fca1179a50d Mon Sep 17 00:00:00 2001 From: dng Date: Mon, 12 Dec 2022 17:18:09 -0800 Subject: [PATCH 7/7] Update heading levels --- apps/docs/pages/guides/storage/image-resizing.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/docs/pages/guides/storage/image-resizing.mdx b/apps/docs/pages/guides/storage/image-resizing.mdx index 4df9c95b582..cdfbfd3a729 100644 --- a/apps/docs/pages/guides/storage/image-resizing.mdx +++ b/apps/docs/pages/guides/storage/image-resizing.mdx @@ -13,7 +13,7 @@ Supabase Storage offers the functionality to transform and resize images dynamic Image Resizing is currently in beta and enabled for [PRO tiers and above](https://supabase.com/pricing). -### Get a public URL for a transformed image +## Get a public URL for a transformed image You can pass a `transform` option to the functions you are currently using to interact with your objects. This returns the public URL that serves the resized image. @@ -31,7 +31,7 @@ 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 +## Signing URLs with transformation options To share a transformed image for a fixed amount of time, provide the transform options when you create the signed URL: @@ -46,7 +46,7 @@ supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, { The transformation options are embedded into the token—they cannot be changed once signed. -### Downloading images +## Downloading images To download a transformed image, pass the `transform` option to the `download` function.