diff --git a/apps/docs/pages/guides/storage.mdx b/apps/docs/content/guides/storage.mdx
similarity index 68%
rename from apps/docs/pages/guides/storage.mdx
rename to apps/docs/content/guides/storage.mdx
index 49274f6ca0d..fd840fdec13 100644
--- a/apps/docs/pages/guides/storage.mdx
+++ b/apps/docs/content/guides/storage.mdx
@@ -1,12 +1,11 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage',
- title: 'Storage',
- description: 'Use Supabase to store and serve files.',
- subtitle: 'Use Supabase to store and serve files.',
- sidebar_label: 'Overview',
-}
+---
+id: 'storage'
+title: 'Storage'
+description: 'Use Supabase to store and serve files.'
+subtitle: 'Use Supabase to store and serve files.'
+sidebar_label: 'Overview'
+hideToc: true
+---
Supabase Storage makes it simple to upload and serve files of any size, providing a robust framework for file access controls.
@@ -44,7 +43,18 @@ export const examples = [
Find the source code and documentation in the Supabase GitHub repository.
{x.description}
@@ -52,20 +62,3 @@ Find the source code and documentation in the Supabase GitHub repository.
))}
-
-export const integrations = [
- {
- name: 'Supabase Storage API',
- description: 'View the source code.',
- href: 'https://github.com/supabase/storage-api',
- },
- {
- name: 'OpenAPI Spec',
- description: 'See the Swagger Documentation for Supabase Storage.',
- href: 'https://supabase.github.io/storage/',
- },
-]
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/buckets/creating-buckets.mdx b/apps/docs/content/guides/storage/buckets/creating-buckets.mdx
similarity index 86%
rename from apps/docs/pages/guides/storage/buckets/creating-buckets.mdx
rename to apps/docs/content/guides/storage/buckets/creating-buckets.mdx
index cedf1723483..b63979bc8b1 100644
--- a/apps/docs/pages/guides/storage/buckets/creating-buckets.mdx
+++ b/apps/docs/content/guides/storage/buckets/creating-buckets.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-creating-buckets',
- title: 'Creating Buckets',
- description: 'Learn how to create Supabase Storage buckets.',
- sidebar_label: 'Buckets',
-}
+---
+id: 'storage-creating-buckets'
+title: 'Creating Buckets'
+description: 'Learn how to create Supabase Storage buckets.'
+sidebar_label: 'Buckets'
+---
You can create a bucket using the Supabase Dashboard. Since storage is interoperable with your Postgres database, you can also use SQL or our client libraries.
Here we create a bucket called "avatars":
@@ -87,7 +85,3 @@ const { data, error } = await supabase.storage.createBucket('avatars', {
If an upload request doesn't meet the above restrictions it will be rejected.
For more information check [File Limits](/docs/guides/storage/uploads/file-limits) Section.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/buckets/fundamentals.mdx b/apps/docs/content/guides/storage/buckets/fundamentals.mdx
similarity index 84%
rename from apps/docs/pages/guides/storage/buckets/fundamentals.mdx
rename to apps/docs/content/guides/storage/buckets/fundamentals.mdx
index be6447f45c4..ccc5785e512 100644
--- a/apps/docs/pages/guides/storage/buckets/fundamentals.mdx
+++ b/apps/docs/content/guides/storage/buckets/fundamentals.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-bucket-public-and-private',
- title: 'Storage Buckets',
- description: 'Learn how Supabase Storage Buckets works.',
- sidebar_label: 'Buckets',
-}
+---
+id: 'storage-bucket-public-and-private'
+title: 'Storage Buckets'
+description: 'Learn how Supabase Storage Buckets works.'
+sidebar_label: 'Buckets'
+---
Buckets allow you to keep your files organized and determines the [Access Model](#access-model) for your assets. [Upload restrictions](/docs/guides/storage/buckets/creating-buckets#restricting-uploads) like max file size and allowed content types are also defined at the bucket level.
@@ -40,7 +38,3 @@ Access control is still enforced for other types of operations including uploadi
- Blog post content
Public buckets are more performant than private buckets since they are [cached differently](/docs/guides/storage/cdn/fundamentals#public-vs-private-buckets).
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/cdn/fundamentals.mdx b/apps/docs/content/guides/storage/cdn/fundamentals.mdx
similarity index 88%
rename from apps/docs/pages/guides/storage/cdn/fundamentals.mdx
rename to apps/docs/content/guides/storage/cdn/fundamentals.mdx
index f9aea721fa9..3f0543e1d05 100644
--- a/apps/docs/pages/guides/storage/cdn/fundamentals.mdx
+++ b/apps/docs/content/guides/storage/cdn/fundamentals.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-cdn',
- title: 'Storage CDN',
- description: 'Learn how Supabase Storage caches objects with a CDN.',
- sidebar_label: 'CDN',
-}
+---
+id: 'storage-cdn'
+title: 'Storage CDN'
+description: 'Learn how Supabase Storage caches objects with a CDN.'
+sidebar_label: 'CDN'
+---
All assets uploaded to Supabase Storage are cached on a Content Delivery Network (CDN) to improve the latency for users all around the world. CDNs are a geographically distributed set of servers or **nodes** which cache content from an **origin server**. For Supabase Storage, the origin is the storage server running in the [same region as your project](https://supabase.com/dashboard/project/_/settings/general). Aside from performance, CDNs also help with security and availability by mitigating Distributed Denial of Service (DDoS) and other application attacks.
@@ -35,7 +33,3 @@ Objects in public buckets do not require any authorization to access objects. Th
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.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/cdn/metrics.mdx b/apps/docs/content/guides/storage/cdn/metrics.mdx
similarity index 89%
rename from apps/docs/pages/guides/storage/cdn/metrics.mdx
rename to apps/docs/content/guides/storage/cdn/metrics.mdx
index 9257fbb32d3..f6c6fd41072 100644
--- a/apps/docs/pages/guides/storage/cdn/metrics.mdx
+++ b/apps/docs/content/guides/storage/cdn/metrics.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-cdn',
- title: 'Cache Metrics',
- description: 'Learn how Supabase Storage caches objects with a CDN.',
- sidebar_label: 'CDN',
-}
+---
+id: 'storage-cdn'
+title: 'Cache Metrics'
+description: 'Learn how Supabase Storage caches objects with a CDN.'
+sidebar_label: 'CDN'
+---
Cache hits can be determined via the `metadata.response.headers.cf_cache_status` key in our [Logs Explorer](/docs/guides/platform/logs#logs-explorer). Any value that corresponds to either `HIT`, `STALE`, `REVALIDATED`, or `UPDATING` is categorized as a cache hit.
The following example query will show the top cache misses from the `edge_logs`:
@@ -50,7 +48,3 @@ order by timestamp desc;
```
Try out [this query](https://supabase.com/dashboard/project/_/logs/explorer?q=%0Aselect%0A++timestamp_trunc%28timestamp%2C+hour%29+as+timestamp%2C%0A++countif%28h.cf_cache_status+in+%28%27HIT%27%2C+%27STALE%27%2C+%27REVALIDATED%27%2C+%27UPDATING%27%29%29+%2F+count%28f.id%29+as+ratio%0Afrom%0A++edge_logs+as+f%0A++cross+join+unnest%28f.metadata%29+as+m%0A++cross+join+unnest%28m.request%29+as+r%0A++cross+join+unnest%28m.response%29+as+res%0A++cross+join+unnest%28res.headers%29+as+h%0Awhere+starts_with%28r.path%2C+%27%2Fstorage%2Fv1%2Fobject%27%29+and+r.method+%3D+%27GET%27%0Agroup+by+timestamp%0Aorder+by+timestamp+desc%3B) in the Logs Explorer.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/cdn/smart-cdn.mdx b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx
similarity index 88%
rename from apps/docs/pages/guides/storage/cdn/smart-cdn.mdx
rename to apps/docs/content/guides/storage/cdn/smart-cdn.mdx
index 2ca47c9d7b2..e6b9f235cd9 100644
--- a/apps/docs/pages/guides/storage/cdn/smart-cdn.mdx
+++ b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-cdn',
- title: 'Smart CDN',
- description: 'Learn how Supabase Storage caches objects with a CDN.',
- sidebar_label: 'CDN',
-}
+---
+id: 'storage-cdn'
+title: 'Smart CDN'
+description: 'Learn how Supabase Storage caches objects with a CDN.'
+sidebar_label: 'CDN'
+---
With Smart CDN caching enabled, the asset metadata in your database is synchronized to the edge. This automatically revalidates the cache when the asset is changed or deleted.
@@ -38,7 +36,3 @@ If you anticipate that your asset might be deleted, it's advisable to set a shor
If you need to ensure assets refresh directly from the origin server and bypass the cache, you can achieve this by adding a unique query string to the URL.
For instance, you can use a URL like `/storage/v1/object/sign/profile-pictures/cat.jpg?version=1` with a long browser cache (e.g., 1 year). To update the picture, increment the version query parameter in the URL, like `/storage/v1/object/sign/profile-pictures/cat.jpg?version=2`. The CDN will recognize it as a new object and fetch the updated version from the origin.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/debugging/error-codes.mdx b/apps/docs/content/guides/storage/debugging/error-codes.mdx
similarity index 86%
rename from apps/docs/pages/guides/storage/debugging/error-codes.mdx
rename to apps/docs/content/guides/storage/debugging/error-codes.mdx
index 4625ce58818..a190912b3cd 100644
--- a/apps/docs/pages/guides/storage/debugging/error-codes.mdx
+++ b/apps/docs/content/guides/storage/debugging/error-codes.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-errors-codes',
- title: 'Error Codes',
- description: 'Supabase Error Codes',
- sidebar_label: 'Debugging',
-}
+---
+id: 'storage-errors-codes'
+title: 'Error Codes'
+description: 'Supabase Error Codes'
+sidebar_label: 'Debugging'
+---
Here's a list of the most common error codes and their potential resolutions:
@@ -57,7 +55,3 @@ This issue occurs where there is a unhandled error.
**Resolution:**
- File a support ticket to Storage team [here](https://supabase.com/dashboard/support/new)
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/debugging/logs.mdx b/apps/docs/content/guides/storage/debugging/logs.mdx
similarity index 84%
rename from apps/docs/pages/guides/storage/debugging/logs.mdx
rename to apps/docs/content/guides/storage/debugging/logs.mdx
index 4202bd22355..c21d4b96757 100644
--- a/apps/docs/pages/guides/storage/debugging/logs.mdx
+++ b/apps/docs/content/guides/storage/debugging/logs.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-logs',
- title: 'Logs',
- description: 'Learn how to check Storage Logs',
- sidebar_label: 'Debugging',
-}
+---
+id: 'storage-logs'
+title: 'Logs'
+description: 'Learn how to check Storage Logs'
+sidebar_label: 'Debugging'
+---
Accessing the [Storage Logs](https://supabase.green/dashboard/project/__/logs/explorer?q=select+id%2C+storage_logs.timestamp%2C+event_message+from+storage_logs%0A++%0A++order+by+timestamp+desc%0A++limit+100%0A++) allows you to examine all incoming request logs to your Storage service. You can also filter logs and delve into specific aspects of your requests.
@@ -62,7 +60,3 @@ where r.remoteAddress in ("IP_ADDRESS")
order by timestamp desc
limit 100;
```
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/production/scaling.mdx b/apps/docs/content/guides/storage/production/scaling.mdx
similarity index 89%
rename from apps/docs/pages/guides/storage/production/scaling.mdx
rename to apps/docs/content/guides/storage/production/scaling.mdx
index 35e760fc98f..f1b2bfebb0c 100644
--- a/apps/docs/pages/guides/storage/production/scaling.mdx
+++ b/apps/docs/content/guides/storage/production/scaling.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-schema-optimizations',
- title: 'Storage Optimizations',
- description: 'Scaling Storage',
- subtitle: 'Scaling Storage',
- sidebar_label: 'Schema',
-}
+---
+id: 'storage-schema-optimizations'
+title: 'Storage Optimizations'
+description: 'Scaling Storage'
+subtitle: 'Scaling Storage'
+sidebar_label: 'Schema'
+---
Here are some optimizations that you can consider to improve performance and reduce costs as you start scaling Storage.
@@ -86,7 +84,3 @@ const { data, error } = await supabase.rpc('list_objects', {
## Optimizing RLS
When creating RLS policies against the storage tables you can add indexes to the interested columns to speed up the lookup
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/quickstart.mdx b/apps/docs/content/guides/storage/quickstart.mdx
similarity index 93%
rename from apps/docs/pages/guides/storage/quickstart.mdx
rename to apps/docs/content/guides/storage/quickstart.mdx
index 084fa5ba658..233d05e5738 100644
--- a/apps/docs/pages/guides/storage/quickstart.mdx
+++ b/apps/docs/content/guides/storage/quickstart.mdx
@@ -1,13 +1,11 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-quickstart',
- title: 'Storage Quickstart',
- description: 'Learn how to use Supabase to store and serve files.',
- subtitle: 'Learn how to use Supabase to store and serve files.',
- sidebar_label: 'Quickstart',
- tocVideo: 'J9mTPY8rIXE',
-}
+---
+id: 'storage-quickstart'
+title: 'Storage Quickstart'
+description: 'Learn how to use Supabase to store and serve files.'
+subtitle: 'Learn how to use Supabase to store and serve files.'
+sidebar_label: 'Quickstart'
+tocVideo: 'J9mTPY8rIXE'
+---
This guide shows the basic functionality of Supabase Storage. Find a full [example application on GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/nextjs-user-management).
@@ -238,7 +236,3 @@ create policy "Public Access"
allowFullScreen
>
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/schema/design.mdx b/apps/docs/content/guides/storage/schema/design.mdx
similarity index 80%
rename from apps/docs/pages/guides/storage/schema/design.mdx
rename to apps/docs/content/guides/storage/schema/design.mdx
index 5e1acef5493..2a55a2a2445 100644
--- a/apps/docs/pages/guides/storage/schema/design.mdx
+++ b/apps/docs/content/guides/storage/schema/design.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-schema-design',
- title: 'The Storage Schema',
- description: 'Learn about the storage schema',
- subtitle: 'Learn about the storage schema',
- sidebar_label: 'Schema',
-}
+---
+id: 'storage-schema-design'
+title: 'The Storage Schema'
+description: 'Learn about the storage schema'
+subtitle: 'Learn about the storage schema'
+sidebar_label: 'Schema'
+---
Storage uses Postgres to store metadata regarding your buckets and objects. Users can use RLS (Row-Level Security) policies for access control. This data is stored in a dedicated schema within your project called `storage`.
@@ -28,7 +26,3 @@ You have the option to query this table directly to retrieve information about y
We strongly recommend refraining from making any alterations to the `storage` schema and treating it as read-only. This approach is important because any modifications to the schema on your end could potentially clash with our future updates, leading to downtime.
However, we encourage you to add custom indexes as they can significantly improve the performance of the RLS policies you create for enforcing access control.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/schema/helper-functions.mdx b/apps/docs/content/guides/storage/schema/helper-functions.mdx
similarity index 80%
rename from apps/docs/pages/guides/storage/schema/helper-functions.mdx
rename to apps/docs/content/guides/storage/schema/helper-functions.mdx
index 53e1be7ad02..a29ab4bb17a 100644
--- a/apps/docs/pages/guides/storage/schema/helper-functions.mdx
+++ b/apps/docs/content/guides/storage/schema/helper-functions.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-schema',
- title: 'Storage Helper Functions',
- description: 'Learn the storage schema',
- subtitle: 'Learn the storage schema',
- sidebar_label: 'Schema',
-}
+---
+id: 'storage-schema'
+title: 'Storage Helper Functions'
+description: 'Learn the storage schema'
+subtitle: 'Learn the storage schema'
+sidebar_label: 'Schema'
+---
Supabase Storage provides SQL helper functions which you can use to write RLS policies.
@@ -63,7 +61,3 @@ with check (
bucket_id = 'cats' and storage.extension(name) = 'png'
);
```
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/security/access-control.mdx b/apps/docs/content/guides/storage/security/access-control.mdx
similarity index 90%
rename from apps/docs/pages/guides/storage/security/access-control.mdx
rename to apps/docs/content/guides/storage/security/access-control.mdx
index 6dc1219eb21..e6af3eee841 100644
--- a/apps/docs/pages/guides/storage/security/access-control.mdx
+++ b/apps/docs/content/guides/storage/security/access-control.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-access-control',
- title: 'Storage Access Control',
- description: 'Learn how to restrict Supabase file uploads.',
- sidebar_label: 'Uploads',
- tocVideo: '4ERX__Y908k',
-}
+---
+id: 'storage-access-control'
+title: 'Storage Access Control'
+description: 'Learn how to restrict Supabase file uploads.'
+sidebar_label: 'Uploads'
+tocVideo: '4ERX__Y908k'
+---
Supabase Storage is designed to work perfectly with Postgres [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) (RLS).
@@ -103,7 +101,3 @@ using ( auth.uid() = owner_id );
If you exclusively use Storage from trusted clients, such as your own servers, and need to bypass the RLS policies, you can use the `service key` in the `Authorization` header. Service keys entirely bypass RLS policies, granting you unrestricted access to all Storage APIs.
Remember you should not share the service key publicly.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/serving/downloads.mdx b/apps/docs/content/guides/storage/serving/downloads.mdx
similarity index 79%
rename from apps/docs/pages/guides/storage/serving/downloads.mdx
rename to apps/docs/content/guides/storage/serving/downloads.mdx
index cafa92ace95..62fea784b3e 100644
--- a/apps/docs/pages/guides/storage/serving/downloads.mdx
+++ b/apps/docs/content/guides/storage/serving/downloads.mdx
@@ -1,13 +1,11 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-image-transformations',
- title: 'Serving assets from Storage',
- description: 'Serving assets from Storage',
- subtitle: 'Serving assets from Storage',
- sidebar_label: 'Serving assets',
- tocVideo: 'dLqSmxX3r7I',
-}
+---
+id: 'storage-image-transformations'
+title: 'Serving assets from Storage'
+description: 'Serving assets from Storage'
+subtitle: 'Serving assets from Storage'
+sidebar_label: 'Serving assets'
+tocVideo: 'dLqSmxX3r7I'
+---
## Public buckets
@@ -53,7 +51,3 @@ if (data) {
console.log(data.signedUrl)
}
```
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/serving/image-transformations.mdx b/apps/docs/content/guides/storage/serving/image-transformations.mdx
similarity index 95%
rename from apps/docs/pages/guides/storage/serving/image-transformations.mdx
rename to apps/docs/content/guides/storage/serving/image-transformations.mdx
index e247e421f68..d60dc23a173 100644
--- a/apps/docs/pages/guides/storage/serving/image-transformations.mdx
+++ b/apps/docs/content/guides/storage/serving/image-transformations.mdx
@@ -1,13 +1,11 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-image-transformations',
- title: 'Storage Image Transformations',
- description: 'Transform images with Storage',
- subtitle: 'Transform images with Storage',
- sidebar_label: 'Image Transformations',
- tocVideo: 'dLqSmxX3r7I',
-}
+---
+id: 'storage-image-transformations'
+title: 'Storage Image Transformations'
+description: 'Transform images with Storage'
+subtitle: 'Transform images with Storage'
+sidebar_label: 'Image Transformations'
+tocVideo: 'dLqSmxX3r7I'
+---
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.
@@ -383,7 +381,3 @@ IMGPROXY_URL=yourinternalimgproxyurl.internal.com
allowFullScreen
>
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/uploads/file-limits.mdx b/apps/docs/content/guides/storage/uploads/file-limits.mdx
similarity index 82%
rename from apps/docs/pages/guides/storage/uploads/file-limits.mdx
rename to apps/docs/content/guides/storage/uploads/file-limits.mdx
index 223203ef65e..84c816470ea 100644
--- a/apps/docs/pages/guides/storage/uploads/file-limits.mdx
+++ b/apps/docs/content/guides/storage/uploads/file-limits.mdx
@@ -1,11 +1,9 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'storage-file-limits',
- title: 'Limits',
- description: 'Learn how to increase Supabase file limits.',
- sidebar_label: 'Uploads',
-}
+---
+id: 'storage-file-limits'
+title: 'Limits'
+description: 'Learn how to increase Supabase file limits.'
+sidebar_label: 'Uploads'
+---
You can customize the Max file size for file uploads.
@@ -35,7 +33,3 @@ You can have different restrictions on a per bucket level.
You are able to restrict the file types (eg. `pdf`, `images`, `videos`) along with the max file size which should be lower than the global limit.
To apply these limit on a bucket level see [Creating Bucket](/docs/guides/storage/buckets/creating-buckets#restricting-uploads)
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/uploads/resumable-uploads.mdx b/apps/docs/content/guides/storage/uploads/resumable-uploads.mdx
similarity index 94%
rename from apps/docs/pages/guides/storage/uploads/resumable-uploads.mdx
rename to apps/docs/content/guides/storage/uploads/resumable-uploads.mdx
index 4a8faed56d2..73e07e7067b 100644
--- a/apps/docs/pages/guides/storage/uploads/resumable-uploads.mdx
+++ b/apps/docs/content/guides/storage/uploads/resumable-uploads.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'resumable-uploads',
- title: 'Resumable Uploads',
- description: 'Learn how to upload files to Supabase Storage.',
- subtitle: 'Learn how to upload files to Supabase Storage.',
- sidebar_label: 'Uploads',
-}
+---
+id: 'resumable-uploads'
+title: 'Resumable Uploads'
+description: 'Learn how to upload files to Supabase Storage.'
+subtitle: 'Learn how to upload files to Supabase Storage.'
+sidebar_label: 'Uploads'
+---
The resumable upload method is recommended when:
@@ -149,7 +147,3 @@ We do advise against overwriting files when possible, as the CDN will take some
Uploading a file to a new path is the recommended way to avoid propagation delays and stale content.
To learn more, see the [CDN](/docs/guides/storage/cdn/fundamentals) guide.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/uploads/standard-uploads.mdx b/apps/docs/content/guides/storage/uploads/standard-uploads.mdx
similarity index 89%
rename from apps/docs/pages/guides/storage/uploads/standard-uploads.mdx
rename to apps/docs/content/guides/storage/uploads/standard-uploads.mdx
index d3699892e13..90f219f5726 100644
--- a/apps/docs/pages/guides/storage/uploads/standard-uploads.mdx
+++ b/apps/docs/content/guides/storage/uploads/standard-uploads.mdx
@@ -1,12 +1,10 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'standard-uploads',
- title: 'Standard Uploads',
- description: 'Learn how to upload files to Supabase Storage.',
- subtitle: 'Learn how to upload files to Supabase Storage.',
- sidebar_label: 'Uploads',
-}
+---
+id: 'standard-uploads'
+title: 'Standard Uploads'
+description: 'Learn how to upload files to Supabase Storage.'
+subtitle: 'Learn how to upload files to Supabase Storage.'
+sidebar_label: 'Uploads'
+---
## Uploading
@@ -125,7 +123,3 @@ await supabase.storage.from('bucket_name').upload('file_path', file, {
When two or more clients upload a file to the same path, the first client to complete the upload will succeed and the other clients will receive a `400 Asset Already Exists` error.
If you provide the `x-upsert` header the last client to complete the upload will succeed instead.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/lib/docs.ts b/apps/docs/lib/docs.ts
index f0fd564b757..b9ac429c1aa 100644
--- a/apps/docs/lib/docs.ts
+++ b/apps/docs/lib/docs.ts
@@ -1,8 +1,17 @@
-import { dirname, join } from 'node:path'
+import { type CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
+import matter from 'gray-matter'
+import { serialize } from 'next-mdx-remote/serialize'
+import type { SerializeOptions } from 'next-mdx-remote/dist/types'
+import { existsSync } from 'node:fs'
+import { readdir, readFile } from 'node:fs/promises'
+import { dirname, join, extname, sep } from 'node:path'
import { fileURLToPath } from 'node:url'
+import remarkGfm from 'remark-gfm'
-export const DOCS_DIRECTORY = join(dirname(fileURLToPath(import.meta.url)), '..')
-export const GUIDES_DIRECTORY = join(DOCS_DIRECTORY, 'content/guides')
+import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
+
+const DOCS_DIRECTORY = join(dirname(fileURLToPath(import.meta.url)), '..')
+const GUIDES_DIRECTORY = join(DOCS_DIRECTORY, 'content/guides')
type GuideFrontmatter = {
title: string
@@ -15,3 +24,76 @@ export function isValidGuideFrontmatter(obj: object): obj is GuideFrontmatter {
if ('description' in obj && typeof obj.description !== 'string') return false
return true
}
+
+export async function getGuidesStaticPaths(section: string) {
+ const directory = join(GUIDES_DIRECTORY, section)
+ const files = (await readdir(directory, { recursive: true }))
+ .filter((file) => extname(file) === '.mdx')
+ .map((file) => ({
+ params: {
+ slug: file.replace(/\.mdx$/, '').split(sep),
+ },
+ }))
+
+ // Index page isn't included in the directory
+ const indexFile = join(GUIDES_DIRECTORY, `${section}.mdx`)
+ if (existsSync(indexFile)) {
+ files.push({ params: { slug: [] } })
+ }
+
+ return {
+ paths: files,
+ fallback: false,
+ }
+}
+
+export async function getGuidesStaticProps(
+ section: string,
+ { params }: { params?: { slug?: string | Array } }
+) {
+ let relPath: string
+ switch (typeof params?.slug) {
+ case 'string':
+ relPath = section + sep + params.slug
+ break
+ case 'object': // actually an array
+ relPath = section + sep + params.slug.join(sep)
+ break
+ case 'undefined':
+ relPath = section
+ }
+
+ const fullPath = join(GUIDES_DIRECTORY, relPath + '.mdx')
+ const mdx = await readFile(fullPath, 'utf-8')
+
+ const editLink = `supabase/supabase/blob/master/apps/docs/content/guides/${relPath}.mdx`
+
+ const { data: frontmatter, content } = matter(mdx)
+ if (!isValidGuideFrontmatter(frontmatter)) {
+ throw Error('Type of frontmatter is not valid')
+ }
+
+ const codeHikeOptions: CodeHikeConfig = {
+ theme: codeHikeTheme,
+ lineNumbers: true,
+ showCopyButton: true,
+ skipLanguages: [],
+ autoImport: false,
+ }
+
+ const mdxOptions: SerializeOptions = {
+ mdxOptions: {
+ useDynamicImport: true,
+ remarkPlugins: [remarkGfm, [remarkCodeHike, codeHikeOptions]],
+ },
+ }
+ const mdxSource = await serialize(content, mdxOptions)
+
+ return {
+ props: {
+ frontmatter,
+ mdxSource,
+ editLink,
+ },
+ }
+}
diff --git a/apps/docs/pages/guides/auth/[[...slug]].tsx b/apps/docs/pages/guides/auth/[[...slug]].tsx
index d77f8e7bc6e..777f65e6ddd 100644
--- a/apps/docs/pages/guides/auth/[[...slug]].tsx
+++ b/apps/docs/pages/guides/auth/[[...slug]].tsx
@@ -1,88 +1,16 @@
-import { type CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import matter from 'gray-matter'
-import { serialize } from 'next-mdx-remote/serialize'
-import type { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'
+import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
import { MDXRemote } from 'next-mdx-remote'
-import type { SerializeOptions } from 'next-mdx-remote/dist/types'
-import { existsSync } from 'node:fs'
-import { readdir, readFile } from 'node:fs/promises'
-import { join, extname, sep } from 'node:path'
-import remarkGfm from 'remark-gfm'
-
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
import components from '~/components'
import Layout from '~/layouts/DefaultGuideLayout'
-import { GUIDES_DIRECTORY, isValidGuideFrontmatter } from '~/lib/docs'
+import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
export const getStaticPaths = (async () => {
- const directory = join(GUIDES_DIRECTORY, 'auth')
- const files = (await readdir(directory, { recursive: true }))
- .filter((file) => extname(file) === '.mdx')
- .map((file) => ({
- params: {
- slug: file.replace(/\.mdx$/, '').split(sep),
- },
- }))
-
- // Index page isn't included in the directory
- const indexFile = join(GUIDES_DIRECTORY, 'auth.mdx')
- if (existsSync(indexFile)) {
- files.push({ params: { slug: [] } })
- }
-
- return {
- paths: files,
- fallback: false,
- }
+ return getGuidesStaticPaths('auth')
}) satisfies GetStaticPaths
-export const getStaticProps = (async ({ params }) => {
- let relPath: string
- switch (typeof params.slug) {
- case 'string':
- relPath = 'auth' + sep + params.slug
- break
- case 'object': // actually an array
- relPath = 'auth' + sep + params.slug.join(sep)
- break
- case 'undefined':
- relPath = 'auth'
- }
-
- const fullPath = join(GUIDES_DIRECTORY, relPath + '.mdx')
- const mdx = await readFile(fullPath, 'utf-8')
-
- const editLink = `supabase/supabase/blob/master/apps/docs/content/guides/${relPath}.mdx`
-
- const { data: frontmatter, content } = matter(mdx)
- if (!isValidGuideFrontmatter(frontmatter)) {
- throw Error('Type of frontmatter is not valid')
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxOptions: SerializeOptions = {
- mdxOptions: {
- useDynamicImport: true,
- remarkPlugins: [remarkGfm, [remarkCodeHike, codeHikeOptions]],
- },
- }
- const mdxSource = await serialize(content, mdxOptions)
-
- return {
- props: {
- frontmatter,
- mdxSource,
- editLink,
- },
- }
+export const getStaticProps = (async (args) => {
+ return getGuidesStaticProps('auth', args)
}) satisfies GetStaticProps
export default function AuthGuide({
diff --git a/apps/docs/pages/guides/storage/[[...slug]].tsx b/apps/docs/pages/guides/storage/[[...slug]].tsx
new file mode 100644
index 00000000000..c3ae4c4b3c3
--- /dev/null
+++ b/apps/docs/pages/guides/storage/[[...slug]].tsx
@@ -0,0 +1,28 @@
+import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
+import { MDXRemote } from 'next-mdx-remote'
+
+import components from '~/components'
+import Layout from '~/layouts/DefaultGuideLayout'
+import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
+
+export const getStaticPaths = (async () => {
+ return getGuidesStaticPaths('storage')
+}) satisfies GetStaticPaths
+
+export const getStaticProps = (async (args) => {
+ return getGuidesStaticProps('storage', args)
+}) satisfies GetStaticProps
+
+export default function StorageGuide({
+ frontmatter,
+ mdxSource,
+ editLink,
+}: InferGetStaticPropsType) {
+ const { hideToc, ...meta } = frontmatter
+
+ return (
+
+
+
+ )
+}
diff --git a/apps/docs/scripts/codemod/mdx-meta.mjs b/apps/docs/scripts/codemod/mdx-meta.mjs
index 5d87187e852..03b0719e6b0 100644
--- a/apps/docs/scripts/codemod/mdx-meta.mjs
+++ b/apps/docs/scripts/codemod/mdx-meta.mjs
@@ -7,7 +7,7 @@
* Also deletes import and export statements.
*/
-let SUB_DIR = null
+let SUB_DIR = 'storage'
import { parse } from 'acorn'
import { fromMarkdown } from 'mdast-util-from-markdown'