chore(studio): remove region limitation for vector buckets (#48248)

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Remove the region limitation on vector buckets

## What is the current behavior?

Currently vector buckets are limited to a subset of Supabase regions

## What is the new behavior?

All supabase regions now have access to vector buckets

## Additional context




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Vector buckets are now available based solely on platform enablement,
without region-based restrictions.

* **Bug Fixes**
* Removed the region limitation message and related region availability
checks from the Storage Vectors page.
* Updated vector bucket upgrade behavior to reflect platform
availability more consistently.

* **Tests**
* Updated coverage to reflect the simplified platform-based availability
behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Tyler Hillery authored and GitHub committed 2026-07-24 07:54:07 -07:00
1 parent 99fd5d0117
commit 74a57861b3
3 files changed
+5 -128

No files matched your search

@@ -1,74 +0,0 @@
import { VectorBucket } from 'icons'
import { AWS_REGIONS } from 'shared-data'
import { Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns/EmptyStatePresentational'
import { PageContainer } from 'ui-patterns/PageContainer'
import { PageSection, PageSectionContent } from 'ui-patterns/PageSection'
import { AVAILABLE_REPLICA_REGIONS } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.constants'
import { AlphaNotice } from '@/components/ui/AlphaNotice'
import { InlineLinkClassName } from '@/components/ui/InlineLink'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
export const VECTOR_BUCKETS_AVAILABLE_REGIONS = [
'us-east-1',
'us-east-2',
'us-west-2',
'eu-central-1',
'ap-southeast-2',
]
const getRegionNameFromCode = (code: string) =>
Object.values(AWS_REGIONS).find((x) => x.code === code)?.displayName
export const RegionLimitation = () => {
const { data: project } = useSelectedProjectQuery()
const regionLabel = AVAILABLE_REPLICA_REGIONS.find((region) =>
project?.region?.includes(region.region)
)
return (
<PageContainer>
<PageSection>
<PageSectionContent className="flex flex-col gap-y-8">
<AlphaNotice
entity="Vector buckets"
feedbackUrl="https://github.com/orgs/supabase/discussions/40815"
/>
<EmptyStatePresentational
icon={VectorBucket}
className="[&>div>div>h3]:flex [&>div>div>h3]:items-center [&>div>div>h3]:gap-x-2"
title="Coming soon to your project's region"
description={
<>
Your project is in{' '}
<Tooltip>
<TooltipTrigger className={InlineLinkClassName}>
{regionLabel?.name}
</TooltipTrigger>
<TooltipContent side="bottom">{regionLabel?.region}</TooltipContent>
</Tooltip>
, but Vector buckets are only available for{' '}
<Tooltip>
<TooltipTrigger className={InlineLinkClassName}>certain regions</TooltipTrigger>
<TooltipContent side="bottom">
<ul>
{VECTOR_BUCKETS_AVAILABLE_REGIONS.map((x) => (
<li key={x}>
<span>{getRegionNameFromCode(x)}</span>
<span className="text-foreground-light ml-2">{x}</span>
</li>
))}
</ul>
</TooltipContent>
</Tooltip>
. We're actively looking to expand that soon.
</>
}
/>
</PageSectionContent>
</PageSection>
</PageContainer>
)
}
@@ -2,30 +2,17 @@ import { IS_PLATFORM, useParams } from 'common'
import { BucketsUpgradePlan } from '@/components/interfaces/Storage/BucketsUpgradePlan'
import { VectorsBuckets } from '@/components/interfaces/Storage/VectorBuckets'
import {
RegionLimitation,
VECTOR_BUCKETS_AVAILABLE_REGIONS,
} from '@/components/interfaces/Storage/VectorBuckets/RegionLimitation'
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
import { StorageBucketsLayout } from '@/components/layouts/StorageLayout/StorageBucketsLayout'
import StorageLayout from '@/components/layouts/StorageLayout/StorageLayout'
import { useIsVectorBucketsEnabled } from '@/data/config/project-storage-config-query'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import type { NextPageWithLayout } from '@/types'
const StorageVectorsPage: NextPageWithLayout = () => {
const { ref: projectRef } = useParams()
const { data: project } = useSelectedProjectQuery()
const isVectorBucketsEnabled = useIsVectorBucketsEnabled({ projectRef })
// [Joshen] We're actively looking into lifting this restriction so can remove once done
const isAvailableInProjectRegion = VECTOR_BUCKETS_AVAILABLE_REGIONS.includes(
project?.region ?? ''
)
if (IS_PLATFORM && !isAvailableInProjectRegion) {
return <RegionLimitation />
} else if (IS_PLATFORM && !isVectorBucketsEnabled) {
if (IS_PLATFORM && !isVectorBucketsEnabled) {
return <BucketsUpgradePlan type="vector" />
} else if (!isVectorBucketsEnabled) {
return null
@@ -3,7 +3,6 @@ import { http, HttpResponse } from 'msw'
import { beforeEach, describe, expect, test, vi } from 'vitest'
import type { ProjectStorageConfigData } from '@/data/config/project-storage-config-query'
import type { ProjectDetail } from '@/data/projects/project-detail-query'
import { API_URL } from '@/lib/constants'
import StorageVectorsPage from '@/pages/project/[ref]/storage/vectors'
import { customRender } from '@/tests/lib/custom-render'
@@ -39,16 +38,7 @@ vi.mock('@/lib/constants', async (importOriginal) => {
})
// Stub the heavy leaf children — each fires its own queries and renders a large
// tree. We only assert which branch the page picks. Keep the real
// `VECTOR_BUCKETS_AVAILABLE_REGIONS` so the region gate runs for real.
vi.mock(
'@/components/interfaces/Storage/VectorBuckets/RegionLimitation',
async (importOriginal) => ({
...(await importOriginal<Record<string, unknown>>()),
RegionLimitation: () => <div>region-limitation</div>,
})
)
// tree. We only assert which branch the page picks.
vi.mock('@/components/interfaces/Storage/VectorBuckets', () => ({
VectorsBuckets: () => <div>vectors-buckets</div>,
}))
@@ -57,18 +47,6 @@ vi.mock('@/components/interfaces/Storage/BucketsUpgradePlan', () => ({
BucketsUpgradePlan: ({ type }: { type: string }) => <div>buckets-upgrade-plan-{type}</div>,
}))
const AVAILABLE_REGION = 'us-east-1'
const UNAVAILABLE_REGION = 'ap-south-1'
const mockProject = (region: string) => {
addAPIMock({
method: 'get',
path: '/platform/projects/:ref',
// The page only reads `region` off the project
response: () => HttpResponse.json<ProjectDetail>({ region } as unknown as ProjectDetail),
})
}
const mockStorageConfig = (vectorBucketsEnabled: boolean) => {
addAPIMock({
method: 'get',
@@ -99,20 +77,9 @@ const mockDeploymentMode = (isCli: boolean) => {
describe('StorageVectorsPage', () => {
beforeEach(() => {
mockIsPlatform.value = true
mockProject(AVAILABLE_REGION)
})
test('platform + region not supported: shows region limitation', async () => {
mockProject(UNAVAILABLE_REGION)
mockStorageConfig(true)
customRender(<StorageVectorsPage dehydratedState={undefined} />)
expect(await screen.findByText('region-limitation')).toBeInTheDocument()
expect(screen.queryByText('vectors-buckets')).not.toBeInTheDocument()
})
test('platform + supported region + not enabled: shows upgrade plan', async () => {
test('platform + not enabled: shows upgrade plan', async () => {
mockStorageConfig(false)
customRender(<StorageVectorsPage dehydratedState={undefined} />)
@@ -121,7 +88,7 @@ describe('StorageVectorsPage', () => {
expect(screen.queryByText('vectors-buckets')).not.toBeInTheDocument()
})
test('platform + supported region + enabled: shows vector buckets', async () => {
test('platform + enabled: shows vector buckets', async () => {
mockStorageConfig(true)
customRender(<StorageVectorsPage dehydratedState={undefined} />)
@@ -129,16 +96,13 @@ describe('StorageVectorsPage', () => {
expect(await screen.findByText('vectors-buckets')).toBeInTheDocument()
})
test('CLI (non-platform, enabled): shows vector buckets, skips region/upgrade gates', async () => {
test('CLI (non-platform, enabled): shows vector buckets, skips upgrade gate', async () => {
mockIsPlatform.value = false
// Even an unsupported region shouldn't gate off-platform
mockProject(UNAVAILABLE_REGION)
mockDeploymentMode(true)
customRender(<StorageVectorsPage dehydratedState={undefined} />)
expect(await screen.findByText('vectors-buckets')).toBeInTheDocument()
expect(screen.queryByText('region-limitation')).not.toBeInTheDocument()
})
test('self-hosted (non-platform): renders nothing', async () => {