Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const TopNavBar: FC = () => {
}

const HeaderLogo = memo(() => {
const { navigationLogoUrl } = useCustomContent(['navigation:logo_url'])
const { navigationLogo } = useCustomContent(['navigation:logo'])

return (
<Link
Expand All @@ -122,20 +122,20 @@ const HeaderLogo = memo(() => {
>
<Image
className="hidden dark:block !m-0"
src={navigationLogoUrl?.dark ?? '/docs/supabase-dark.svg'}
src={navigationLogo?.dark ?? '/docs/supabase-dark.svg'}
priority={true}
loading="eager"
width={96}
height={18}
width={navigationLogo?.width ?? 96}
height={navigationLogo?.height ?? 18}
alt="Supabase wordmark"
/>
<Image
className="block dark:hidden !m-0"
src={navigationLogoUrl?.light ?? '/docs/supabase-light.svg'}
src={navigationLogo?.light ?? '/docs/supabase-light.svg'}
priority={true}
loading="eager"
width={96}
height={18}
width={navigationLogo?.width ?? 96}
height={navigationLogo?.height ?? 18}
alt="Supabase wordmark"
/>
<span className="font-mono text-sm font-medium text-brand-link mb-px">DOCS</span>
Expand Down
4 changes: 3 additions & 1 deletion apps/docs/hooks/custom-content/CustomContent.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export type CustomContentTypes = {
homepageHeading: string
navigationLogoUrl: {
navigationLogo: {
light: string
dark: string
width?: number
height?: number
}
}
2 changes: 1 addition & 1 deletion apps/docs/hooks/custom-content/custom-content.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"homepage:heading": "Supabase Documentation",
"navigation:logo_url": {
"navigation:logo": {
"light": "/docs/supabase-light.svg",
"dark": "/docs/supabase-dark.svg"
}
Expand Down
14 changes: 6 additions & 8 deletions apps/docs/hooks/custom-content/useCustomContent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ describe('useCustomContent', () => {
it('should return null if content is not found in the custom-content.json file', async () => {
vi.doMock('./custom-content.json', () => ({
default: {
'navigation:logo_url': null,
'navigation:logo': null,
},
}))

const { useCustomContent } = await import('./useCustomContent')
const { result } = renderHook(() => useCustomContent(['navigation:logo_url']))
expect(result.current.navigationLogoUrl).toEqual(null)
const { result } = renderHook(() => useCustomContent(['navigation:logo']))
expect(result.current.navigationLogo).toEqual(null)
})

it('should return the content for the key passed in if it exists in the custom-content.json file', async () => {
vi.doMock('./custom-content.json', () => ({
default: {
'navigation:logo_url': {
'navigation:logo': {
light: 'https://example.com/logo-light.svg',
dark: 'https://example.com/logo-dark.svg',
},
Expand All @@ -36,10 +36,8 @@ describe('useCustomContent', () => {
}))

const { useCustomContent } = await import('./useCustomContent')
const { result } = renderHook(() =>
useCustomContent(['navigation:logo_url', 'homepage:heading'])
)
expect(result.current.navigationLogoUrl).toEqual({
const { result } = renderHook(() => useCustomContent(['navigation:logo', 'homepage:heading']))
expect(result.current.navigationLogo).toEqual({
light: 'https://example.com/logo-light.svg',
dark: 'https://example.com/logo-dark.svg',
})
Expand Down
1 change: 1 addition & 0 deletions apps/docs/public/humans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ Tyler Fontaine
Tyler Shukert
TzeYiing L
Wen Bo Xie
Yorvi Arias
Yuliya Marinova
Yuri Santana
____________
Expand Down
2 changes: 1 addition & 1 deletion apps/www/_blog/2025-09-29-lovable-cloud-launch.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'Lovable Cloud + Supabase: The Default Platform for AI Builders'
description: Lovable Cloud makes building with AI agents easier than ever, with every project powered by Supabase behind the scenes.
author: wenbo
author: prashant
image: 2025-09-lovable-cloud-launch/og.png
thumb: 2025-09-lovable-cloud-launch/og.png
categories:
Expand Down
76 changes: 76 additions & 0 deletions apps/www/_blog/2025-09-30-bolt-cloud-launch.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: Enterprise speed, enterprise standards with Bolt Cloud + Supabase
description: With today's launch of Bolt Cloud, every project that needs a backend is powered by Supabase, giving developers enterprise standards with the speed of vibe coding.
author: prashant
image: 2025-09-bolt-cloud-launch/og.png
thumb: 2025-09-bolt-cloud-launch/og.png
categories:
- product
- bolt
- enterprise
date: 2025-09-30:08:00
toc_depth: 2
---

With today's launch of Bolt Cloud, every project in [Bolt Cloud](https://bolt.new) that needs a backend is powered by Supabase. Now, when you tell Bolt what you want to build, your project launches with a complete Supabase foundation including:

- A full Postgres Database
- Authentication and user management
- Storage for files, videos, and more
- Edge Functions
- Realtime for more immersive user experiences

Together, Bolt and Supabase give developers and product managers the best of both worlds: the speed of vibe coding and the standards enterprises require. Bolt has already connected their apps to over 600,000 Supabase backends today.

## The enterprise developer problem

Enterprise developers and product managers face familiar challenges:

- **Endless error loops.** Quick demos often collapse under real-world traffic or audits. Supabase + Bolt ensure reliability from the start.
- **Half-wired backends.** Databases here, auth there, storage somewhere else — every integration adds friction and failure points. The Bolt agent wires everything up with Supabase built in.
- **Prototypes that stall.** Tools that accelerate early prototypes often fail at scale, forcing painful rewrites. Supabase scale plus Bolt Cloud means you can move fast without hitting a rewrite wall.

Enterprise teams need speed and reliability. Supabase bridges both. It's the Postgres development platform that lets you build in a weekend and scale to millions, with the performance, compliance, and observability enterprises demand. Bolt Cloud proves the same point: speed only matters if you can trust the foundation.

## Supabase and Bolt Cloud: build enterprise applications in minutes

Bolt Cloud projects that use Supabase as their backend let teams move fast on infrastructure already trusted by enterprises across industries:

- **[Postgres Database](/database).** Production-ready Postgres with extensions, scaling, and backups built in. No proprietary query languages, no migration headaches, just SQL.
- **[Supabase Auth](/auth).** Complete authentication and user management, including enterprise features like SAML and SSO, plus Row Level Security for granular access control.
- **[Supabase Storage](/storage).** S3-compatible object storage, built for handling user-generated content at scale.
- **[Supabase Edge Functions](/edge-functions).** Globally distributed functions for custom business logic, deployed close to your users.
- **[Realtime APIs](/realtime).** Postgres replication exposed as APIs, enabling collaboration and live data without additional infrastructure.

Because Supabase is just Postgres, enterprises can reuse their skills, connect existing systems through Foreign Data Wrappers, and trust technology proven at global scale.

## Enterprise standards included

Bolt Cloud projects built on Supabase meet enterprise requirements:

- SOC 2 and HIPAA certifications for compliance-driven industries
- Row Level Security for protecting sensitive data
- Read replicas and horizontal scaling for unpredictable traffic
- Point-in-time recovery and automatic backups for resilience

These are not afterthoughts. They are table stakes for enterprise scale. Supabase delivers them out of the box.

## Why this matters

_Build in a weekend_. _Scale to millions_. This isn't just a tagline. It's how we operate. It means balancing the need for teams to move fast with the requirement to act responsibly and safely. Supabase is not just for startups. Modern enterprise teams face equal pressure to move faster than ever.

Bolt Cloud shows how this vision works in practice. A modern frontend workflow can extend into a secure, scalable backend powered by Supabase. Enterprise developers can move at the speed of AI-assisted development without leaving behind the standards their organizations require.

## Start building

Supabase is more than a database. It is the fully integrated Postgres development platform that reduces complexity for developers and reduces risk for enterprises. Bolt Cloud highlights the same trend we built around: giving teams superpowers without compromise.

**For developers:** Easy tools, instant setup, and seamless integrations.

**For enterprises:** Compliance, reliability, and the ability to scale with confidence.

It is not a tradeoff anymore. The new generation of tools delivers both.

[Get started with Supabase →](https://supabase.com/dashboard)

[Start your first Bolt Cloud project today →](https://bolt.new)
204 changes: 204 additions & 0 deletions apps/www/_blog/2025-09-30-postgrest-13-release.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
---
title: PostgREST 13
description: New features and changes in PostgREST version 13.
author: steve_chavez,laurenceisla,avallete
image: 2025-09-30-postgrest-13-release/postgrest-13-release.png
thumb: 2025-09-30-postgrest-13-release/postgrest-13-release.png
categories:
- postgres
tags:
- postgres
- postgrest
- release-notes
date: '2025-09-30'
---

PostgREST 13 is out! It comes with API and Observabilty improvements. In this post, we'll see what's new.

## Spread To-Many relationships

This new feature allows you to represent one-to-many and many-to-many relationships as flat JSON arrays.

For example, if you have database similar to IMDB and you’d like to represent it as a hierarchical JSON structure for your frontend, like so:

```json
[
{
"title": "The Shawshank Redemption",
"actors": ["Tim Robbins", "Morgan Freeman"],
"genres": ["Drama"]
},
{
"title": "The Godfather",
"actors": ["Marlon Brando", "Al Pacino"],
"genres": ["Drama", "Crime"]
},
{
"title": "The Dark Knight",
"actors": ["Christian Bale", "Heath Ledger"],
"genres": ["Drama", "Crime", "Action"]
}
]
```

You can now do it this way:

<$CodeTabs>

```js name=JavaScript
const { data, error } = await supabase.from('titles').select(`
title:primary_title,
...people(actors:primary_name),
...genres(genres:name)
`)
```

```bash name=Bash
curl --get 'https://<your-domain>/titles'
-d "select=title:primary_title,...people(actors:primary_name),...genres(genres:name)"
-H "Authorization: Bearer <YOUR_KEY>"
```

```swift name=Swift
try await supabase.from("titles").select(
"""
title:primary_title,
...people(actors:primary_name),
...genres(genres:name)
""")
```

</$CodeTabs>

The above `...people` is “spreading” the many-to-many relationship between `titles` and `people`, forming a flat array only consisting of the `primary_name` column. This flat array is then renamed to `actors`. We do a similar process for `genres` , which also forms a many-to-many relationship with `people`.

You can see the data model used for this example on this [gist](https://gist.github.com/steve-chavez/93f7ae04b4323e1952710af7129b32cf). There are more details about this feature on the [official docs](https://docs.postgrest.org/en/v13/references/api/resource_embedding.html#spread-to-many-relationships).

## Automatic tsvector convertion

Previously you could only use the full text search operator on `tsvector` columns, now you can do it on `text` and `json/jsonb` columns too:

<$CodeTabs>

```js name=JavaScript
const { data, error } = await supabase.from('titles').textSearch('primary_name', `'god' & 'father'`)
```

```bash name=Bash
curl --get 'https://<your-domain>/titles'
-d "primary_name=fts.'god'%26'father"
-H "Authorization: Bearer <YOUR_KEY>"
```

```swift name=Swift
try await supabase
.from("titles")
.fts("primary_name",value: "'god' & 'father'")
```

</$CodeTabs>

This works because `text` and `json/jsonb` columns will be automatically converted with `to_tsvector`.

To ensure this operation is fast, add an index:

```sql
create index idx_titles on people
using gin (to_tsvector('english', primary_name));
```

## Max Affected

You can now limit to the amount of rows affected by an `update` or `delete` operation with `maxAffected`:

<$CodeTabs>

```js name=JavaScript
const { data, error } = await supabase
.from('people')
.update({ primary_name: 'Marlon Brando Jr.' })
.eq('nconst', 'nm0000008')
.maxAffected(1)

// This is available starting from supabase-js version 2.56.0
```

```bash name=Bash
curl -X PATCH 'https://<your-domain>/people' \
-d "nconst=eq.nm0000008" \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Prefer: handling=strict, max-affected=1" \
-H "Content-Type: application/json" \
-d @- <<JSON
{ primary_name: 'Marlon Brando Jr.' }
JSON
```

```swift name=Swift
try await supabase
.from("people")
.update(["primary_name": "Marlon Brando Jr."])
.eq("nconst", value: "nm0000008")
.maxAffected(1)
.execute()

// This is available starting from supabase-swift version 2.33.0
```

</$CodeTabs>

If the rows affected by the operation surpass the limit in `maxAffected`, an error will be thrown.

This also works with `rpc()`, given that it modifies rows and returns the affected rows. More on details on the [official docs](https://docs.postgrest.org/en/v13/references/api/preferences.html#max-affected).

## Content-Length header

For observability, you can now verify the response body size in bytes in the `Content-Length` header.

```bash
HTTP/1.1 200 OK
Content-Length: 104
Content-Location: /items
```

This helps in cases where you want to know which requests consume the most traffic to avoid exceeding egress limits.

## Proxy-Status header

The PostgREST error code is now present in the `Proxy-Status` header.

```bash
HTTP/1.1 406 Not Acceptable
Proxy-Status: PostgREST; error=PGRST116
```

You can check the `Proxy-Status` and `Content-Length` headers in the Supabase Logs Explorer.

## Breaking Changes

### JWT `kid` validation

PostgREST now validates the JWT `kid` claim. If your JWT contains a Key ID (`kid`), it will try to match this with one of the `kid`'s in the configured JSON Web Key Set. Check the [official docs](https://docs.postgrest.org/en/v13/references/auth.html#jwk-kid-validation) for more details.

If you use Supabase Auth or the CLI to create JSON Web Keys, you shouldn’t worry about this change as both systems will ensure `kid`'s are present in the JSON Web Key Set.

For users that integrate with other Auth systems, make sure that both your JWT and JWKS follow the above rules.

### Schema validation in PostgREST search path

The schemas inside `db-schemas` and `db-extra-search-path` are now validated. This means you cannot put a nonexistent schema there, if you do PostgREST will fail with an error message.

If you drop a schema during a migration, you should make sure this is synced with the PostgREST search path, which is possible thanks to postgres transactional DDL:

```sql
begin;
drop schema old_schema;
alter role authenticator set pgrst.db_schemas = 'public, pg_graphql, others'; -- make sure old_schema is not present here
commit;
```

## Try it out

PostgREST v13 is now available for all new projects on the Supabase platform, old projects can upgrade to get this new version.

You can look at the full changelog on the [release notes](https://github.com/PostgREST/postgrest/releases/tag/v13.0.0).
Loading
Loading