mirror of
https://github.com/supabase/supabase.git
synced 2026-10-13 13:19:09 +03:00
Merge branch 'master' into fs/storage-ui-v2
This commit is contained in:
1029 files changed
+127506
-60162
No files matched your search
@@ -0,0 +1,253 @@
|
||||
---
|
||||
description: How to generate pages and interfaces in Studio, a web interface for managing Supabase projects
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
- Next.js app using pages router
|
||||
- Pages go in @apps/studio/pages
|
||||
- Project related pages go in @apps/studio/pages/projects/[ref]
|
||||
- Organization related pages go in @apps/studio/pages/org/[slug]
|
||||
- Studio specific components go in @apps/studio/components
|
||||
- Studio specific generic UI components go in @apps/studio/components/ui
|
||||
- Studio specific components related to individual pages go in @apps/studio/components/interfaces e.g. @apps/studio/components/interfaces/Auth
|
||||
- Generic helper functions go in @apps/studio/lib
|
||||
- Generic hooks go in @apps/studio/hooks
|
||||
|
||||
## Component system
|
||||
|
||||
Our primitive component system is in @packages/ui and is based off shadcn/ui components. These components can be shared across all @apps e.g. studio and docs. Do not introduce new ui components unless asked to.
|
||||
|
||||
- UI components are imported from this package across apps e.g. import { Button, Badge } from 'ui'
|
||||
- Some components have a _Shadcn_ namespace appended to component name e.g. import { Input*Shadcn* } from 'ui'
|
||||
- We should be using _Shadcn_ components where possible
|
||||
- Before composing interfaces, read @packages/ui/index.tsx file for a full list of available components
|
||||
|
||||
## Styling
|
||||
|
||||
We use Tailwind for styling.
|
||||
|
||||
- You should never use tailwind classes for colours and instead use classes we've defined ourselves
|
||||
- Backgrounds // most of the time you will not need to define a background
|
||||
- 'bg' used for main app surface background
|
||||
- 'bg-muted' for elevating content // you can use Card instead
|
||||
- 'bg-warning' for highlighting information that needs to be acted on
|
||||
- 'bg-destructive' for highlighting issues
|
||||
- Text
|
||||
- 'text-foreground' for primary text like headings
|
||||
- 'text-foreground-light' for body text
|
||||
- 'text-foreground-lighter' for subtle text
|
||||
- 'text-warning' for calling out information that needs action
|
||||
- 'text-destructive' for calling out when something went wrong
|
||||
- When needing to apply typography styles, read @apps/studio/styles/typography.scss and use one of the available classes instead of hard coding classes e.g. use "heading-default" instead of "text-sm font-medium"
|
||||
|
||||
## Page structure
|
||||
|
||||
When creating a new page follow these steps:
|
||||
|
||||
- Create the page in @apps/studio/pages
|
||||
- Use the PageLayout component that has the following props
|
||||
|
||||
```jsx
|
||||
export interface NavigationItem {
|
||||
id?: string
|
||||
label: string
|
||||
href?: string
|
||||
icon?: ReactNode
|
||||
onClick?: () => void
|
||||
badge?: string
|
||||
active?: boolean
|
||||
}
|
||||
|
||||
interface PageLayoutProps {
|
||||
children?: ReactNode
|
||||
title?: string | ReactNode
|
||||
subtitle?: string | ReactNode
|
||||
icon?: ReactNode
|
||||
breadcrumbs?: Array<{
|
||||
label?: string
|
||||
href?: string
|
||||
element?: ReactNode
|
||||
}>
|
||||
primaryActions?: ReactNode
|
||||
secondaryActions?: ReactNode
|
||||
navigationItems?: NavigationItem[]
|
||||
className?: string
|
||||
size?: 'default' | 'full' | 'large' | 'small'
|
||||
isCompact?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
- If a page has page related actions, add them to primary and secondary action props e.g. Users page has "Create new user" action
|
||||
- If a page is within an existing section (e.g. Auth), you should use the related layout component e.g. AuthLayout
|
||||
- Create a new component in @apps/studio/components/interfaces for the contents of the page
|
||||
- Use ScaffoldContainer if the page should be center aligned in a container
|
||||
- Use ScaffoldSection, ScaffoldSectionTitle, ScaffoldSectionDescription if the page has multiple sections
|
||||
|
||||
### Page example
|
||||
|
||||
```jsx
|
||||
import { MyPageComponent } from 'components/interfaces/MyPage/MyPageComponent'
|
||||
import AuthLayout from './AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const MyPage: NextPageWithLayout = () => {
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
<MyPageComponent />
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
MyPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<AuthLayout>{page}</AuthLayout>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
export default MyPage
|
||||
|
||||
export const MyPageComponent = () => (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<div>
|
||||
<ScaffoldSectionTitle>My page section</ScaffoldSectionTitle>
|
||||
<ScaffoldSectionDescription>A brief description of the purpose of the page</ScaffoldSectionDescription>
|
||||
</div>
|
||||
// Content goes here
|
||||
</ScaffoldSection>
|
||||
)
|
||||
```
|
||||
|
||||
## Forms
|
||||
|
||||
- Build forms with `react-hook-form` + `zod`.
|
||||
- Use our `_Shadcn_` form primitives from `ui` and prefer `FormItemLayout` with layout="flex-row-reverse" for most controls (see `apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx`).
|
||||
- Keep imports from `ui` with `_Shadcn_` suffixes.
|
||||
- Forms should generally be wrapped in a Card unless specified
|
||||
|
||||
### Example (single field)
|
||||
|
||||
```tsx
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import * as z from 'zod'
|
||||
|
||||
import { Button, Form_Shadcn_, FormField_Shadcn_, FormControl_Shadcn_, Input_Shadcn_ } from 'ui'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
|
||||
const profileSchema = z.object({
|
||||
username: z.string().min(2, 'Username must be at least 2 characters'),
|
||||
})
|
||||
|
||||
export function ProfileForm() {
|
||||
const form = useForm<z.infer<typeof profileSchema>>({
|
||||
resolver: zodResolver(profileSchema),
|
||||
defaultValues: { username: '' },
|
||||
mode: 'onSubmit',
|
||||
reValidateMode: 'onBlur',
|
||||
})
|
||||
|
||||
function onSubmit(values: z.infer<typeof profileSchema>) {
|
||||
// handle values
|
||||
}
|
||||
|
||||
return (
|
||||
<Form_Shadcn_ {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<Card>
|
||||
<CardContent className="space-y-6">
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
layout="flex-row-reverse"
|
||||
label="Username"
|
||||
description="This is your public display name."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_ placeholder="shadcn" autoComplete="off" {...field} />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</CardContent>
|
||||
<CardFooter className="justify-end">
|
||||
<Button type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</form>
|
||||
</Form_Shadcn_>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Cards
|
||||
|
||||
- Use cards when needing to group related pieces of information
|
||||
- Cards can have sections with CardContent
|
||||
- Use CardFooter for actions
|
||||
- Only use CardHeader and CardTitle if the card content has not been described by the surrounding content e.g. Page title or ScaffoldSectionTitle
|
||||
- Use CardHeader and CardTitle when you are using multiple Cards to group related pieces of content e.g. Primary branch, Persistent branches, Preview branches
|
||||
|
||||
## Sheets
|
||||
|
||||
- Use a sheet when needing to reveal more complicated forms or information relating to an object and context switching away to a new page would be disruptive e.g. we list auth providers, clicking an auth provider opens a sheet with information about that provider and a form to enable, user can close sheet to go back to providers list
|
||||
|
||||
## Tables
|
||||
|
||||
- Use the generic ui table components for most tables
|
||||
- Tables are generally contained witin a card
|
||||
- If a table has associated actions, they should go above on right hand side
|
||||
- If a table has associated search or filters, they should go above on left hand side
|
||||
- If a table is the main content of a page, and it does not have search or filters, you can add table actions to primary and secondary actions of PageLayout
|
||||
- If a table is the main content of a page section, and it does not have search or filters, you can add table actions to the right of ScaffoldSectionTitle
|
||||
- For simple lists of objects you can use ResourceList with ResourceListItem instead
|
||||
|
||||
### Table example
|
||||
|
||||
```jsx
|
||||
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from 'ui'
|
||||
|
||||
;<Table>
|
||||
<TableCaption>A list of your recent invoices.</TableCaption>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Method</TableHead>
|
||||
<TableHead className="text-right">Amount</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium">INV001</TableCell>
|
||||
<TableCell>Paid</TableCell>
|
||||
<TableCell>Credit Card</TableCell>
|
||||
<TableCell className="text-right">$250.00</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
```
|
||||
|
||||
## Alerts
|
||||
|
||||
- Use Admonition component to alert users of important actions or restrictions in place
|
||||
- Place the Admonition either at the top of the contents of the page (below page title) or at the top of the related ScaffoldSection , below ScaffoldTitle
|
||||
- Use sparingly
|
||||
|
||||
### Alert example
|
||||
|
||||
```jsx
|
||||
<Admonition
|
||||
type="note"
|
||||
title="No authentication logs available for this user"
|
||||
description="Auth events such as logging in will be shown here"
|
||||
/>
|
||||
```
|
||||
@@ -15,6 +15,5 @@
|
||||
|
||||
/apps/studio/csp.js @supabase/security
|
||||
/apps/studio/components/interfaces/Billing/Payment @supabase/security
|
||||
/apps/studio/components/interfaces/Organization/BillingSettings/ @supabase/security
|
||||
/apps/studio/components/interfaces/Organization/Documents/ @supabase/security
|
||||
/apps/studio/pages/new/index.tsx @supabase/security
|
||||
@@ -0,0 +1,5 @@
|
||||
# Add 'documentation' to any change in apps/docs
|
||||
# https://github.com/marketplace/actions/labeler
|
||||
documentation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'apps/docs/**/*'
|
||||
@@ -22,7 +22,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
|
||||
@@ -15,7 +15,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
autofix:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
permissions:
|
||||
contents: write
|
||||
if: ${{ github.event_name == 'pull_request' && (github.event.label.name == 'autofix') }}
|
||||
|
||||
@@ -14,7 +14,7 @@ permissions:
|
||||
jobs:
|
||||
misspell:
|
||||
name: runner / misspell
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Check out code.
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -15,7 +15,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
env:
|
||||
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.SEARCH_SUPABASE_URL }}
|
||||
|
||||
@@ -20,7 +20,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
comment_on_pr:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure'
|
||||
steps:
|
||||
- id: download_artifact
|
||||
|
||||
@@ -13,7 +13,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
lint-all:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -31,10 +31,10 @@ jobs:
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
key: 3186b58a532c98d7f470f2b887c2b74a086d5f2e
|
||||
key: 301e0d4b35f8f0c8553b4e93917b8b2685ef2627
|
||||
- name: install linter
|
||||
if: steps.cache-cargo.outputs.cache-hit != 'true'
|
||||
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 3186b58a532c98d7f470f2b887c2b74a086d5f2e
|
||||
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 301e0d4b35f8f0c8553b4e93917b8b2685ef2627
|
||||
- name: run linter
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -26,7 +26,7 @@ permissions:
|
||||
jobs:
|
||||
supa-mdx-lint:
|
||||
name: supa-mdx-lint
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -53,10 +53,10 @@ jobs:
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
key: 3186b58a532c98d7f470f2b887c2b74a086d5f2e
|
||||
key: 301e0d4b35f8f0c8553b4e93917b8b2685ef2627
|
||||
- name: install linter
|
||||
if: steps.filter.outputs.docs == 'true' && steps.cache-cargo.outputs.cache-hit != 'true'
|
||||
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 3186b58a532c98d7f470f2b887c2b74a086d5f2e
|
||||
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 301e0d4b35f8f0c8553b4e93917b8b2685ef2627
|
||||
- name: install reviewdog
|
||||
if: steps.filter.outputs.docs == 'true'
|
||||
uses: reviewdog/action-setup@3f401fe1d58fe77e10d665ab713057375e39b887 # v1.3.0
|
||||
|
||||
@@ -12,7 +12,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
update-docs:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -14,7 +14,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
update-troubleshooting:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
env:
|
||||
DOCS_GITHUB_APP_ID: ${{ secrets.SEARCH_GITHUB_APP_ID }}
|
||||
|
||||
@@ -19,7 +19,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
env:
|
||||
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.SEARCH_SUPABASE_URL }}
|
||||
|
||||
@@ -16,7 +16,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -5,6 +5,7 @@ on:
|
||||
branches: ['master']
|
||||
paths:
|
||||
- 'apps/docs/**/*.ts*'
|
||||
- 'apps/docs/spec/**/*.json'
|
||||
|
||||
# Cancel old builds on new commit for same workflow + branch/PR
|
||||
concurrency:
|
||||
@@ -19,7 +20,7 @@ env:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
name: 'Pull Request Labeler'
|
||||
|
||||
# only docs uses the labeler at the moment
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- 'apps/docs/**/*'
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v6
|
||||
@@ -21,7 +21,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -15,7 +15,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v4
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
|
||||
# i18n is not a node package, so we handle that one separately
|
||||
format-i18n:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v4
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
pnpm exec prettier -c 'i18n/**/*.{js,jsx,ts,tsx,css,md,mdx,json}'
|
||||
|
||||
format-sql:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
settings:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
outputs:
|
||||
image_version: ${{ steps.meta.outputs.version }}
|
||||
steps:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
release_x86:
|
||||
needs: settings
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
arch: amd64
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
- settings
|
||||
- release_x86
|
||||
- release_arm
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
env:
|
||||
DOCS_GITHUB_APP_ID: ${{ secrets.SEARCH_GITHUB_APP_ID }}
|
||||
|
||||
@@ -16,7 +16,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -26,8 +26,7 @@ permissions:
|
||||
jobs:
|
||||
test:
|
||||
# Uses larger hosted runner as it significantly decreases build times
|
||||
runs-on:
|
||||
group: Default Larger Runners
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
strategy:
|
||||
matrix:
|
||||
test_number: [1]
|
||||
@@ -69,7 +68,7 @@ jobs:
|
||||
finish:
|
||||
needs: test
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
|
||||
@@ -16,8 +16,7 @@ permissions:
|
||||
jobs:
|
||||
typecheck:
|
||||
# Uses larger hosted runner as it significantly decreases build times
|
||||
runs-on:
|
||||
group: Default Larger Runners
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -16,7 +16,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -16,7 +16,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
strategy:
|
||||
matrix:
|
||||
test_number: [1]
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
finish:
|
||||
needs: test
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
|
||||
@@ -47,10 +47,6 @@ const nextConfig = {
|
||||
// We are already running linting via GH action, this will skip linting during production build on Vercel
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
experimental: {
|
||||
// Ensure compatibility with Turbopack and Sharp
|
||||
serverComponentsExternalPackages: ['sharp'],
|
||||
},
|
||||
// Configure Sharp as an external package for server-side rendering
|
||||
serverExternalPackages: ['sharp'],
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||
"migrate": "cross-env NODE_OPTIONS=--no-deprecation tsx scripts/migrate.ts",
|
||||
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start --port 3030",
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
|
||||
"vercel-build": "pnpm migrate && pnpm build",
|
||||
"typecheck_IGNORED": "tsc --noEmit"
|
||||
},
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -1,8 +0,0 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
@@ -102,7 +102,7 @@ export default buildConfig({
|
||||
// Global configuration for better performance
|
||||
globals: [],
|
||||
graphQL: {
|
||||
disable: process.env.NODE_ENV !== 'development', // Disable GraphQL in production for better performance
|
||||
disable: true,
|
||||
},
|
||||
// Reduce payload init overhead
|
||||
telemetry: false,
|
||||
|
||||
@@ -1,46 +1,31 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
# Supabase Design System
|
||||
|
||||
Design resources for building consistent user experiences at Supabase.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
First, make a copy of _.env.local.example_ and name it _env.local_. Then run the development server as described below.
|
||||
|
||||
From within this _design-system_ directory, run:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Or from the root directory run:
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
```bash
|
||||
pnpm dev:design-system
|
||||
```
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
Open [http://localhost:3003](http://localhost:3003) with your browser to see the result.
|
||||
|
||||
### Watching for MDX changes
|
||||
|
||||
If you would like to watch for changes to MDX files with hot reload, you can run the following command in a separate Terminal shell:
|
||||
If you would like to watch for changes to MDX files with hot reload, you can run the following command in a separate terminal shell:
|
||||
|
||||
```
|
||||
pnpm content:dev
|
||||
```
|
||||
|
||||
This runs Contentlayer concurrently and watches for any changes.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
@@ -8,7 +8,7 @@ const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Supabase Design System',
|
||||
description: 'Generated by create next app',
|
||||
description: 'Design resources for building consistent user experiences at Supabase.',
|
||||
}
|
||||
|
||||
interface RootLayoutProps {
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
import { cn } from 'ui/src/lib/utils/cn'
|
||||
// import { Card } from '@ui/components/shadcn/ui/card'
|
||||
import color from 'ui/src/lib/tailwind-demo-classes'
|
||||
import { Grid, GridItem } from './grid'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Colors = ({
|
||||
definition,
|
||||
}: {
|
||||
definition: 'background' | 'border' | 'text' | 'colors' | 'palletes'
|
||||
}) => {
|
||||
const [copiedIndex, setCopiedIndex] = useState<number | null>(null)
|
||||
|
||||
const handleCopy = async (value: string, index: number) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(value)
|
||||
setCopiedIndex(index)
|
||||
setTimeout(() => {
|
||||
setCopiedIndex(null)
|
||||
}, 2000)
|
||||
} catch (err) {
|
||||
console.error('Failed to copy text: ', err)
|
||||
}
|
||||
}
|
||||
const Example = ({ x }: { x: string }) => {
|
||||
switch (definition) {
|
||||
case 'background':
|
||||
@@ -53,10 +66,11 @@ const Colors = ({
|
||||
<GridItem
|
||||
key={i}
|
||||
className={cn(x.includes('contrast') && 'bg-foreground hover:bg-foreground-light')}
|
||||
onClick={() => handleCopy(x, i)}
|
||||
>
|
||||
<Example x={x} />
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground">
|
||||
{x}
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground text-center">
|
||||
{copiedIndex === i ? 'Copied!' : x}
|
||||
</span>
|
||||
</GridItem>
|
||||
)
|
||||
@@ -66,90 +80,4 @@ const Colors = ({
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
/* <div className="flex flex-col gap-12 py-20">
|
||||
<div className="flex flex-row gap-12">
|
||||
<div>
|
||||
<h5 className="mb-3">Background</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.background.map((x: string, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">Border</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.border.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border-4')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">texts</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.text.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<span className={cn(x, 'relative w-12 h-12 flex items-center justify-center')}>
|
||||
###
|
||||
</span>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row gap-12">
|
||||
<div>
|
||||
<h5 className="mb-3">Colors</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.colors.map((x: string, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">Palletes</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.palletes.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */
|
||||
}
|
||||
|
||||
export { Colors }
|
||||
@@ -38,13 +38,13 @@ export const docsConfig: DocsConfig = {
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Color usage',
|
||||
href: '/docs/color-usage',
|
||||
title: 'Tailwind Classes',
|
||||
href: '/docs/tailwind-classes',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Tailwind classes',
|
||||
href: '/docs/tailwind-classes',
|
||||
title: 'Color Usage',
|
||||
href: '/docs/color-usage',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,13 @@ description: Latest updates and announcements.
|
||||
toc: false
|
||||
---
|
||||
|
||||
## 1st Sep 2025 - Update button styles
|
||||
|
||||
- [`Color usage`](/design-system/docs/color-usage) page updated
|
||||
- Color tokens improved for accessibility
|
||||
|
||||
[PR](https://github.com/supabase/supabase/pull/38343)
|
||||
|
||||
## 18th Oct 2024 - Update multi-select
|
||||
|
||||
Improved Multi Select with combobox, badge limit, and more examples.
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
---
|
||||
title: Color usage
|
||||
description: Colors system breakdown with best practice
|
||||
description: Colors system breakdown with best practices.
|
||||
---
|
||||
|
||||
Colors available in the Supabase Design System
|
||||
The shorthand utility classes below simplify our full color palette by providing sensible, contrast-checked defaults. Use them whenever possible to ensure accessible text colors and balanced background fills.
|
||||
|
||||
These are examples of using colors with shorthands.
|
||||
## Text
|
||||
|
||||
Use accent text colors (e.g. text-destructive, text-warning) sparingly to avoid visual overload.
|
||||
|
||||
<Colors definition={'text'} />
|
||||
|
||||
## Background
|
||||
|
||||
@@ -60,15 +64,8 @@ This is not to be confused with `Dialogs`, they require to use the same app back
|
||||
|
||||
<Colors definition={'border'} />
|
||||
|
||||
## Text
|
||||
|
||||
These can also be accessed with `foreground`. Like `text-foreground-light`.
|
||||
|
||||
<Colors definition={'text'} />
|
||||
|
||||
## Other Colors
|
||||
|
||||
These can also be accessed with `foreground`. Like `text-foreground-light`.
|
||||
|
||||
<Colors definition={'colors'} />
|
||||
```
|
||||
@@ -1,37 +1,37 @@
|
||||
---
|
||||
title: Tailwind Classes
|
||||
description: Icons system breakdown. Copy values of Icons.
|
||||
description: Theming support for Tailwind classes.
|
||||
---
|
||||
|
||||
Supabase is migrating to use tailwind classes that use CSS properties.
|
||||
Supabase uses Tailwind classes that in turn use CSS properties.
|
||||
This is to support the concept of theming, so that:
|
||||
|
||||
1. It is easy for the team to update the theme without changing 100s of files.
|
||||
2. We could offer custom or additional themes in future.
|
||||
1. We can update themes from one place.
|
||||
2. We can offer custom or additional themes in the future.
|
||||
|
||||
## Primitives
|
||||
|
||||
We (the Supabase Design team ✨) define primitive color values using Figma Variables.
|
||||
We define primitive color values using these tokens:
|
||||
|
||||
- `background`
|
||||
- `foreground`
|
||||
- `border`
|
||||
- `brand`
|
||||
- `destructive`
|
||||
- `warning`
|
||||
- `destructive`
|
||||
|
||||
These values are exported from Figma as a .json file and transformed into tailwind utilities through some scripts under `packages/ui/internals/tokens`.
|
||||
These values are exported from Figma as a .json file and transformed into Tailwind utilities through some scripts under `packages/ui/internals/tokens`.
|
||||
|
||||
Any of these colors are available on any tailwind utility that accepts color. For example:
|
||||
Any of these colors are available on any Tailwind utility that accepts color. For example:
|
||||
|
||||
```jsx
|
||||
// this uses the default foreground color
|
||||
// this uses the default foreground color for this theme
|
||||
<span className="text-foreground"></span>
|
||||
|
||||
// this uses the 'light' foreground color
|
||||
// this uses the 'light' foreground color for this theme (one notch 'softer' than the default)
|
||||
<span className="text-foreground-light"></span>
|
||||
|
||||
// this uses the default warning color
|
||||
// this uses the default warning color for this theme
|
||||
<span className="text-warning"></span>
|
||||
|
||||
// this uses the '500' warning color
|
||||
@@ -48,12 +48,12 @@ We support shorthand classes for `background`, `foreground` and `border`. For ex
|
||||
|
||||
This will stop you from needing to 'double type' the same utility name.
|
||||
|
||||
You might notice we use `foreground` and `background` as prefixes, this is only because it is a Design Token standard, where as tailwind uses `bg` and `text`.
|
||||
You might notice we use `foreground` and `background` as prefixes, this is only because it is a Design Token standard, where as Tailwind uses `bg` and `text`.
|
||||
|
||||
## Mixing colors
|
||||
|
||||
Even with shorthands, remember you can use any color. For example, `foreground-light` can also be applied on borders and backgrounds as `border-foreground-light` and `bg-foreground-light`, if needed.
|
||||
Similarly, background and border primitives can be used on other tailwind utilities.
|
||||
Similarly, background and border primitives can be used on other Tailwind utilities.
|
||||
|
||||
```jsx
|
||||
// use the text light color for some text
|
||||
@@ -61,13 +61,13 @@ Similarly, background and border primitives can be used on other tailwind utilit
|
||||
|
||||
// we can use the same color for a background
|
||||
<div className="bg-foreground-light">
|
||||
<span>I have the same color background as the left example</span>
|
||||
<span>I have the same background color as the above example</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Opacity support
|
||||
|
||||
All the colors are generated using tailwind opacity, like `hsl(--background-default) / var(--tw-bg-opacity)`.
|
||||
All colors are generated using Tailwind opacity, like `hsl(--background-default) / var(--tw-bg-opacity)`.
|
||||
This means all the color options in our themes can support opacity rules. For example:
|
||||
|
||||
```jsx
|
||||
@@ -82,7 +82,9 @@ This means all the color options in our themes can support opacity rules. For ex
|
||||
|
||||
## Usage
|
||||
|
||||
The following tailwind classes are a combination of tailwind utilities and our primitives. They're under development and are likely to change but most are now in use and will probably be permanent fixtures.
|
||||
The following Tailwind classes are a combination of Tailwind utilities and our primitives.
|
||||
|
||||
Note that the shade of the `DEFAULT` value on each scale pattern is variable. Sometimes it is fixed at a particular shade (such as `500` or `600`), but only when contrast is sufficient.
|
||||
|
||||
### Foreground (Text)
|
||||
|
||||
@@ -118,7 +120,7 @@ Examples:
|
||||
| `background-control` | Inputs, Radios, Checkboxes |
|
||||
| `background-button-{DEFAULT}` | Button default |
|
||||
|
||||
The `background` part can be omitted when used on the `bg` tailwind utility.
|
||||
The `background` part can be omitted when used on the `bg` Tailwind utility.
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "next dev --turbopack --port 3003",
|
||||
"build": "pnpm run content:build && pnpm run build:registry && next build",
|
||||
"build": "pnpm run content:build && pnpm run build:registry && next build --turbopack",
|
||||
"build:registry": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/build-registry.mts && prettier --log-level silent --write \"registry/**/*.{ts,tsx,mdx}\" --cache",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
|
||||
@@ -14,7 +14,7 @@ function CustomDatePicker({ onChange, onCancel, search }: CustomOptionProps) {
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="w-full space-y-4">
|
||||
<div className="w-[300px] space-y-4">
|
||||
<Calendar
|
||||
initialFocus
|
||||
mode="range"
|
||||
|
||||
@@ -354,11 +354,11 @@ Some guides and tutorials will require that users copy their Supabase project UR
|
||||
|
||||
```mdx
|
||||
<ProjectConfigVariables variable="url" />
|
||||
<ProjectConfigVariables variable="anonKey" />
|
||||
<ProjectConfigVariables variable="publishableKey" />
|
||||
```
|
||||
|
||||
<ProjectConfigVariables variable="url" />
|
||||
<ProjectConfigVariables variable="anonKey" />
|
||||
<ProjectConfigVariables variable="publishableKey" />
|
||||
|
||||
### Step Hike
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="Explore more resources"
|
||||
url="/guides/resources"
|
||||
className="no-underline text-brand text-sm"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -328,7 +328,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="More on Self-Hosting"
|
||||
url="/guides/self-hosting"
|
||||
className="no-underline text-brand text-sm"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,6 +33,10 @@ export default async function ReferencePage(props: { params: Promise<{ slug: Arr
|
||||
const { sdkId, maybeVersion, path } = parsedPath
|
||||
|
||||
const sdkData = REFERENCES[sdkId]
|
||||
if (sdkData.enabled === false) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const latestVersion = sdkData.versions[0]
|
||||
const version = maybeVersion ?? latestVersion
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
'[transition-property:opacity,transform,color] [transition-duration:150ms,250ms,250ms]',
|
||||
'motion-reduce:[transition-duration:150ms,1ms,300ms]',
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
!isNo && 'hover:text-warning-600 hover:border-warning-500',
|
||||
!isNo && 'hover:text-warning hover:border-warning-500',
|
||||
isNo && `bg-warning text-warning-200 !border-warning disabled:opacity-100`,
|
||||
!showNo && 'opacity-0 invisible'
|
||||
)}
|
||||
|
||||
@@ -58,7 +58,7 @@ function FeedbackModal({ visible, page, onCancel, onSubmit }: FeedbackModalProps
|
||||
href="https://supabase.com/dashboard/support/new"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand hover:underline"
|
||||
className="text-brand-link hover:underline"
|
||||
>
|
||||
support request
|
||||
</a>
|
||||
|
||||
@@ -20,7 +20,7 @@ function AiPrompt({ className }: { className?: string }) {
|
||||
className={cn(
|
||||
'group',
|
||||
'w-fit rounded-full border px-3 py-1 flex gap-2 items-center text-foreground-light text-sm',
|
||||
'hover:border-brand hover:text-brand focus-visible:text-brand',
|
||||
'hover:border-brand hover:text-brand-link focus-visible:text-brand-link',
|
||||
'transition-colors',
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -11,6 +11,9 @@ export interface NavMenuSection {
|
||||
name: string
|
||||
url?: `/${string}` | `https://${string}`
|
||||
items: Partial<NavMenuSection>[]
|
||||
icon?: string
|
||||
hasLightIcon?: boolean
|
||||
isDarkMode?: boolean
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { ComponentProps } from 'react'
|
||||
|
||||
import { isFeatureEnabled } from 'common'
|
||||
import { isFeatureEnabled } from 'common/enabled-features'
|
||||
import type { IconPanel } from 'ui-patterns/IconPanel'
|
||||
import type { GlobalMenuItems, NavMenuConstant, NavMenuSection } from '../Navigation.types'
|
||||
|
||||
const {
|
||||
authenticationShowProviders: allAuthProvidersEnabled,
|
||||
billingAll: billingEnabled,
|
||||
docsCompliance: complianceEnabled,
|
||||
'docsSelf-hosting': selfHostingEnabled,
|
||||
sdkCsharp: sdkCsharpEnabled,
|
||||
sdkDart: sdkDartEnabled,
|
||||
@@ -16,6 +17,7 @@ const {
|
||||
} = isFeatureEnabled([
|
||||
'authentication:show_providers',
|
||||
'billing:all',
|
||||
'docs:compliance',
|
||||
'docs:self-hosting',
|
||||
'sdk:csharp',
|
||||
'sdk:dart',
|
||||
@@ -460,7 +462,7 @@ export const NativeMobileLoginItems = [
|
||||
},
|
||||
]
|
||||
|
||||
export const SocialLoginItems = [
|
||||
export const SocialLoginItems: Array<Partial<NavMenuSection>> = [
|
||||
{
|
||||
name: 'Google',
|
||||
icon: '/docs/img/icons/google-icon',
|
||||
@@ -591,7 +593,7 @@ export const PhoneLoginsItems = [
|
||||
},
|
||||
]
|
||||
|
||||
export const auth = {
|
||||
export const auth: NavMenuConstant = {
|
||||
icon: 'auth',
|
||||
title: 'Auth',
|
||||
items: [
|
||||
@@ -697,7 +699,7 @@ export const auth = {
|
||||
enabled: allAuthProvidersEnabled,
|
||||
},
|
||||
{
|
||||
name: 'Web3 (Sign in with Solana)',
|
||||
name: 'Web3 (Ethereum or Solana)',
|
||||
url: '/guides/auth/auth-web3',
|
||||
enabled: allAuthProvidersEnabled,
|
||||
},
|
||||
@@ -791,6 +793,7 @@ export const auth = {
|
||||
{ name: 'Password Security', url: '/guides/auth/password-security' },
|
||||
{ name: 'Rate Limits', url: '/guides/auth/rate-limits' },
|
||||
{ name: 'Bot Detection (CAPTCHA)', url: '/guides/auth/auth-captcha' },
|
||||
{ name: 'Audit Logs', url: '/guides/auth/audit-logs' },
|
||||
{
|
||||
name: 'JSON Web Tokens (JWT)',
|
||||
url: '/guides/auth/jwts',
|
||||
@@ -1440,6 +1443,10 @@ export const functions: NavMenuConstant = {
|
||||
name: 'Development Environment',
|
||||
url: '/guides/functions/development-environment' as `/${string}`,
|
||||
},
|
||||
{
|
||||
name: 'Architecture',
|
||||
url: '/guides/functions/architecture',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -1865,7 +1872,7 @@ export const storage: NavMenuConstant = {
|
||||
],
|
||||
}
|
||||
|
||||
export const vectorIndexItems = [
|
||||
export const vectorIndexItems: Array<Partial<NavMenuSection>> = [
|
||||
{
|
||||
name: 'HNSW indexes',
|
||||
url: '/guides/ai/vector-indexes/hnsw-indexes',
|
||||
@@ -1876,7 +1883,7 @@ export const vectorIndexItems = [
|
||||
},
|
||||
]
|
||||
|
||||
export const ai = {
|
||||
export const ai: NavMenuConstant = {
|
||||
icon: 'ai',
|
||||
title: 'AI & Vectors',
|
||||
url: '/guides/ai',
|
||||
@@ -2188,6 +2195,7 @@ export const security: NavMenuConstant = {
|
||||
{
|
||||
name: 'Compliance',
|
||||
url: undefined,
|
||||
enabled: complianceEnabled,
|
||||
items: [
|
||||
{ name: 'SOC 2', url: '/guides/security/soc-2-compliance' },
|
||||
{ name: 'HIPAA', url: '/guides/security/hipaa-compliance' },
|
||||
|
||||
@@ -22,7 +22,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
<li key={id} className="function-link-item text-foreground-lighter leading-3">
|
||||
<Link
|
||||
href={`#${id}`}
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand flex gap-3"
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand-link flex gap-3"
|
||||
>
|
||||
{icon && <img className="w-3" src={`${BASE_PATH}${icon}`} />}
|
||||
{title}
|
||||
@@ -99,7 +99,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
href={`${menu.parent ?? '/'}`}
|
||||
className={[
|
||||
'flex items-center gap-1 text-xs group mb-3',
|
||||
'text-base transition-all duration-200 text-brand hover:text-brand-600 hover:cursor-pointer ',
|
||||
'text-base transition-all duration-200 text-brand-link hover:text-brand-600 hover:cursor-pointer ',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="relative w-2">
|
||||
|
||||
@@ -19,7 +19,7 @@ const HeaderLink = React.memo(function HeaderLink(props: {
|
||||
className={[
|
||||
' ',
|
||||
!props.title && 'capitalize',
|
||||
props.url === pathname ? 'text-brand' : 'hover:text-brand text-foreground',
|
||||
props.url === pathname ? 'text-brand-link' : 'hover:text-brand-link text-foreground',
|
||||
].join(' ')}
|
||||
>
|
||||
{props.title ?? props.id}
|
||||
@@ -75,7 +75,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
'flex items-center gap-2',
|
||||
'cursor-pointer transition text-sm',
|
||||
activeItem
|
||||
? 'text-brand font-medium'
|
||||
? 'text-brand-link font-medium'
|
||||
: 'hover:text-foreground text-foreground-lighter',
|
||||
].join(' ')}
|
||||
parent={props.subItem.parent}
|
||||
@@ -104,8 +104,8 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
className={[
|
||||
'cursor-pointer transition text-sm',
|
||||
subSubItem.url === pathname
|
||||
? 'text-brand'
|
||||
: 'hover:text-brand text-foreground-lighter',
|
||||
? 'text-brand-link'
|
||||
: 'hover:text-brand-link text-foreground-lighter',
|
||||
].join(' ')}
|
||||
>
|
||||
{subSubItem.name}
|
||||
|
||||
@@ -105,7 +105,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
{group.label}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -119,7 +119,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 px-5 rounded text-sm transition',
|
||||
`${
|
||||
section.url === pathname
|
||||
? 'bg-background text-brand'
|
||||
? 'bg-background text-brand-link'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
@@ -144,7 +144,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
{section.name}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -157,7 +157,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 ml-4 px-5 rounded text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand'
|
||||
? 'bg-background text-brand-link'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
|
||||
@@ -274,7 +274,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
|
||||
const hasBranches = selectedProject?.is_branch_enabled ?? false
|
||||
const ref = hasBranches ? selectedBranch?.project_ref : selectedProject?.ref
|
||||
|
||||
const needsApiQuery = variable === 'anonKey' || variable === 'url'
|
||||
const needsApiQuery = variable === 'publishableKey' || variable === 'url'
|
||||
const needsSupavisorQuery = variable === 'sessionPooler'
|
||||
|
||||
const {
|
||||
@@ -303,7 +303,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
|
||||
switch (variable) {
|
||||
case 'url':
|
||||
return !apiData.app_config?.endpoint
|
||||
case 'anonKey':
|
||||
case 'publishableKey':
|
||||
return !apiData.service_api_keys?.some((key) => key.tags === 'anon')
|
||||
}
|
||||
}
|
||||
@@ -336,7 +336,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
|
||||
case 'url':
|
||||
variableValue = `https://${apiData?.app_config?.endpoint}`
|
||||
break
|
||||
case 'anonKey':
|
||||
case 'publishableKey':
|
||||
variableValue = apiData?.service_api_keys?.find((key) => key.tags === 'anon')?.api_key || ''
|
||||
break
|
||||
case 'sessionPooler':
|
||||
|
||||
@@ -6,7 +6,7 @@ export type Org = OrganizationsData[number]
|
||||
export type Project = ProjectsData[number]
|
||||
export type Branch = BranchesData[number]
|
||||
|
||||
export type Variable = 'url' | 'anonKey' | 'sessionPooler'
|
||||
export type Variable = 'url' | 'publishableKey' | 'sessionPooler'
|
||||
|
||||
function removeDoubleQuotes(str: string) {
|
||||
return str.replaceAll('"', '')
|
||||
@@ -30,7 +30,7 @@ function unescapeDoubleQuotes(str: string) {
|
||||
|
||||
export const prettyFormatVariable: Record<Variable, string> = {
|
||||
url: 'Project URL',
|
||||
anonKey: 'Anon key',
|
||||
publishableKey: 'Publishable key',
|
||||
sessionPooler: 'Connection string (pooler session mode)',
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
### Get API details
|
||||
|
||||
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
|
||||
|
||||
To do this, you need to get the Project URL and key. Get the URL from [the API settings section](/dashboard/project/_/settings/api) of a project and the key from the [the API Keys section of a project's Settings page](/dashboard/project/_/settings/api-keys/).
|
||||
|
||||
<Admonition type="note" title="Changes to API keys">
|
||||
|
||||
Supabase is changing the way keys work to improve project security and developer experience. You can [read the full announcement](https://github.com/orgs/supabase/discussions/29260), but in the transition period, you can use both the current `anon` and `service_role` keys and the new publishable key with the form `sb_publishable_xxx` which will replace the older keys.
|
||||
|
||||
To get the key values, open [the API Keys section of a project's Settings page](/dashboard/project/_/settings/api-keys/) and do the following:
|
||||
|
||||
- **For legacy keys**, copy the `anon` key for client-side operations and the `service_role` key for server-side operations from the **Legacy API Keys** tab.
|
||||
- **For new keys**, open the **API Keys** tab, if you don't have a publishable key already, click **Create new API Keys**, and copy the value from the **Publishable key** section.
|
||||
|
||||
</Admonition>
|
||||
@@ -0,0 +1,12 @@
|
||||
{/* TODO: How to completely consolidate partials? */}
|
||||
|
||||
<Admonition type="note" title="Changes to API keys">
|
||||
|
||||
Supabase is changing the way keys work to improve project security and developer experience. You can [read the full announcement](https://github.com/orgs/supabase/discussions/29260), but in the transition period, you can use both the current `anon` and `service_role` keys and the new publishable key with the form `sb_publishable_xxx` which will replace the older keys.
|
||||
|
||||
To get the key values, open [the API Keys section of a project's Settings page](/dashboard/project/_/settings/api-keys/) and do the following:
|
||||
|
||||
- **For legacy keys**, copy the `anon` key for client-side operations and the `service_role` key for server-side operations from the **Legacy API Keys** tab.
|
||||
- **For new keys**, open the **API Keys** tab, if you don't have a publishable key already, click **Create new API Keys**, and copy the value from the **Publishable key** section.
|
||||
|
||||
</Admonition>
|
||||
@@ -11,6 +11,6 @@ Your database will be available in less than a minute.
|
||||
|
||||
You can find your project credentials on the dashboard:
|
||||
|
||||
- [Database connection strings](https://supabase.com/dashboard/project/_/settings/api?showConnect=true): Direct and Pooler connection details including the connection string and parameters.
|
||||
- [Database password](https://supabase.com/dashboard/project/_/database/settings): Reset database password here if you do not have it.
|
||||
- [API credentials](https://supabase.com/dashboard/project/_/settings/api): your serverless API URL and `anon` / `service_role` keys.
|
||||
- [Database connection strings](/dashboard/project/_/settings/api?showConnect=true): Direct and Pooler connection details including the connection string and parameters.
|
||||
- [Database password](/dashboard/project/_/database/settings): Reset database password here if you do not have it.
|
||||
- [API credentials](/dashboard/project/_/settings/api): your serverless API URL and `anon` / `service_role` keys.
|
||||
@@ -33,13 +33,7 @@ Now we are going to set up the database schema. You can just copy/paste the SQL
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
|
||||
### Get the API keys
|
||||
|
||||
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
|
||||
We just need to get the Project URL and `anon` key from the API settings.
|
||||
|
||||
1. Go to the [API Settings](https://app.supabase.com/project/_/settings/api) page in the Dashboard.
|
||||
2. Find your Project `URL`, `anon`, and `service_role` keys on this page.
|
||||
<$Partial path="api_settings.mdx" />
|
||||
|
||||
### Set up Google authentication
|
||||
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@supabase/mcp-server-supabase@latest",
|
||||
"@supabase/mcp-server-supabase",
|
||||
"--read-only",
|
||||
"--project-ref=<project-ref>"
|
||||
],
|
||||
"env": {
|
||||
"SUPABASE_ACCESS_TOKEN": "<personal-access-token>"
|
||||
"SUPABASE_ACCESS_TOKEN": "<access-token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `<project-ref>` with your project ref, and `<personal-access-token>` with your personal access token.
|
||||
Replace `<project-ref>` with your project ref, and `<access-token>` with your personal access token.
|
||||
|
||||
</TabPanel>
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
"/c",
|
||||
"npx",
|
||||
"-y",
|
||||
"@supabase/mcp-server-supabase@latest",
|
||||
"@supabase/mcp-server-supabase",
|
||||
"--read-only",
|
||||
"--project-ref=<project-ref>"
|
||||
],
|
||||
"env": {
|
||||
"SUPABASE_ACCESS_TOKEN": "<personal-access-token>"
|
||||
"SUPABASE_ACCESS_TOKEN": "<access-token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,18 +65,18 @@ Or, if using `pnpm` instead of `npm`
|
||||
"/c",
|
||||
"pnpm",
|
||||
"dlx",
|
||||
"@supabase/mcp-server-supabase@latest",
|
||||
"@supabase/mcp-server-supabase",
|
||||
"--read-only",
|
||||
"--project-ref=<project-ref>"
|
||||
],
|
||||
"env": {
|
||||
"SUPABASE_ACCESS_TOKEN": "<personal-access-token>"
|
||||
"SUPABASE_ACCESS_TOKEN": "<access-token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Replace `<project-ref>` with your project ref, and `<personal-access-token>` with your personal access token.
|
||||
Replace `<project-ref>` with your project ref, and `<access-token>` with your personal access token.
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
@@ -110,19 +110,19 @@ Or, if using `pnpm` instead of `npm`
|
||||
"args": [
|
||||
"npx",
|
||||
"-y",
|
||||
"@supabase/mcp-server-supabase@latest",
|
||||
"@supabase/mcp-server-supabase",
|
||||
"--read-only",
|
||||
"--project-ref=<project-ref>"
|
||||
],
|
||||
"env": {
|
||||
"SUPABASE_ACCESS_TOKEN": "<personal-access-token>"
|
||||
"SUPABASE_ACCESS_TOKEN": "<access-token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `<project-ref>` with your project ref, and `<personal-access-token>` with your personal access token.
|
||||
Replace `<project-ref>` with your project ref, and `<access-token>` with your personal access token.
|
||||
|
||||
This assumes you have Windows Subsystem for Linux (WSL) enabled and `node`/`npx` are installed within the WSL environment.
|
||||
|
||||
@@ -137,19 +137,19 @@ Or, if using `pnpm` instead of `npm`
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@supabase/mcp-server-supabase@latest",
|
||||
"@supabase/mcp-server-supabase",
|
||||
"--read-only",
|
||||
"--project-ref=<project-ref>"
|
||||
],
|
||||
"env": {
|
||||
"SUPABASE_ACCESS_TOKEN": "<personal-access-token>"
|
||||
"SUPABASE_ACCESS_TOKEN": "<access-token>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `<project-ref>` with your project ref, and `<personal-access-token>` with your personal access token.
|
||||
Replace `<project-ref>` with your project ref, and `<access-token>` with your personal access token.
|
||||
|
||||
</TabPanel>
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
- If you're planning to migrate a database larger than 6 GB, we recommend [upgrading to at least a Large compute add-on](/docs/guides/platform/compute-add-ons). This will ensure you have the necessary resources to handle the migration efficiently.
|
||||
|
||||
- We strongly advise you to pre-provision the disk space you will need for your migration. On paid projects, you can do this by navigating to the [Compute and Disk Settings](https://supabase.com/dashboard/project/_/settings/compute-and-disk) page. For more information on disk scaling and disk limits, check out our [disk settings](https://supabase.com/docs/guides/platform/compute-and-disk#disk) documentation.
|
||||
- We strongly advise you to pre-provision the disk space you will need for your migration. On paid projects, you can do this by navigating to the [Compute and Disk Settings](/dashboard/project/_/settings/compute-and-disk) page. For more information on disk scaling and disk limits, check out our [disk settings](/docs/guides/platform/compute-and-disk#disk) documentation.
|
||||
|
||||
</Admonition>
|
||||
@@ -4,7 +4,7 @@ Before you start building you need to set up the Database and API. You can do th
|
||||
|
||||
### Create a project
|
||||
|
||||
1. [Create a new project](https://supabase.com/dashboard) in the Supabase Dashboard.
|
||||
1. [Create a new project](/dashboard) in the Supabase Dashboard.
|
||||
2. Enter your project details.
|
||||
3. Wait for the new database to launch.
|
||||
|
||||
@@ -21,7 +21,7 @@ Now set up the database schema. You can use the "User Management Starter" quicks
|
||||
>
|
||||
<TabPanel id="dashboard" label="Dashboard">
|
||||
|
||||
1. Go to the [SQL Editor](https://supabase.com/dashboard/project/_/sql) page in the Dashboard.
|
||||
1. Go to the [SQL Editor](/dashboard/project/_/sql) page in the Dashboard.
|
||||
2. Click **User Management Starter** under the **Community > Quickstarts** tab.
|
||||
3. Click **Run**.
|
||||
|
||||
@@ -55,11 +55,4 @@ supabase migration new user_management_starter
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
|
||||
### Get the API keys
|
||||
|
||||
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
|
||||
|
||||
To do this, you need to get the Project URL and `anon` key from the API settings.
|
||||
|
||||
1. Go to the [API Settings](https://supabase.com/dashboard/project/_/settings/api) page in the Dashboard.
|
||||
2. Find your Project `URL`, `anon`, and `service_role` keys on this page.
|
||||
<$Partial path="api_settings.mdx" />
|
||||
@@ -24,9 +24,9 @@ curl -X POST https://api.supabase.com/v1/projects \
|
||||
}'
|
||||
```
|
||||
|
||||
When your project is up and running, go to the [Table Editor](https://supabase.com/dashboard/project/_/editor), create a new table and insert some data.
|
||||
When your project is up and running, go to the [Table Editor](/dashboard/project/_/editor), create a new table and insert some data.
|
||||
|
||||
Alternatively, you can run the following snippet in your project's [SQL Editor](https://supabase.com/dashboard/project/_/sql/new). This will create a `instruments` table with some sample data.
|
||||
Alternatively, you can run the following snippet in your project's [SQL Editor](/dashboard/project/_/sql/new). This will create a `instruments` table with some sample data.
|
||||
|
||||
</StepHikeCompact.Details>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- Go to your [Supabase Project Dashboard](https://supabase.com/dashboard)
|
||||
- Go to your [Supabase Project Dashboard](/dashboard)
|
||||
- In the left sidebar, click the `Authentication` icon (near the top)
|
||||
- Click on [`Providers`](https://supabase.com/dashboard/project/_/auth/providers) under the Configuration section
|
||||
- Click on [`Providers`](/dashboard/project/_/auth/providers) under the Configuration section
|
||||
- Click on **{{ .provider }}** from the accordion list to expand and turn **{{ .provider }} Enabled** to ON
|
||||
- Enter your **{{ .provider }} Client ID** and **{{ .provider }} Client Secret** saved in the previous step
|
||||
- Click `Save`
|
||||
@@ -1,8 +1,8 @@
|
||||
The next step requires a callback URL, which looks like this: `https://<project-ref>.supabase.co/auth/v1/callback`
|
||||
|
||||
- Go to your [Supabase Project Dashboard](https://supabase.com/dashboard)
|
||||
- Go to your [Supabase Project Dashboard](/dashboard)
|
||||
- Click on the `Authentication` icon in the left sidebar
|
||||
- Click on [`Providers`](https://supabase.com/dashboard/project/_/auth/providers) under the Configuration section
|
||||
- Click on [`Providers`](/dashboard/project/_/auth/providers) under the Configuration section
|
||||
- Click on **{{ .provider }}** from the accordion list to expand and you'll find your **Callback URL**, you can click `Copy` to copy it to the clipboard
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
@@ -139,10 +139,10 @@ export const integrations = [
|
||||
href: 'https://supabase.com/customers/berriai',
|
||||
},
|
||||
{
|
||||
name: 'Mendable switches from Pinecone to Supabase for PostgreSQL vector embeddings',
|
||||
name: 'Firecrawl switches from Pinecone to Supabase for PostgreSQL vector embeddings',
|
||||
description:
|
||||
'How Mendable boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector',
|
||||
href: 'https://supabase.com/customers/mendableai',
|
||||
'How Firecrawl boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector',
|
||||
href: 'https://supabase.com/customers/firecrawl',
|
||||
},
|
||||
{
|
||||
name: 'Markprompt: GDPR-Compliant AI Chatbots for Docs and Websites',
|
||||
|
||||
@@ -54,7 +54,7 @@ poetry install
|
||||
|
||||
### Step 3: Create a Supabase project
|
||||
|
||||
Create a [Supabase project](https://supabase.com/dashboard) and database by following the instructions [here](https://supabase.com/docs/guides/platform). Export the environment variables required for the retrieval plugin to work:
|
||||
Create a [Supabase project](/dashboard) and database by following the instructions [here](/docs/guides/platform). Export the environment variables required for the retrieval plugin to work:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=<open_ai_api_key>
|
||||
|
||||
@@ -33,7 +33,7 @@ There are 3 steps to build similarity search inside your documentation:
|
||||
|
||||
### Prepare your database
|
||||
|
||||
To prepare, create a [new Supabase project](https://database.new) and store the database and API credentials, which you can find in the project [settings](https://supabase.com/dashboard/project/_/settings).
|
||||
To prepare, create a [new Supabase project](https://database.new) and store the database and API credentials, which you can find in the project [settings](/dashboard/project/_/settings).
|
||||
|
||||
Now we can use the [Headless Vector Search](https://github.com/supabase/headless-vector-search#set-up) instructions to set up the database:
|
||||
|
||||
@@ -42,7 +42,7 @@ Now we can use the [Headless Vector Search](https://github.com/supabase/headless
|
||||
3. Apply the database migrations: `supabase db push`
|
||||
4. Set your OpenAI key as a secret: `supabase secrets set OPENAI_API_KEY=sk-xxx`
|
||||
5. Deploy the Edge Functions: `supabase functions deploy --no-verify-jwt`
|
||||
6. Expose `docs` schema via API in Supabase Dashboard [settings](https://supabase.com/dashboard/project/_/settings/api) > `API Settings` > `Exposed schemas`
|
||||
6. Expose `docs` schema via API in Supabase Dashboard [settings](/dashboard/project/_/settings/api) > `API Settings` > `Exposed schemas`
|
||||
|
||||
### Ingest your documentation
|
||||
|
||||
@@ -112,6 +112,6 @@ const onSubmit = (e: Event) => {
|
||||
|
||||
## Resources
|
||||
|
||||
- Read about how we built [ChatGPT for the Supabase Docs](https://supabase.com/blog/chatgpt-supabase-docs).
|
||||
- Read about how we built [ChatGPT for the Supabase Docs](/blog/chatgpt-supabase-docs).
|
||||
- Read the pgvector Docs for [Embeddings and vector similarity](/docs/guides/database/extensions/pgvector)
|
||||
- See how to build something like this from scratch [using Next.js](/docs/guides/ai/examples/nextjs-vector-search).
|
||||
@@ -6,25 +6,25 @@ video: 'https://www.youtube.com/v/OgnYxRkxEUw'
|
||||
tocVideo: 'OgnYxRkxEUw'
|
||||
---
|
||||
|
||||
We can combine Hugging Face with [Supabase Storage](https://supabase.com/storage) and [Database Webhooks](https://supabase.com/docs/guides/database/webhooks) to automatically caption for any image we upload to a storage bucket.
|
||||
We can combine Hugging Face with [Supabase Storage](/storage) and [Database Webhooks](/docs/guides/database/webhooks) to automatically caption for any image we upload to a storage bucket.
|
||||
|
||||
## About Hugging Face
|
||||
|
||||
[Hugging Face](https://huggingface.co/) is the collaboration platform for the machine learning community.
|
||||
|
||||
[Huggingface.js](https://huggingface.co/docs/huggingface.js/index) provides a convenient way to make calls to 100,000+ Machine Learning models, making it easy to incorporate AI functionality into your [Supabase Edge Functions](https://supabase.com/edge-functions).
|
||||
[Huggingface.js](https://huggingface.co/docs/huggingface.js/index) provides a convenient way to make calls to 100,000+ Machine Learning models, making it easy to incorporate AI functionality into your [Supabase Edge Functions](/edge-functions).
|
||||
|
||||
## Setup
|
||||
|
||||
- Open your Supabase project dashboard or [create a new project](https://supabase.com/dashboard/projects).
|
||||
- [Create a new bucket](https://supabase.com/dashboard/project/_/storage/buckets) called `images`.
|
||||
- Open your Supabase project dashboard or [create a new project](/dashboard/projects).
|
||||
- [Create a new bucket](/dashboard/project/_/storage/buckets) called `images`.
|
||||
- Generate TypeScript types from remote Database.
|
||||
- Create a new Database table called `image_caption`.
|
||||
- Create `id` column of type `uuid` which references `storage.objects.id`.
|
||||
- Create a `caption` column of type `text`.
|
||||
- Regenerate TypeScript types to include new `image_caption` table.
|
||||
- Deploy the function to Supabase: `supabase functions deploy huggingface-image-captioning`.
|
||||
- Create the Database Webhook in the [Supabase Dashboard](https://supabase.com/dashboard/project/_/database/hooks) to trigger the `huggingface-image-captioning` function anytime a record is added to the `storage.objects` table.
|
||||
- Create the Database Webhook in the [Supabase Dashboard](/dashboard/project/_/database/hooks) to trigger the `huggingface-image-captioning` function anytime a record is added to the `storage.objects` table.
|
||||
|
||||
## Generate TypeScript types
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ poetry new video-search
|
||||
|
||||
## Setup Supabase project
|
||||
|
||||
If you haven't already, [install the Supabase CLI](https://supabase.com/docs/guides/cli), then initialize Supabase in the root of your newly created poetry project:
|
||||
If you haven't already, [install the Supabase CLI](/docs/guides/cli), then initialize Supabase in the root of your newly created poetry project:
|
||||
|
||||
```shell
|
||||
supabase init
|
||||
|
||||
@@ -12,19 +12,19 @@ While our [Headless Vector search](/docs/guides/ai/examples/headless-vector-sear
|
||||
2. Store you embeddings in Postgres using pgvector.
|
||||
3. Deploy a function for answering your users' questions.
|
||||
|
||||
You can read our [Supabase Clippy](https://supabase.com/blog/chatgpt-supabase-docs) blog post for a full example.
|
||||
You can read our [Supabase Clippy](/blog/chatgpt-supabase-docs) blog post for a full example.
|
||||
|
||||
We assume that you have a Next.js project with a collection of `.mdx` files nested inside your `pages` directory. We will start developing locally with the Supabase CLI and then push our local database changes to our hosted Supabase project. You can find the [full Next.js example on GitHub](https://github.com/supabase-community/nextjs-openai-doc-search).
|
||||
|
||||
## Create a project
|
||||
|
||||
1. [Create a new project](https://supabase.com/dashboard) in the Supabase Dashboard.
|
||||
1. [Create a new project](/dashboard) in the Supabase Dashboard.
|
||||
1. Enter your project details.
|
||||
1. Wait for the new database to launch.
|
||||
|
||||
## Prepare the database
|
||||
|
||||
Let's prepare the database schema. We can use the "OpenAI Vector Search" quickstart in the [SQL Editor](https://supabase.com/dashboard/project/_/sql), or you can copy/paste the SQL below and run it yourself.
|
||||
Let's prepare the database schema. We can use the "OpenAI Vector Search" quickstart in the [SQL Editor](/dashboard/project/_/sql), or you can copy/paste the SQL below and run it yourself.
|
||||
|
||||
<Tabs
|
||||
scrollable
|
||||
@@ -35,7 +35,7 @@ Let's prepare the database schema. We can use the "OpenAI Vector Search" quickst
|
||||
>
|
||||
<TabPanel id="dashboard" label="Dashboard">
|
||||
|
||||
1. Go to the [SQL Editor](https://supabase.com/dashboard/project/_/sql) page in the Dashboard.
|
||||
1. Go to the [SQL Editor](/dashboard/project/_/sql) page in the Dashboard.
|
||||
2. Click **OpenAI Vector Search**.
|
||||
3. Click **Run**.
|
||||
|
||||
@@ -147,7 +147,7 @@ Let's prepare the database schema. We can use the "OpenAI Vector Search" quickst
|
||||
|
||||
Anytime the user sends a query, we want to find the content that's relevant to their questions. We can do this using pgvector's similarity search.
|
||||
|
||||
These are quite complex SQL operations, so let's wrap them in database functions that we can call from our frontend using [RPC](https://supabase.com/docs/reference/javascript/rpc).
|
||||
These are quite complex SQL operations, so let's wrap them in database functions that we can call from our frontend using [RPC](/docs/reference/javascript/rpc).
|
||||
|
||||
</StepHikeCompact.Details>
|
||||
|
||||
@@ -527,8 +527,8 @@ const handleConfirm = React.useCallback(
|
||||
|
||||
Want to learn more about the awesome tech that is powering this?
|
||||
|
||||
- Read about how we built [ChatGPT for the Supabase Docs](https://supabase.com/blog/chatgpt-supabase-docs).
|
||||
- Read the pgvector Docs for [Embeddings and vector similarity](https://supabase.com/docs/guides/database/extensions/pgvector)
|
||||
- Read about how we built [ChatGPT for the Supabase Docs](/blog/chatgpt-supabase-docs).
|
||||
- Read the pgvector Docs for [Embeddings and vector similarity](/docs/guides/database/extensions/pgvector)
|
||||
- Watch Greg's video for a full breakdown:
|
||||
|
||||
<div class="video-container">
|
||||
|
||||
@@ -34,7 +34,7 @@ If you haven't already, head over to [database.new](https://database.new) and cr
|
||||
|
||||
When creating your project, make sure to note down your database password as you will need it to construct the `DB_URL` in the next step.
|
||||
|
||||
You can find your database connection string on your project dashboard, click [Connect](https://supabase.com/dashboard/project/_?showConnect=true). Use the Session pooler connection string which looks like this:
|
||||
You can find your database connection string on your project dashboard, click [Connect](/dashboard/project/_?showConnect=true). Use the Session pooler connection string which looks like this:
|
||||
|
||||
```txt
|
||||
postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres
|
||||
@@ -188,7 +188,7 @@ seed = "image_search.main:seed"
|
||||
search = "image_search.main:search"
|
||||
```
|
||||
|
||||
After activating the virtual environment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](https://supabase.com/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table.
|
||||
After activating the virtual environment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table.
|
||||
|
||||
## Perform an image search from a text query
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ On the other hand, if you need to scale your application, you will need to [crea
|
||||
|
||||
## HNSW vs IVFFlat indexes
|
||||
|
||||
`pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
|
||||
`pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
|
||||
|
||||
<Image
|
||||
alt="dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute add-on"
|
||||
@@ -68,7 +68,7 @@ The values of lists and probes directly affect accuracy and queries per second (
|
||||
- Higher `probes` means that select queries will be slower, but you can achieve better accuracy.
|
||||
- `lists` and `probes` are not independent. Higher `lists` means that you will have to use higher `probes` to achieve the same accuracy.
|
||||
|
||||
You can find more examples of how `lists` and `probes` constants affect accuracy and QPS in [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blogpost.
|
||||
You can find more examples of how `lists` and `probes` constants affect accuracy and QPS in [pgvector 0.4.0 performance](/blog/pgvector-performance) blogpost.
|
||||
|
||||
<Image
|
||||
alt="multi database"
|
||||
@@ -109,7 +109,7 @@ Don't forget to check out the general [Production Checklist](/docs/guides/platfo
|
||||
|
||||
You can look at our [Choosing Compute Add-on](/docs/guides/ai/choosing-compute-addon) guide to get a basic understanding of how much compute you might need for your workload.
|
||||
|
||||
Or take a look at our [pgvector 0.5.0 performance](https://supabase.com/blog/increase-performance-pgvector-hnsw) and [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blog posts to see what pgvector is capable of and how the above technique can be used to achieve the best results.
|
||||
Or take a look at our [pgvector 0.5.0 performance](/blog/increase-performance-pgvector-hnsw) and [pgvector 0.4.0 performance](/blog/pgvector-performance) blog posts to see what pgvector is capable of and how the above technique can be used to achieve the best results.
|
||||
|
||||
<Image
|
||||
alt="multi database"
|
||||
|
||||
@@ -15,7 +15,7 @@ sidebar_label: 'Google Colab'
|
||||
|
||||
Google Colab is a hosted Jupyter Notebook service. It provides free access to computing resources, including GPUs and TPUs, and is well-suited to machine learning, data science, and education. We can use Colab to manage collections using [Supabase Vecs](/docs/guides/ai/vecs-python-client).
|
||||
|
||||
In this tutorial we'll connect to a database running on the Supabase [platform](https://supabase.com/dashboard/). If you don't already have a database, you can create one here: [database.new](https://database.new).
|
||||
In this tutorial we'll connect to a database running on the Supabase [platform](/dashboard/). If you don't already have a database, you can create one here: [database.new](https://database.new).
|
||||
|
||||
## Create a new notebook
|
||||
|
||||
@@ -37,7 +37,7 @@ pip install vecs
|
||||
|
||||
## Connect to your database
|
||||
|
||||
On your project dashboard, click [Connect](https://supabase.com/dashboard/project/_?showConnect=true). The connection string should look like `postgres://postgres.xxxx:password@xxxx.pooler.supabase.com:6543/postgres`
|
||||
On your project dashboard, click [Connect](/dashboard/project/_?showConnect=true). The connection string should look like `postgres://postgres.xxxx:password@xxxx.pooler.supabase.com:6543/postgres`
|
||||
|
||||
Create a new code block below the install block (`ctrl+m b`) and add the following code using the Postgres URI you copied above:
|
||||
|
||||
@@ -77,7 +77,7 @@ collection.upsert(
|
||||
)
|
||||
```
|
||||
|
||||
This will create a table inside your database within the `vecs` schema, called `colab_collection`. You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
This will create a table inside your database within the `vecs` schema, called `colab_collection`. You can view the inserted items in the [Table Editor](/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"
|
||||
vx = vecs.create_client(DB_CONNECTION)
|
||||
```
|
||||
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](https://supabase.com/dashboard/project/_?showConnect=true).
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](/dashboard/project/_?showConnect=true).
|
||||
|
||||
<Admonition type='note'>
|
||||
|
||||
@@ -60,7 +60,7 @@ You must use the "connection pooling" string (domain ending in `*.pooler.supabas
|
||||
|
||||
Now all that's left is to step through the notebook. You can do this by clicking the "execute" button (`ctrl+enter`) at the top left of each code cell. The notebook guides you through the process of creating a collection, adding data to it, and querying it.
|
||||
|
||||
You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
You can view the inserted items in the [Table Editor](/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Prepare you database with the relevant tables:
|
||||
>
|
||||
<TabPanel id="dashboard" label="Dashboard">
|
||||
|
||||
1. Go to the [SQL Editor](https://supabase.com/dashboard/project/_/sql) page in the Dashboard.
|
||||
1. Go to the [SQL Editor](/dashboard/project/_/sql) page in the Dashboard.
|
||||
2. Click **LangChain** in the Quick start section.
|
||||
3. Click **Run**.
|
||||
|
||||
@@ -76,8 +76,8 @@ $$;
|
||||
You can now search your documents using any Node.js application. This is intended to be run on a secure server route.
|
||||
|
||||
```js
|
||||
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from 'langchain/embeddings/openai'
|
||||
import { SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from '@langchain/openai'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY
|
||||
@@ -111,8 +111,8 @@ export const run = async () => {
|
||||
Given the above `match_documents` Postgres function, you can also pass a filter parameter to only return documents with a specific metadata field value. This filter parameter is a JSON object, and the `match_documents` function will use the Postgres JSONB Containment operator `@>` to filter documents by the metadata field values you specify. See details on the [Postgres JSONB Containment operator](https://www.postgresql.org/docs/current/datatype-json.html#JSON-CONTAINMENT) for more information.
|
||||
|
||||
```js
|
||||
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from 'langchain/embeddings/openai'
|
||||
import { SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from '@langchain/openai'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
// First, follow set-up instructions above
|
||||
@@ -147,11 +147,11 @@ export const run = async () => {
|
||||
|
||||
### Advanced metadata filtering
|
||||
|
||||
You can also use query builder-style filtering ([similar to how the Supabase JavaScript library works](https://supabase.com/docs/reference/javascript/using-filters)) instead of passing an object. Note that since the filter properties will be in the metadata column, you need to use arrow operators (`->` for integer or `->>` for text) as defined in [PostgREST API documentation](https://postgrest.org/en/stable/references/api/tables_views.html?highlight=operators#json-columns) and specify the data type of the property (e.g. the column should look something like `metadata->some_int_value::int`).
|
||||
You can also use query builder-style filtering ([similar to how the Supabase JavaScript library works](/docs/reference/javascript/using-filters)) instead of passing an object. Note that since the filter properties will be in the metadata column, you need to use arrow operators (`->` for integer or `->>` for text) as defined in [PostgREST API documentation](https://postgrest.org/en/stable/references/api/tables_views.html?highlight=operators#json-columns) and specify the data type of the property (e.g. the column should look something like `metadata->some_int_value::int`).
|
||||
|
||||
```js
|
||||
import { SupabaseFilterRPCCall, SupabaseVectorStore } from 'langchain/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from 'langchain/embeddings/openai'
|
||||
import { SupabaseFilterRPCCall, SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'
|
||||
import { OpenAIEmbeddings } from '@langchain/openai'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
// First, follow set-up instructions above
|
||||
|
||||
@@ -11,7 +11,9 @@ For data science or ephemeral workloads, the [Supabase Vecs](https://supabase.gi
|
||||
|
||||
<Admonition type="tip">
|
||||
|
||||
You can get your connection string from the [**Database Settings**](https://supabase.com/dashboard/project/_/database/settings) page in your dashboard. Make sure to check **Use connection pooling**, then copy the URI. Also, change the URI scheme from `postgres` to `postgresql`. `vecs` uses SQLAlchemy under the hood, which only supports `postgresql` as a dialect.
|
||||
Click [**Connect**](/dashboard/project/_/?showConnect=true) at the top of any project page to get your connection string.
|
||||
|
||||
Copy the URI from the **Shared pooler** option.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"
|
||||
vx = vecs.create_client(DB_CONNECTION)
|
||||
```
|
||||
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](https://supabase.com/dashboard/project/_?showConnect=true).
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](/dashboard/project/_?showConnect=true).
|
||||
|
||||
<Admonition type='note'>
|
||||
|
||||
@@ -58,7 +58,7 @@ You must use the "connection pooling" string (domain ending in `*.pooler.supabas
|
||||
|
||||
Now all that's left is to step through the notebook. You can do this by clicking the "execute" button (`ctrl+enter`) at the top left of each code cell. The notebook guides you through the process of creating a collection, adding data to it, and querying it.
|
||||
|
||||
You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
You can view the inserted items in the [Table Editor](/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"
|
||||
vx = vecs.create_client(DB_CONNECTION)
|
||||
```
|
||||
|
||||
Replace the `DB_CONNECTION` with your Session pooler connection string. You can find the connection string on your project dashboard by clicking [Connect](https://supabase.com/dashboard/project/_?showConnect=true).
|
||||
Replace the `DB_CONNECTION` with your Session pooler connection string. You can find the connection string on your project dashboard by clicking [Connect](/dashboard/project/_?showConnect=true).
|
||||
|
||||
<Admonition type='note'>
|
||||
|
||||
@@ -59,7 +59,7 @@ You must use the Session pooler connection string with Google Colab since Colab
|
||||
|
||||
Now all that's left is to step through the notebook. You can do this by clicking the "execute" button (`ctrl+enter`) at the top left of each code cell. The notebook guides you through the process of creating a collection, adding data to it, and querying it.
|
||||
|
||||
You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
You can view the inserted items in the [Table Editor](/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"
|
||||
vx = vecs.create_client(DB_CONNECTION)
|
||||
```
|
||||
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](https://supabase.com/dashboard/project/_?showConnect=true).
|
||||
Replace the `DB_CONNECTION` with your own connection string. You can find the connection string on your project dashboard by clicking [Connect](/dashboard/project/_?showConnect=true).
|
||||
|
||||
<Admonition type='note'>
|
||||
|
||||
@@ -59,7 +59,7 @@ You must use the "connection pooling" string (domain ending in `*.pooler.supabas
|
||||
|
||||
Now all that's left is to step through the notebook. You can do this by clicking the "execute" button (`ctrl+enter`) at the top left of each code cell. The notebook guides you through the process of creating a collection, adding data to it, and querying it.
|
||||
|
||||
You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
You can view the inserted items in the [Table Editor](/dashboard/project/_/editor/), by selecting the `vecs` schema from the schema dropdown.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -113,13 +113,13 @@ You may have an existing system that stores users, documents, and their permissi
|
||||
|
||||
<Admonition type="caution">
|
||||
|
||||
RLS is latency-sensitive, so extra caution should be taken before implementing this method. Use the [query plan analyzer](https://supabase.com/docs/guides/platform/performance#optimizing-poor-performing-queries) to measure execution times for your queries to ensure they are within expected ranges. For enterprise applications, contact enterprise@supabase.io.
|
||||
RLS is latency-sensitive, so extra caution should be taken before implementing this method. Use the [query plan analyzer](/docs/guides/platform/performance#optimizing-poor-performing-queries) to measure execution times for your queries to ensure they are within expected ranges. For enterprise applications, contact enterprise@supabase.io.
|
||||
|
||||
</Admonition>
|
||||
|
||||
<Admonition type="tip">
|
||||
|
||||
For data sources other than Postgres, see [Foreign Data Wrappers](/docs/guides/database/extensions/wrappers/overview) for a list of external sources supported today. If your data lives in a source not provided in the list, contact [support](https://supabase.com/dashboard/support/new) and we'll be happy to discuss your use case.
|
||||
For data sources other than Postgres, see [Foreign Data Wrappers](/docs/guides/database/extensions/wrappers/overview) for a list of external sources supported today. If your data lives in a source not provided in the list, contact [support](/dashboard/support/new) and we'll be happy to discuss your use case.
|
||||
|
||||
</Admonition>
|
||||
|
||||
@@ -189,7 +189,7 @@ Since we're managing users and authentication outside of Supabase, we have two o
|
||||
|
||||
#### Direct Postgres connection
|
||||
|
||||
You can directly connect to your Supabase Postgres DB using the [connection info](/dashboard/project/_/database/settings) on your project's Database Settings page. To use RLS with this method, we use a custom session variable that contains the current user's ID:
|
||||
You can directly connect to your Supabase Postgres DB using the [connection info](/dashboard/project/_/?showConnect=true) on a project page. To use RLS with this method, we use a custom session variable that contains the current user's ID:
|
||||
|
||||
```sql
|
||||
-- enable row level security
|
||||
@@ -271,4 +271,4 @@ order by document_sections.embedding <#> embedding;
|
||||
|
||||
There are endless approaches to this problem based on the complexities of each system. Luckily Postgres comes with all the primitives needed to provide access control in the way that works best for your project.
|
||||
|
||||
If the examples above didn't fit your use case or you need to adjust them slightly to better fit your existing system, feel free to reach out to [support](https://supabase.com/dashboard/support/new) and we'll be happy to assist you.
|
||||
If the examples above didn't fit your use case or you need to adjust them slightly to better fit your existing system, feel free to reach out to [support](/dashboard/support/new) and we'll be happy to assist you.
|
||||
@@ -22,7 +22,7 @@ Vectors in Supabase are enabled via [pgvector](https://github.com/pgvector/pgvec
|
||||
>
|
||||
<TabPanel id="dashboard" label="Dashboard">
|
||||
|
||||
1. Go to the [Database](https://supabase.com/dashboard/project/_/database/tables) page in the Dashboard.
|
||||
1. Go to the [Database](/dashboard/project/_/database/tables) page in the Dashboard.
|
||||
2. Click on **Extensions** in the sidebar.
|
||||
3. Search for "vector" and enable the extension.
|
||||
|
||||
@@ -63,7 +63,7 @@ In the above SQL snippet, we create a `documents` table with a column called `em
|
||||
|
||||
<Admonition type="tip">
|
||||
|
||||
In general, embeddings with fewer dimensions perform best. See our [analysis on fewer dimensions in pgvector](https://supabase.com/blog/fewer-dimensions-are-better-pgvector).
|
||||
In general, embeddings with fewer dimensions perform best. See our [analysis on fewer dimensions in pgvector](/blog/fewer-dimensions-are-better-pgvector).
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Today `pgvector` supports two types of indexes:
|
||||
- [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes)
|
||||
- [IVFFlat](/docs/guides/ai/vector-indexes/ivf-indexes)
|
||||
|
||||
In general we recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
|
||||
In general we recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
|
||||
|
||||
## Distance operators
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Today `pgvector` supports two types of indexes:
|
||||
- [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes)
|
||||
- [IVFFlat](/docs/guides/ai/vector-indexes/ivf-indexes)
|
||||
|
||||
In general we recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes). If you have a special use case that requires IVFFlat instead, keep reading.
|
||||
In general we recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes). If you have a special use case that requires IVFFlat instead, keep reading.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -43,4 +43,4 @@ Reference:
|
||||
|
||||
## API URL and keys
|
||||
|
||||
You can find the API URL and Keys in the [Dashboard](https://supabase.com/dashboard/project/_/settings/api-keys).
|
||||
You can find the API URL and Keys in the [Dashboard](/dashboard/project/_/settings/api-keys).
|
||||
@@ -20,7 +20,7 @@ This creates a corresponding route `todos` which can accept `GET`, `POST`, `PATC
|
||||
>
|
||||
<TabPanel id="dashboard" label="Dashboard">
|
||||
|
||||
1. Go to the [Table editor](https://supabase.com/dashboard/project/_/editor) page in the Dashboard.
|
||||
1. Go to the [Table editor](/dashboard/project/_/editor) page in the Dashboard.
|
||||
1. Click **New Table** and create a table with the name `todos`.
|
||||
1. Click **Save**.
|
||||
1. Click **New Column** and create a column with the name `task` and type `text`.
|
||||
@@ -52,7 +52,7 @@ create table
|
||||
|
||||
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
|
||||
|
||||
1. Go to the [Settings](https://supabase.com/dashboard/project/_/settings/general) page in the Dashboard.
|
||||
1. Go to the [Settings](/dashboard/project/_/settings/general) page in the Dashboard.
|
||||
2. Click **API** in the sidebar.
|
||||
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ We'll create a database table called `todos` for storing tasks. This creates a c
|
||||
<StepHikeCompact.Step step={1}>
|
||||
<StepHikeCompact.Details title="Set up a Supabase project with a 'todos' table">
|
||||
|
||||
[Create a new project](https://supabase.com/dashboard) in the Supabase Dashboard.
|
||||
[Create a new project](/dashboard) in the Supabase Dashboard.
|
||||
|
||||
After your project is ready, create a table in your Supabase database. You can do this with either the Table interface or the [SQL Editor](https://supabase.com/dashboard/project/_/sql).
|
||||
After your project is ready, create a table in your Supabase database. You can do this with either the Table interface or the [SQL Editor](/dashboard/project/_/sql).
|
||||
|
||||
</StepHikeCompact.Details>
|
||||
|
||||
@@ -109,7 +109,7 @@ We'll create a database table called `todos` for storing tasks. This creates a c
|
||||
<StepHikeCompact.Step step={4}>
|
||||
<StepHikeCompact.Details title="Fetch the data">
|
||||
|
||||
Find your API URL and Keys in your Dashboard [API Settings](https://supabase.com/dashboard/project/_/settings/api). You can now query your "todos" table by appending `/rest/v1/todos` to the API URL.
|
||||
Find your API URL and Keys in your Dashboard [API Settings](/dashboard/project/_/settings/api). You can now query your "todos" table by appending `/rest/v1/todos` to the API URL.
|
||||
|
||||
Copy this block of code, substitute `<PROJECT_REF>` and `<ANON_KEY>`, then run it from a terminal.
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ title: 'Auto-generated documentation'
|
||||
description: 'Supabase provides documentation that updates automatically.'
|
||||
---
|
||||
|
||||
Supabase generates documentation in the [Dashboard](https://supabase.com/dashboard) which updates as you make database changes.
|
||||
Supabase generates documentation in the [Dashboard](/dashboard) which updates as you make database changes.
|
||||
|
||||
1. Go to the [API](https://supabase.com/dashboard/project/_/api) page in the Dashboard.
|
||||
1. Go to the [API](/dashboard/project/_/api) page in the Dashboard.
|
||||
2. Select any table under **Tables and Views** in the sidebar.
|
||||
3. Switch between the JavaScript and the cURL docs using the tabs.
|
||||
|
||||
|
||||
@@ -9,19 +9,19 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
|
||||
|
||||
## Official libraries
|
||||
|
||||
| `Language` | `Source Code` | `Documentation` |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Javascript/Typescript | [supabase-js](https://github.com/supabase/supabase-js) | [Docs](https://supabase.com/docs/reference/javascript/introduction) |
|
||||
| Dart/Flutter | [supabase-flutter](https://github.com/supabase/supabase-flutter/tree/main/packages/supabase_flutter) | [Docs](https://supabase.com/docs/reference/dart/introduction) |
|
||||
| Swift | [supabase-swift](https://github.com/supabase/supabase-swift) | [Docs](https://supabase.com/docs/reference/swift/introduction) |
|
||||
| Python | [supabase-py](https://github.com/supabase/supabase-py) | [Docs](https://supabase.com/docs/reference/python/initializing) |
|
||||
| `Language` | `Source Code` | `Documentation` |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
||||
| Javascript/Typescript | [supabase-js](https://github.com/supabase/supabase-js) | [Docs](/docs/reference/javascript/introduction) |
|
||||
| Dart/Flutter | [supabase-flutter](https://github.com/supabase/supabase-flutter/tree/main/packages/supabase_flutter) | [Docs](/docs/reference/dart/introduction) |
|
||||
| Swift | [supabase-swift](https://github.com/supabase/supabase-swift) | [Docs](/docs/reference/swift/introduction) |
|
||||
| Python | [supabase-py](https://github.com/supabase/supabase-py) | [Docs](/docs/reference/python/initializing) |
|
||||
|
||||
## Community libraries
|
||||
|
||||
| `Language` | `Source Code` | `Documentation` |
|
||||
| ----------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| C# | [supabase-csharp](https://github.com/supabase-community/supabase-csharp) | [Docs](https://supabase.com/docs/reference/csharp/introduction) |
|
||||
| Go | [supabase-go](https://github.com/supabase-community/supabase-go) | |
|
||||
| Kotlin | [supabase-kt](https://github.com/supabase-community/supabase-kt) | [Docs](https://supabase.com/docs/reference/kotlin/introduction) |
|
||||
| Ruby | [supabase-rb](https://github.com/supabase-community/supabase-rb) | |
|
||||
| Godot Engine (GDScript) | [supabase-gdscript](https://github.com/supabase-community/godot-engine.supabase) | |
|
||||
| `Language` | `Source Code` | `Documentation` |
|
||||
| ----------------------- | -------------------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| C# | [supabase-csharp](https://github.com/supabase-community/supabase-csharp) | [Docs](/docs/reference/csharp/introduction) |
|
||||
| Go | [supabase-go](https://github.com/supabase-community/supabase-go) | |
|
||||
| Kotlin | [supabase-kt](https://github.com/supabase-community/supabase-kt) | [Docs](/docs/reference/kotlin/introduction) |
|
||||
| Ruby | [supabase-rb](https://github.com/supabase-community/supabase-rb) | |
|
||||
| Godot Engine (GDScript) | [supabase-gdscript](https://github.com/supabase-community/godot-engine.supabase) | |
|
||||
@@ -10,7 +10,7 @@ Supabase APIs are generated from your database, which means that we can use data
|
||||
|
||||
## Generating types from project dashboard
|
||||
|
||||
Supabase allows you to generate and download TypeScript types directly from the [project dashboard](https://supabase.com/dashboard/project/_/api?page=tables-intro).
|
||||
Supabase allows you to generate and download TypeScript types directly from the [project dashboard](/dashboard/project/_/api?page=tables-intro).
|
||||
|
||||
## Generating types using Supabase CLI
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ CREATE SCHEMA myschema;
|
||||
|
||||
You can expose custom database schemas - to do so you need to follow these steps:
|
||||
|
||||
1. Go to [API settings](https://supabase.com/dashboard/project/_/settings/api) and add your custom schema to "Exposed schemas".
|
||||
1. Go to [API settings](/dashboard/project/_/settings/api) and add your custom schema to "Exposed schemas".
|
||||
2. Run the following SQL, substituting `myschema` with your schema name:
|
||||
|
||||
```sql
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
id: 'auth-audit-logs'
|
||||
title: 'Auth Audit Logs'
|
||||
description: 'Monitor and track authentication events with audit logging.'
|
||||
subtitle: 'Monitor and track authentication events with audit logging.'
|
||||
---
|
||||
|
||||
Auth audit logs provide comprehensive tracking of authentication events in your Supabase project. Audit logs are automatically captured for all authentication events and help you monitor user authentication activities, detect suspicious behavior, and maintain compliance with security requirements.
|
||||
|
||||
## What gets logged
|
||||
|
||||
Supabase auth audit logs automatically capture all authentication events including:
|
||||
|
||||
- User signups and logins
|
||||
- Password changes and resets
|
||||
- Email verification events
|
||||
- Token refresh and logout events
|
||||
|
||||
## Storage options
|
||||
|
||||
By default, audit logs are stored in two places:
|
||||
|
||||
1. **Your project's Postgres database** - Stored in the `auth.audit_log_entries` table, searchable via SQL but uses database storage
|
||||
2. **External log storage** - Cost-efficient storage accessible through the dashboard
|
||||
|
||||
You can disable Postgres storage to reduce database storage costs while keeping the external log storage.
|
||||
|
||||
### Configuring audit log storage
|
||||
|
||||
1. Navigate to your project dashboard
|
||||
2. Go to **Authentication**
|
||||
3. Find the **Audit Logs** under **Configuration** section
|
||||
4. Toggle on "Disable writing auth audit logs to project database" to disable database storage
|
||||
|
||||
<Admonition type="tip">
|
||||
|
||||
Disabling Postgres storage reduces your database storage costs. Audit logs will still be available through the dashboard.
|
||||
|
||||
</Admonition>
|
||||
|
||||
## Log format
|
||||
|
||||
Audit logs contain detailed information about each authentication event:
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": "2025-08-01T10:30:00Z",
|
||||
"user_id": "uuid",
|
||||
"action": "user_signedup",
|
||||
"ip_address": "192.168.1.1",
|
||||
"user_agent": "Mozilla/5.0...",
|
||||
"metadata": {
|
||||
"provider": "email"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Log actions reference
|
||||
|
||||
| Action | Description |
|
||||
| ------------------------------- | --------------------------------------- |
|
||||
| `login` | User login attempt |
|
||||
| `logout` | User logout |
|
||||
| `invite_accepted` | Team invitation accepted |
|
||||
| `user_signedup` | New user registration |
|
||||
| `user_invited` | User invitation sent |
|
||||
| `user_deleted` | User account deleted |
|
||||
| `user_modified` | User profile updated |
|
||||
| `user_recovery_requested` | Password reset request |
|
||||
| `user_reauthenticate_requested` | User reauthentication required |
|
||||
| `user_confirmation_requested` | Email/phone confirmation requested |
|
||||
| `user_repeated_signup` | Duplicate signup attempt |
|
||||
| `user_updated_password` | Password change completed |
|
||||
| `token_revoked` | Refresh token revoked |
|
||||
| `token_refreshed` | Refresh token used to obtain new tokens |
|
||||
| `generate_recovery_codes` | MFA recovery codes generated |
|
||||
| `factor_in_progress` | MFA factor enrollment started |
|
||||
| `factor_unenrolled` | MFA factor removed |
|
||||
| `challenge_created` | MFA challenge initiated |
|
||||
| `verification_attempted` | MFA verification attempt |
|
||||
| `factor_deleted` | MFA factor deleted |
|
||||
| `recovery_codes_deleted` | MFA recovery codes deleted |
|
||||
| `factor_updated` | MFA factor settings updated |
|
||||
| `mfa_code_login` | Login with MFA code |
|
||||
| `identity_unlinked` | An identity unlinked from account |
|
||||
|
||||
## Limitations
|
||||
|
||||
- There may be a short delay before logs appear
|
||||
- Query capabilities are limited to the dashboard interface
|
||||
@@ -112,7 +112,7 @@ response = supabase.auth.sign_in_anonymously()
|
||||
|
||||
## Convert an anonymous user to a permanent user
|
||||
|
||||
Converting an anonymous user to a permanent user requires [linking an identity](/docs/guides/auth/auth-identity-linking#manual-linking-beta) to the user. This requires you to [enable manual linking](/dashboard/project/_/settings/auth) in your Supabase project.
|
||||
Converting an anonymous user to a permanent user requires [linking an identity](/docs/guides/auth/auth-identity-linking#manual-linking-beta) to the user. This requires you to [enable manual linking](/dashboard/project/_/auth/providers) in your Supabase project.
|
||||
|
||||
### Link an email / phone identity
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ In the Settings page, look for the **Sitekey** section and copy the key.
|
||||
|
||||
## Enable CAPTCHA protection for your Supabase project
|
||||
|
||||
Navigate to the **[Auth](https://supabase.com/dashboard/project/_/settings/auth)** section of your Project Settings in the Supabase Dashboard and find the **Enable CAPTCHA protection** toggle under Settings > Authentication > Bot and Abuse Protection > Enable CAPTCHA protection.
|
||||
Navigate to the **[Auth](/dashboard/project/_/auth/protection)** section of your Project Settings in the Supabase Dashboard and find the **Enable CAPTCHA protection** toggle under Settings > Authentication > Bot and Abuse Protection > Enable CAPTCHA protection.
|
||||
|
||||
Select your CAPTCHA provider from the dropdown, enter your CAPTCHA **Secret key**, and click **Save**.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ sitemapPriority: 0.5
|
||||
|
||||
As of 7th Feb 2024, [this repository](https://github.com/supabase-community/auth-ui) is no longer maintained by the Supabase Team. At the moment, the team does not have capacity to give the expected level of care to this repository. We may revisit Auth UI in the future but regrettably have to leave it on hold for now as we focus on other priorities such as improving the Server-Side Rendering (SSR) package and advanced Auth primitives.
|
||||
|
||||
As an alternative you can use the [Supabase UI Library](https://supabase.com/ui) which has auth ready blocks to use in your projects.
|
||||
As an alternative you can use the [Supabase UI Library](/ui) which has auth ready blocks to use in your projects.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ npm install @supabase/auth-helpers-react
|
||||
|
||||
## Set up environment variables
|
||||
|
||||
Retrieve your project URL and anon key in your project's [API settings](https://supabase.com/dashboard/project/_/settings/api) in the Dashboard to set up the following environment variables. For local development you can set them in a `.env.local` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/nextjs/.env.local.example).
|
||||
Retrieve your project URL and anon key in your project's [API settings](/dashboard/project/_/settings/api) in the Dashboard to set up the following environment variables. For local development you can set them in a `.env.local` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/nextjs/.env.local.example).
|
||||
|
||||
```bash .env.local
|
||||
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
|
||||
@@ -132,7 +132,7 @@ You can now determine if a user is authenticated by checking that the `user` obj
|
||||
|
||||
### Code Exchange API route
|
||||
|
||||
The `Code Exchange` API route is required for the [server-side auth flow](https://supabase.com/docs/guides/auth/server-side-rendering) implemented by the Next.js Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
The `Code Exchange` API route is required for the [server-side auth flow](/docs/guides/auth/server-side-rendering) implemented by the Next.js Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
|
||||
<Tabs
|
||||
scrollable
|
||||
|
||||
@@ -51,7 +51,7 @@ npm install @supabase/auth-helpers-nextjs @supabase/supabase-js
|
||||
|
||||
## Declare environment variables
|
||||
|
||||
Retrieve your project's URL and anon key from your [API settings](https://supabase.com/dashboard/project/_/settings/api), and create a `.env.local` file with the following environment variables:
|
||||
Retrieve your project's URL and anon key from your [API settings](/dashboard/project/_/settings/api), and create a `.env.local` file with the following environment variables:
|
||||
|
||||
```bash .env.local
|
||||
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
|
||||
|
||||
@@ -55,7 +55,7 @@ This library supports the following tooling versions:
|
||||
|
||||
## Set up environment variables
|
||||
|
||||
Retrieve your project URL and anon key in your project's [API settings](https://supabase.com/dashboard/project/_/settings/api) in the Dashboard to set up the following environment variables. For local development you can set them in a `.env` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/remix/.env.example).
|
||||
Retrieve your project URL and anon key in your project's [API settings](/dashboard/project/_/settings/api) in the Dashboard to set up the following environment variables. For local development you can set them in a `.env` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/remix/.env.example).
|
||||
|
||||
```bash .env
|
||||
SUPABASE_URL=YOUR_SUPABASE_URL
|
||||
@@ -64,7 +64,7 @@ SUPABASE_PUBLISHABLE_KEY=YOUR_SUPABASE_PUBLISHABLE_KEY
|
||||
|
||||
### Code Exchange route
|
||||
|
||||
The `Code Exchange` route is required for the [server-side auth flow](https://supabase.com/docs/guides/auth/server-side-rendering) implemented by the Remix Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
The `Code Exchange` route is required for the [server-side auth flow](/docs/guides/auth/server-side-rendering) implemented by the Remix Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
|
||||
<Tabs
|
||||
scrollable
|
||||
@@ -822,7 +822,7 @@ export default function Index() {
|
||||
|
||||
<Admonition type="tip">
|
||||
|
||||
Ensure you have [enabled replication](https://supabase.com/dashboard/project/_/database/publications) on the table you are subscribing to.
|
||||
Ensure you have [enabled replication](/dashboard/project/_/database/publications) on the table you are subscribing to.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ npm install @supabase/auth-helpers-sveltekit @supabase/supabase-js
|
||||
|
||||
### Declare environment variables
|
||||
|
||||
Retrieve your project's URL and anon key from your [API settings](https://supabase.com/dashboard/project/_/settings/api), and create a `.env.local` file with the following environment variables:
|
||||
Retrieve your project's URL and anon key from your [API settings](/dashboard/project/_/settings/api), and create a `.env.local` file with the following environment variables:
|
||||
|
||||
```bash .env.local
|
||||
# Find these in your Supabase project settings https://supabase.com/dashboard/project/_/settings/api
|
||||
@@ -161,7 +161,7 @@ Note that we are specifying `filterSerializedResponseHeaders` here. We need to t
|
||||
|
||||
### Code Exchange route
|
||||
|
||||
The `Code Exchange` route is required for the [server-side auth flow](https://supabase.com/docs/guides/auth/server-side-rendering) implemented by the SvelteKit Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
The `Code Exchange` route is required for the [server-side auth flow](/docs/guides/auth/server-side-rendering) implemented by the SvelteKit Auth Helpers. It exchanges an auth `code` for the user's `session`, which is set as a cookie for future requests made to Supabase.
|
||||
|
||||
<Tabs
|
||||
scrollable
|
||||
@@ -213,7 +213,7 @@ export const GET = async ({ url, locals: { supabase } }) => {
|
||||
|
||||
### Generate types from your database
|
||||
|
||||
In order to get the most out of TypeScript and its IntelliSense, you should import the generated Database types into the `app.d.ts` type definition file that comes with your SvelteKit project, where `import('./DatabaseDefinitions')` points to the generated types file outlined in [v2 docs here](https://supabase.com/docs/reference/javascript/release-notes#typescript-support) after you have logged in, linked, and generated types through the Supabase CLI.
|
||||
In order to get the most out of TypeScript and its IntelliSense, you should import the generated Database types into the `app.d.ts` type definition file that comes with your SvelteKit project, where `import('./DatabaseDefinitions')` points to the generated types file outlined in [v2 docs here](/docs/reference/javascript/release-notes#typescript-support) after you have logged in, linked, and generated types through the Supabase CLI.
|
||||
|
||||
```ts src/app.d.ts
|
||||
// src/app.d.ts
|
||||
@@ -368,7 +368,7 @@ export const load = async ({ fetch, data, depends }) => {
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
TypeScript types can be [generated with the Supabase CLI](https://supabase.com/docs/reference/javascript/typescript-support) and passed to `createSupabaseLoadClient` to add type support to the Supabase client.
|
||||
TypeScript types can be [generated with the Supabase CLI](/docs/reference/javascript/typescript-support) and passed to `createSupabaseLoadClient` to add type support to the Supabase client.
|
||||
|
||||
</Admonition>
|
||||
|
||||
@@ -785,7 +785,7 @@ export const handle: Handle = sequence(supabase, authorization)
|
||||
|
||||
### Client-side data fetching with RLS
|
||||
|
||||
For [row level security](https://supabase.com/docs/guides/database/postgres/row-level-security) to work properly when fetching data client-side, you need to use `supabaseClient` from `PageData` and only run your query once the session is defined client-side:
|
||||
For [row level security](/docs/guides/database/postgres/row-level-security) to work properly when fetching data client-side, you need to use `supabaseClient` from `PageData` and only run your query once the session is defined client-side:
|
||||
|
||||
```svelte src/routes/+page.svelte
|
||||
<script lang="ts">
|
||||
|
||||
@@ -200,7 +200,7 @@ The `before-user-created` hook solves this by:
|
||||
- Detecting that a user is about to be created
|
||||
- Providing the email address in the `user.email` field
|
||||
|
||||
Run the following snippet in your project's [SQL Editor](https://supabase.com/dashboard/project/_/sql/new). This will create a `signup_email_domains` table with some sample data and a `hook_restrict_signup_by_email_domain` function to be called by the `before-user-created` auth hook.
|
||||
Run the following snippet in your project's [SQL Editor](/dashboard/project/_/sql/new). This will create a `signup_email_domains` table with some sample data and a `hook_restrict_signup_by_email_domain` function to be called by the `before-user-created` auth hook.
|
||||
|
||||
```sql
|
||||
-- Create ENUM type for domain rule classification
|
||||
@@ -305,7 +305,7 @@ The `before-user-created` hook solves this by:
|
||||
- Allowing you to inspect the `app_metadata.provider`
|
||||
- Knowing the request came from an OAuth flow
|
||||
|
||||
Run the following snippet in your project's [SQL Editor](https://supabase.com/dashboard/project/_/sql/new). This will create a `hook_reject_discord_signups` function to be called by the `before-user-created` auth hook.
|
||||
Run the following snippet in your project's [SQL Editor](/dashboard/project/_/sql/new). This will create a `hook_reject_discord_signups` function to be called by the `before-user-created` auth hook.
|
||||
|
||||
```sql
|
||||
-- Create the function
|
||||
@@ -352,7 +352,7 @@ The `before-user-created` hook solves this by:
|
||||
- Detecting that a user is about to be created
|
||||
- Providing the IP address in the `metadata.ip_address` field
|
||||
|
||||
Run the following snippet in your project's [SQL Editor](https://supabase.com/dashboard/project/_/sql/new). This will create a `signup_networks` table with some sample data and a `hook_restrict_signup_by_network` function to be called by the `before-user-created` auth hook.
|
||||
Run the following snippet in your project's [SQL Editor](/dashboard/project/_/sql/new). This will create a `signup_networks` table with some sample data and a `hook_restrict_signup_by_network` function to be called by the `before-user-created` auth hook.
|
||||
|
||||
```sql SQL_EDITOR
|
||||
-- Create ENUM type for network rule classification
|
||||
@@ -607,7 +607,7 @@ The `before-user-created` hook solves this by:
|
||||
- Detecting that a user is about to be created
|
||||
- Providing the IP address in the `metadata.ip_address` field
|
||||
|
||||
Before creating the edge function run the following snippet in your project's [SQL Editor](https://supabase.com/dashboard/project/_/sql/new). This will create a `signup_networks` table with some sample data and a `hook_restrict_signup_by_network` function to be called by the `before-user-created` auth hook.
|
||||
Before creating the edge function run the following snippet in your project's [SQL Editor](/dashboard/project/_/sql/new). This will create a `signup_networks` table with some sample data and a `hook_restrict_signup_by_network` function to be called by the `before-user-created` auth hook.
|
||||
|
||||
```sql SQL_EDITOR
|
||||
-- Create ENUM type for network rule classification
|
||||
|
||||
@@ -88,7 +88,7 @@ response = supabase.auth.link_identity({'provider': 'google'})
|
||||
</$Show>
|
||||
</Tabs>
|
||||
|
||||
In the example above, the user will be redirected to Google to complete the OAuth2.0 flow. Once the OAuth2.0 flow has completed successfully, the user will be redirected back to the application and the Google identity will be linked to the user. You can enable manual linking from your project's authentication [configuration options](/dashboard/project/_/settings/auth) or by setting the environment variable `GOTRUE_SECURITY_MANUAL_LINKING_ENABLED: true` when self-hosting.
|
||||
In the example above, the user will be redirected to Google to complete the OAuth2.0 flow. Once the OAuth2.0 flow has completed successfully, the user will be redirected back to the application and the Google identity will be linked to the user. You can enable manual linking from your project's authentication [configuration options](/dashboard/project/_/auth/providers) or by setting the environment variable `GOTRUE_SECURITY_MANUAL_LINKING_ENABLED: true` when self-hosting.
|
||||
|
||||
## Unlink an identity
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ function AuthMFA() {
|
||||
|
||||
### Security configuration
|
||||
|
||||
Each code is valid for up to 5 minutes, after which a new one can be sent. Successive codes remain valid until expiry. When possible choose the longest code length acceptable to your use case, at a minimum of 6. This can be configured in the [Authentication Settings](/dashboard/project/_/settings/auth).
|
||||
Each code is valid for up to 5 minutes, after which a new one can be sent. Successive codes remain valid until expiry. When possible choose the longest code length acceptable to your use case, at a minimum of 6. This can be configured in the [Authentication Settings](/dashboard/project/_/auth/mfa).
|
||||
|
||||
Be aware that Phone MFA is vulnerable to SIM swap attacks where an attacker will call a mobile provider and ask to port the target's phone number to a new SIM card and then use the said SIM card to intercept an MFA code. Evaluate the your application's tolerance for such an attack. You can read more about SIM swapping attacks [here](https://en.wikipedia.org/wiki/SIM_swap_scam)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ A non-exhaustive list of services that work with Supabase Auth is:
|
||||
- [ZeptoMail](https://www.zoho.com/zeptomail/help/smtp-home.html)
|
||||
- [Brevo](https://help.brevo.com/hc/en-us/articles/7924908994450-Send-transactional-emails-using-Brevo-SMTP)
|
||||
|
||||
Once you've set up your account with an email sending service, head to the [Authentication settings page](/dashboard/project/_/settings/auth) to enable and configure custom SMTP.
|
||||
Once you've set up your account with an email sending service, head to the [Authentication settings page](/dashboard/project/_/auth/smtp) to enable and configure custom SMTP.
|
||||
|
||||
You can also configure custom SMTP using the Management API:
|
||||
|
||||
|
||||
Loaded 100 of 1029 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user