Merge branch 'master' into feat/docs2.0

This commit is contained in:
Terry Sutton
2022-11-17 09:20:50 -03:30
206 changed files with 8306 additions and 2570 deletions

View File

@@ -52,7 +52,8 @@ jobs:
- uses: docker/build-push-action@v3
with:
push: true
context: '{{defaultContext}}:studio'
context: '{{defaultContext}}'
file: studio/Dockerfile
target: production
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}

View File

@@ -79,7 +79,7 @@ Then visit, and edit, any of the following sites:
#### Running sites individually
You can run any of the sites indiviudally by using the scope name. For example:
You can run any of the sites individually by using the scope name. For example:
```sh
npm run dev:www

View File

@@ -6,8 +6,8 @@ interface Props {
title: string
description?: string
to: string
icon?: string | ReactNode
children?: ReactNode
icon?: string | any
children?: any
layout?: 'vertical' | 'horizontal'
}

View File

@@ -0,0 +1,35 @@
import React, { useState } from 'react'
import extensions from '../data/extensions.json'
export default function Extensions() {
const [filter, setFilter] = useState('')
return (
<>
<div className="mb-8 grid">
<label className="text-xs mb-2">Filter extensions</label>
<input
type="text"
className="border text-gray-200"
placeholder="Extension name"
onChange={(e) => setFilter(e.target.value)}
/>
</div>
<div className="grid sm:grid-cols-2 gap-4">
{extensions
.filter((x) => x.name.indexOf(filter) >= 0)
.map((extension) => (
<div className={' my-2 px-2'} key={extension.name}>
<div className="border rounded-sm p-4">
<h3 className="m-0">
<code className="text-sm">{extension.name}</code>
</h3>
<p className=" mt-4">
{extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)}
</p>
</div>
</div>
))}
</div>
</>
)
}

View File

@@ -0,0 +1,74 @@
import { FC } from 'react'
import { removeAnchor } from './CustomHTMLElements/CustomHTMLElements.utils'
const formatSlug = (slug: string) => {
// [Joshen] We will still provide support for headers declared like this:
// ## REST API {#rest-api-overview}
// At least for now, this was a docusaurus thing.
if (slug.includes('#')) return slug.split('#')[1]
return slug
}
const formatTOCHeader = (content: string) => {
let begin = false
const res = []
for (const x of content) {
if (x === '`') {
if (!begin) {
begin = true
res.push(`<code class="text-xs border rounded bg-scale-400 border-scale-500">`)
} else {
begin = false
res.push(`</code>`)
}
} else {
res.push(x)
}
}
return res.join('')
}
interface TOCHeader {
id: number
level: number
text: string
link: string
}
interface Props {
list: TOCHeader[]
}
const GuidesTableOfContents: FC<Props> = ({ list }) => {
return (
<ul className="toc-menu list-none pl-4 text-[0.8rem] grid gap-2 mt-12">
{list.map((item, i) => (
<li key={`${item.level}-${i}`} className={item.level === 3 ? 'ml-4' : ''}>
<a
href={`#${formatSlug(item.link)}`}
className="text-scale-1000 hover:text-brand-900 transition-colors"
dangerouslySetInnerHTML={{ __html: formatTOCHeader(removeAnchor(item.text)) }}
/>
</li>
))}
</ul>
// <ul className="toc-menu list-none pl-4 text-[0.8rem] grid gap-2 mt-12">
// {(toc.json as TOCHeader[])
// .filter((item) => item.lvl !== 1 && item.lvl <= 3)
// .map((item: any, i: number) => {
// return (
// <li key={i} id={item.lvl} style={{ marginLeft: `${(item.lvl - 2) * 1}rem` }}>
// <a
// href={`#${formatSlug(item.slug)}`}
// className="text-scale-1000 hover:text-brand-900 transition-colors"
// dangerouslySetInnerHTML={{ __html: formatTOCHeader(removeAnchor(item.content)) }}
// />
// </li>
// )
// })}
// </ul>
)
}
export default GuidesTableOfContents

View File

@@ -9,7 +9,7 @@ export default function LinkCard({
}: {
title: string
description: string
icon: ReactElement
icon: any
link: string
}) {
return (

View File

@@ -1,5 +1,5 @@
import { ReactElement } from 'react'
export default function LinkCardsWrapper({ children }: { children: ReactElement }) {
export default function LinkCardsWrapper({ children }: { children: any }) {
return <div className="flex w-full flex-col lg:flex-row lg:flex-wrap">{children}</div>
}

View File

@@ -110,15 +110,17 @@ const AlgoliaSearch: FC<Props> = ({}) => {
: 'capitalize'
}`}
>
{item.category}
{item.version ? ` (${item.version})` : ''}:
<>
{item.category}
{item.version ? ` (${item.version})` : ''}:
</>
</p>
)}
<p>
<components.Highlight hit={item} attribute="title" />
</p>
</div>
<p className="aa-ItemContentSubtitle">{item.description}</p>
<p className="aa-ItemContentSubtitle">{item.description as string}</p>
</div>
</a>
)

View File

@@ -1,3 +1,7 @@
// [Terry]
// Delete this after we've implemented GuidesTableofContents and moved all guides
// and rename GuidesTableofContents to TableOfContents
import { FC } from 'react'
import { getAnchor, removeAnchor } from './CustomHTMLElements/CustomHTMLElements.utils'

View File

@@ -11,11 +11,13 @@ import JwtGenerator from './JwtGenerator'
import Frameworks from './Frameworks'
import AuthProviders from './AuthProviders'
import FunctionsExamples from './FunctionsExamples'
import Extensions from './Extensions'
// Other components
import { Heading } from './CustomHTMLElements'
import QuickstartIntro from './MDX/quickstart_intro.mdx'
import ProjectSetup from './MDX/project_setup.mdx'
import { Mermaid } from 'mdx-mermaid/lib/Mermaid'
const components = {
Admonition,
@@ -28,6 +30,8 @@ const components = {
JwtGenerator,
QuickstartIntro,
ProjectSetup,
Mermaid,
Extensions,
Alert: (props: any) => (
<Alert {...props} className="not-prose">
{props.children}

0
apps/docs/docs/.gitkeep Normal file
View File

View File

@@ -1,6 +0,0 @@
---
title: '404'
description: 'Page not found'
---
# Page not found

View File

@@ -1,172 +0,0 @@
---
id: features
title: Features
description: 'Supabase features'
---
This is a non-exhaustive list of features that Supabase provides for every project.
## Database
### Postgres Database
Every project is a full Postgres database. [Docs](/docs/guides/database).
### Database Extensions
Every database comes with a full set of Postgres extensions. [Docs](/docs/guides/database/extensions).
### Database Functions
Create custom database functions which you can call from the browser. [Docs](/docs/guides/database/functions).
### Database Triggers
Attach triggers to your tables to handle database changes. [Docs](/docs/guides/auth/managing-user-data#using-triggers).
### Database Webhooks
Send database changes to any external service using Webhooks. [Link](https://supabase.com/blog/supabase-functions-updates#database-webhooks-alpha).
### Database Backups
Projects are backed up daily with the option to upgrade to Point in Time recovery.
### Search
Build search functionality using Postgres Full Text Search. [Docs](/docs/guides/database/full-text-search).
### Secrets and encryption
Encrypt sensitive data and store secrets using our Postgres extension, Supabase Vault. [Link](https://supabase.com/blog/supabase-vault).
### Database migrations
Develop locally and push your changes to your production database using migrations. [Docs](/docs/guides/cli/local-development#database-migrations)
<br />
## Auth
### Email & Password Logins
Build email logins for your application or website. [Docs](/docs/guides/auth/auth-email).
### Magic Links
Build passwordless logins for your application or website.[Docs](/docs/guides/auth/auth-magic-link).
### Social Logins
Provide social logins - everything from Apple, to GitHub, to Slack. [Docs](/docs/guides/auth/auth-apple).
### Phone Logins
Provide phone logins using a 3rd-party SMS provider. [Docs](/docs/guides/auth/auth-twilio).
### Row Level Security
Control the data each user can access with Postgres Policies. [Docs](/docs/guides/auth/row-level-security).
### Serverside Auth Helpers
Helpers for implementing user authentication in popular frameworks like [Next.js](/docs/guides/auth/auth-helpers/nextjs) and [SvelteKit](/docs/guides/auth/auth-helpers/sveltekit)
### Auth UI Kit
Build login and registration pages with custom themes. [Docs](/docs/guides/auth/auth-helpers/auth-ui).
<br />
## APIs & Client libraries
### Auto-generated REST API
RESTful APIs are autogenerated from your database, without a single line of code. [Docs](/docs/guides/api#rest-api-overview).
### Auto-generated GraphQL API
Fast GraphQL APIs using our custom Postgres GraphQL extension. [Docs](/docs/guides/api#graphql-api-overview).
### Realtime Database changes
Receive your database changes through websockets. [Docs](/docs/guides/realtime/postgres-cdc).
### User Broadcasting
Send messages between connected users through websockets. [Docs](/docs/guides/realtime#broadcast).
### User Presence
Synchronize shared state across your users, including online status and typing indicators. [Docs](/docs/guides/realtime#presence).
### Client libraries
Official client libraries for [JavaScript](/docs/reference/javascript/) and [Dart](/docs/reference/dart).
Unofficial libraries [supported by the community](https://github.com/supabase-community#client-libraries).
<br />
## File Storage
### Large File storage
Supabase Storage makes it simple to store and serve large files. [Docs](/docs/guides/storage).
### Storage CDN
Cache large files using the Supabase CDN. [Docs](/docs/guides/storage-cdn).
<br />
## Edge Functions
### Deno Edge Functions
Globally distributed TypeScript functions to execute custom business logic. [Docs](/docs/guides/functions).
<br />
## Project Managment
### CLI
Use our CLI to develop your project locally and deploy to the Supabase Platform. [Docs](/docs/reference/cli).
### Management API
Manage your projects programmatically. [Docs](/docs/reference/api).
<br />
## Feature Status
Both Postgres and the Supabase Platform are production-ready. Some tools we offer on top of Postgres are still under development.
| Product | Feature | Stage |
| -------------------------- | ---------------------- | ------- |
| Database | Postgres | `GA` |
| Database | Triggers | `GA` |
| Database | Functions | `GA` |
| Database | Extensions | `GA` |
| Database | Full Text Search | `GA` |
| Database | Webhooks | `alpha` |
| Database | Point-in-Time Recovery | `alpha` |
| Database | Vault | `alpha` |
| Studio | | `GA` |
| Realtime | Postgres CDC | `beta` |
| Realtime | Broadcast | `alpha` |
| Realtime | Presence | `alpha` |
| Storage | Backend (S3) | `GA` |
| Storage | API | `beta` |
| Storage | CDN | `beta` |
| Edge Functions | | `beta` |
| Auth | OAuth Providers | `beta` |
| Auth | Passwordless | `beta` |
| Auth | Next.js Auth Helpers | `alpha` |
| Auth | SvelteKit Auth Helpers | `alpha` |
| Auth | Remix Auth Helpers | `alpha` |
| Management API | | `beta` |
| CLI | | `beta` |
| Client Library: JavaScript | | `GA` |
| Client Library: Dart | | `beta` |

View File

@@ -1,11 +0,0 @@
---
id: examples
title: Examples
description: Useful Supabase Edge Functions Examples
---
You can find a list of useful [Edge Function Examples](https://github.com/supabase/supabase/tree/master/examples/edge-functions) in our GitHub repository.
<div className="container" style={{ padding: 0 }}>
<FunctionsExamples />
</div>

View File

@@ -1,12 +0,0 @@
---
id: storage-sample
title: 'Storage Sample Doc'
description: Storage Sample Doc
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
## Description
Sample...

View File

@@ -24,5 +24,5 @@ Read [this post](https://supabase.com/blog/supabase-storage) on why we decided t
- [Source Code](https://github.com/supabase/storage-api)
- [Known bugs and issues](https://github.com/supabase/storage-js/issues)
- [Storage Guides](/guides/storage)
- [Storage Guides](/docs/guides/storage)
- [OpenAPI Docs](https://supabase.github.io/storage-api/)

View File

@@ -1,5 +1,5 @@
import { useEffect, FC } from 'react'
import Head from 'next/head'
import { NextSeo } from 'next-seo'
import NavBar from '../components/Navigation/NavBar'
import SideBar from '../components/Navigation/SideBar'
import Footer from '../components/Footer'
@@ -36,16 +36,20 @@ const Layout: FC<Props> = ({ meta, children, toc }) => {
return (
<>
<Head>
<title>{meta?.title} | Supabase</title>
<meta name="description" content={meta?.description} />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" href="/docs/favicon.ico" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content={meta?.title} />
<meta property="og:description" content={meta?.description} />
<meta property="og:title" content={meta?.title} />
</Head>
<NextSeo
title={`${meta?.title} | Supabase`}
description={meta?.description ? meta?.description : meta?.title}
openGraph={{
title: meta?.title,
description: meta?.description,
url: `https://supabase.com/docs/${currentPage}`,
images: [
{
url: `https://supabase.com/docs/img/supabase-og-image.png`,
},
],
}}
/>
<main>
<NavBar />

View File

@@ -0,0 +1,112 @@
import { MDXProvider } from '@mdx-js/react'
import { useEffect, FC, useRef, useState } from 'react'
import { NextSeo } from 'next-seo'
import NavBar from '../components/Navigation/NavBar'
import SideBar from '../components/Navigation/SideBar'
import Footer from '../components/Footer'
import GuidesTableOfContents from '~/components/GuidesTableOfContents'
import { useRouter } from 'next/router'
import { getPageType } from '../lib/helpers'
import components from '~/components'
import { menuItems } from '../components/Navigation/Navigation.constants'
interface Props {
meta: { title: string; description?: string; hide_table_of_contents?: boolean }
children: any
toc?: any
currentPage: string
}
const Layout: FC<Props> = ({ meta, children }) => {
const { asPath } = useRouter()
const page = getPageType(asPath)
useEffect(() => {
const key = localStorage.getItem('supabaseDarkMode')
if (!key) {
// Default to dark mode if no preference config
document.documentElement.className = 'dark'
} else {
document.documentElement.className = key === 'true' ? 'dark' : ''
}
}, [])
const articleRef = useRef()
const [tocList, setTocList] = useState([])
useEffect(() => {
const articleEl = articleRef.current as HTMLElement
if (!articleRef.current) return
const headings = Array.from(articleEl.querySelectorAll('h2, h3'))
const newHeadings = headings
.filter((heading) => heading.id)
.map((heading) => {
const text = heading.textContent.replace('#', '')
const link = heading.querySelector('a').getAttribute('href')
const level = heading.tagName === 'H2' ? 2 : 3
return { text, link, level }
})
setTocList(newHeadings)
}, [])
const hasTableOfContents = tocList.length > 0
return (
<>
<NextSeo
title={`${meta?.title} | Supabase`}
description={meta?.description ? meta?.description : meta?.title}
openGraph={{
title: meta?.title,
description: meta?.description,
url: `https://supabase.com/docs${asPath}`,
images: [
{
url: `https://supabase.com/docs/img/supabase-og-image.png`,
},
],
}}
/>
<main>
<NavBar currentPage={page} />
<div className="flex w-full flex-row">
<SideBar menuItems={menuItems[page]} />
<div className="main-content-pane docs-width grid md:grid-cols-12 gap-4 justify-between p-4 pb-8 w-full">
<div
className={`${
meta?.hide_table_of_contents || !hasTableOfContents
? 'col-span-12 xl:col-start-2 xl:col-span-10 2xl:col-start-3 2xl:col-span-8'
: 'col-span-12 lg:col-span-9'
} py-2 lg:py-4 px-2 lg:px-8 mx-auto`}
>
<article
ref={articleRef}
className={`${
meta?.hide_table_of_contents || !hasTableOfContents ? 'xl:min-w-[880px]' : ''
} doc-content-container prose dark:prose-dark dark:bg-scale-200 width-full mt-8 2xl:max-w-[880px]`}
>
{meta?.title && <h1>{meta.title}</h1>}
<MDXProvider components={components}>{children}</MDXProvider>
</article>
</div>
{hasTableOfContents && !meta?.hide_table_of_contents && (
<div
className={[
'border-scale-400 dark:bg-scale-200 table-of-contents-height border-l',
'thin-scrollbar overflow-y-auto sticky hidden xl:block md:col-span-3 px-2',
].join(' ')}
>
<GuidesTableOfContents list={tocList} />
</div>
)}
</div>
</div>
<Footer />
</main>
</>
)
}
export default Layout

View File

@@ -45,7 +45,7 @@ export function getDocsBySlug(slug: string) {
// if no match, 404
if (!fs.existsSync(fullPath)) {
console.log(`\nfile ${fullPath} not found, redirect to 404\n`)
fullPath = join(docsDirectory, 'docs/404.mdx')
fullPath = join(docsDirectory, 'pages/404.mdx')
}
const fileContents = fs.readFileSync(fullPath, 'utf8')

View File

@@ -1,10 +1,8 @@
import nextMdx from '@next/mdx'
import bundleAnalyzer from '@next/bundle-analyzer'
import remarkGfm from 'remark-gfm'
import rehypeSlug from 'rehype-slug'
import theme from 'shiki/themes/nord.json' assert { type: 'json' }
//import theme from 'shiki/themes/nord.json' assert { type: 'json' }
import { remarkCodeHike } from '@code-hike/mdx'
import withTM from 'next-transpile-modules'
@@ -35,14 +33,10 @@ const withMDX = nextMdx({
],
rehypePlugins: [rehypeSlug],
// This is required for `MDXProvider` component
providerImportSource: '@mdx-js/react',
// providerImportSource: '@mdx-js/react',
},
})
// const withBundleAnalyzer = bundleAnalyzer({
// enabled: process.env.ANALYZE === 'true',
// })
// /** @type {NextConfig} */
const nextConfig = {
// Append the default value with md extensions
@@ -54,6 +48,27 @@ const nextConfig = {
dangerouslyAllowSVG: true,
domains: ['avatars.githubusercontent.com', 'github.com', 'user-images.githubusercontent.com'],
},
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Strict-Transport-Security',
value: '',
},
{
key: 'X-Robots-Tag',
value: 'all',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
],
},
]
},
}
// next.config.js

View File

@@ -51,11 +51,13 @@
"jsrsasign": "^10.5.26",
"lodash": "^4.17.21",
"markdown-toc": "^1.2.0",
"mdx-mermaid": "2.0.0-rc3",
"next": "12.1.0",
"next-compose-plugins": "^2.2.1",
"next-mdx-remote": "^4.1.0",
"next-mdx-toc": "^0.1.3",
"next-plugin-yaml": "^1.0.1",
"next-seo": "^5.14.1",
"next-themes": "0.0.15",
"next-transpile-modules": "^9.0.0",
"octokit": "^2.0.10",

6
apps/docs/pages/404.mdx Normal file
View File

@@ -0,0 +1,6 @@
export const meta = {
title: '404',
description: 'Page not found',
}
# Page not found

View File

@@ -30,7 +30,6 @@ export default function Doc({ meta, content, toc }: Props) {
export async function getStaticProps({ params }: { params: { slug: string[] } }) {
let slug
if (params.slug.length > 1) {
slug = `docs/${params.slug.join('/')}`
} else {

View File

@@ -1,8 +1,10 @@
---
id: architecture
title: Architecture
description: 'Supabase design and architecture'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'architecture',
title: 'Architecture',
description: 'Supabase design and architecture',
}
Supabase is open source. We choose open source tools which are scalable and make them simple to use.
@@ -154,3 +156,7 @@ As the profile of a developer changes over time, Supabase will continue to evolv
Supabase supports existing tools and communities wherever possible. Supabase is more like a "community of communities" - each tool typically has its own community
which we work with.
Open source is something we approach [collaboratively](https://supabase.com/blog/supabase-series-b#giving-back): we employ maintainers, sponsor projects, invest in businesses, and develop our own open source tools.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: faq
title: FAQs
description: 'Most frequently asked questions regarding Supabase'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'faq',
title: 'FAQs',
description: 'Most frequently asked questions regarding Supabase',
}
### Where do I find support?
@@ -36,3 +38,7 @@ We only support PostgreSQL. It's unlikely we'll ever move away from Postgres; ho
We officially support [JavaScript](/docs/reference/javascript/installing) and [Flutter](/docs/reference/dart/installing).
You can find community-supported libraries in our [GitHub Community](https://github.com/supabase-community), and you can also help us to identify the most popular languages by [voting for a new client library](https://github.com/supabase/supabase/discussions/5).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: features
title: Features
description: 'Supabase features'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'features',
title: 'Features',
description: 'Supabase features',
}
This is a non-exhaustive list of features that Supabase provides for every project.
@@ -170,3 +172,7 @@ Both Postgres and the Supabase Platform are production-ready. Some tools we offe
| CLI | | `beta` |
| Client Library: JavaScript | | `GA` |
| Client Library: Dart | | `beta` |
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: api
title: Serverless APIs
description: Auto-generating and Realtime APIs.
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'api',
title: 'Serverless APIs',
description: 'Auto-generating and Realtime APIs.',
sidebar_label: 'Overview',
}
Supabase auto-generates three types of API directly from your database schema.
@@ -319,8 +321,8 @@ called `supabase_realtime`, and by managing this publication you can control whi
### Securing your Routes
Your API is designed to work with Postgres Row Level Security (RLS). If you use Supabase [Auth](/guides/auth), you can restrict data based on the logged-in user.
To control access to your data, you can use [Policies](/guides/auth#policies).
Your API is designed to work with Postgres Row Level Security (RLS). If you use Supabase [Auth](/docs/guides/auth), you can restrict data based on the logged-in user.
To control access to your data, you can use [Policies](/docs/guides/auth#policies).
When you create a table in Postgres, Row Level Security is disabled by default. To enable RLS:
<Tabs
@@ -373,3 +375,7 @@ The expected value for `useconfig` should be:
```sql
['session_preload_libraries=supautils, safeupdate']
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: generating-types
title: 'Generating Types'
description: How to generate types for your API and Supabase libraries.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'generating-types',
title: 'Generating Types',
description: 'How to generate types for your API and Supabase libraries.',
}
Supabase APIs are generated from your database, which means that we can use database introspection to generate type-safe API definitions.
@@ -105,3 +107,7 @@ Alternatively, you can use a community-supported GitHub action: [generate-supaba
## Resources
- [Generating Supabase types with GitHub Actions](https://blog.esteetey.dev/how-to-create-and-test-a-github-action-that-generates-types-from-supabase-database)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: auth
title: Auth
description: Use Supabase to Authenticate and Authorize your users.
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Auth',
description: 'Use Supabase to Authenticate and Authorize your users.',
sidebar_label: 'Overview',
}
## Overview
@@ -120,3 +122,7 @@ When users sign up, Supabase assigns them a unique ID. You can reference this ID
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/auth-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-apple
title: 'Login with Apple'
description: Add Apple OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-apple',
title: 'Login with Apple',
description: 'Add Apple OAuth to your Supabase project',
}
To enable Apple Auth for your project, you need to set up an Apple OAuth application and add the application credentials to your Supabase Dashboard.
@@ -202,3 +201,7 @@ async function signout() {
- [Ruby](https://www.ruby-lang.org/en/) Docs.
- [ruby-jwt](https://github.com/jwt/ruby-jwt) library.
- Thanks to [Janak Amarasena](https://medium.com/@janakda) who did all the heavy lifting in [How to configure Sign In with Apple](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-azure
title: 'Login with Azure'
description: Add Azure OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-azure',
title: 'Login with Azure',
description: 'Add Azure OAuth to your Supabase project',
}
To enable Azure Auth for your project, you need to set up an Azure OAuth application and add the application credentials to your Supabase Dashboard.
@@ -98,3 +97,7 @@ async function signout() {
- [Azure Developer Account](https://portal.azure.com)
- [GitHub Discussion](https://github.com/supabase/gotrue/pull/54#issuecomment-757043573)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-bitbucket
title: 'Login with Bitbucket'
description: Add Bitbucket OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-bitbucket',
title: 'Login with Bitbucket',
description: 'Add Bitbucket OAuth to your Supabase project',
}
To enable Bitbucket Auth for your project, you need to set up a BitBucket OAuth application and add the application credentials to your Supabase Dashboard.
@@ -90,3 +89,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Bitbucket Account](https://bitbucket.org)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-captcha
title: 'Enable Captcha Protection'
description: Add Captcha Protection to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-captcha',
title: 'Enable Captcha Protection',
description: 'Add Captcha Protection to your Supabase project',
}
Supabase provides you with the option of adding captcha to your sign-in, sign-up, and password reset forms. This keeps your website safe from bots and malicious scripts. Supabase authentication has support for [hCaptcha](https://www.hcaptcha.com/).
@@ -109,3 +108,7 @@ captcha.current.resetCaptcha()
In order to test that this works locally we will need to use something like [ngrok](https://ngrok.com/) or add an entry to your hosts file. You can read more about this in the [hCaptcha docs](https://docs.hcaptcha.com/#local-development).
Run the application and you should now be provided with a captcha challenge.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-discord
title: 'Login with Discord'
description: Add Discord OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-discord',
title: 'Login with Discord',
description: 'Add Discord OAuth to your Supabase project',
}
To enable Discord Auth for your project, you need to set up a Discord Application and add the Application OAuth credentials to your Supabase Dashboard.
@@ -92,3 +91,7 @@ async function signout() {
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Discord Account](https://discord.com)
- [Discord Developer Portal](https://discord.com/developers)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-email
title: 'Login With Email'
description: Use Supabase to Authenticate and Authorize your users using email.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-email',
title: 'Login With Email',
description: 'Use Supabase to Authenticate and Authorize your users using email.',
}
## Overview
@@ -99,3 +98,7 @@ Future<void> signOut() async {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Supabase Flutter Client](https://github.com/supabase/supabase-flutter)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-facebook
title: 'Login with Facebook'
description: Add Facebook OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-facebook',
title: 'Login with Facebook',
description: 'Add Facebook OAuth to your Supabase project',
}
To enable Facebook Auth for your project, you need to set up a Facebook OAuth application and add the application credentials to your Supabase Dashboard.
@@ -107,3 +106,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Facebook Developers Dashboard](https://developers.facebook.com/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-github
title: 'Login with GitHub'
description: Add GitHub OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-github',
title: 'Login with GitHub',
description: 'Add GitHub OAuth to your Supabase project',
}
To enable GitHub Auth for your project, you need to set up a GitHub OAuth application and add the application credentials to your Supabase Dashboard.
@@ -100,3 +99,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [GitHub Developer Settings](https://github.com/settings/developers)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-gitlab
title: 'Login with GitLab'
description: Add GitLab OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-gitlab',
title: 'Login with GitLab',
description: 'Add GitLab OAuth to your Supabase project',
}
To enable GitLab Auth for your project, you need to set up a GitLab OAuth application and add the application credentials to your Supabase Dashboard.
@@ -87,3 +86,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [GitLab Account](https://gitlab.com)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-google
title: 'Login with Google'
description: Add Google OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-google',
title: 'Login with Google',
description: 'Add Google OAuth to your Supabase project',
}
To enable Google Auth for your project, you need to set up a Google OAuth application and add the application credentials to your Supabase Dashboard.
@@ -115,3 +114,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Google Cloud Platform Console](https://console.cloud.google.com/home/dashboard)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: index
title: Auth Helpers
description: A collection of framework-specific Auth utilities for working with Supabase.
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'index',
title: 'Auth Helpers',
description: 'A collection of framework-specific Auth utilities for working with Supabase.',
sidebar_label: 'Overview',
}
A collection of framework-specific Auth utilities for working with Supabase.
@@ -52,3 +54,7 @@ The Auth Helpers are in `beta`. They are usable in their current state, but it's
- [Source code](https://github.com/supabase/auth-helpers)
- [Known bugs and issues](https://github.com/supabase/auth-helpers/issues)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: auth-ui
title: Auth UI
description: A prebuilt, customizable React component for authenticating users.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth-ui',
title: 'Auth UI',
description: 'A prebuilt, customizable React component for authenticating users.',
}
Auth UI is a pre-built React component for authenticating users.
It supports custom themes and extensible styles to match your brand and aesthetic.
@@ -273,3 +275,7 @@ const App = () => (
/>
)
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,11 @@
---
id: nextjs
title: Supabase Auth with Next.js
description: Authentication helpers for Next.js API routes, middleware, and SSR.
sidebar_label: 'Next.js'
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'nextjs',
title: 'Supabase Auth with Next.js',
description: 'Authentication helpers for Next.js API routes, middleware, and SSR.',
sidebar_label: 'Next.js',
}
This submodule provides convenience helpers for implementing user authentication in Next.js applications.
@@ -838,3 +837,7 @@ import { Database } from '../database.types'
const supabaseClient = useSupabaseClient<Database>()
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,11 @@
---
id: remix
title: Supabase Auth with Remix
description: Authentication helpers for loaders and actions in Remix.
sidebar_label: 'Remix'
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'remix',
title: 'Supabase Auth with Remix',
description: 'Authentication helpers for loaders and actions in Remix.',
sidebar_label: 'Remix',
}
This submodule provides convenience helpers for implementing user authentication in Remix applications.
@@ -877,3 +876,7 @@ export default function ProtectedPage() {
return <pre>{JSON.stringify({ user, allRepos }, null, 2)}</pre>;
}
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,11 @@
---
id: sveltekit
title: Supabase Auth with SvelteKit
description: Convenience helpers for implementing user authentication in SvelteKit.
sidebar_label: SvelteKit
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'sveltekit',
title: 'Supabase Auth with SvelteKit',
description: 'Convenience helpers for implementing user authentication in SvelteKit.',
sidebar_label: 'SvelteKit',
}
This submodule provides convenience helpers for implementing user authentication in [SvelteKit](https://kit.svelte.dev/) applications.
@@ -53,21 +52,18 @@ PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Start off by creating a `db.ts` file inside of the `src/lib` directory and instantiate the `supabaseClient`.
```ts title=src/lib/db.ts
import { createClient } from '@supabase/auth-helpers-sveltekit';
import { env } from '$env/dynamic/public';
import { createClient } from '@supabase/auth-helpers-sveltekit'
import { env } from '$env/dynamic/public'
// or use the static env
// import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
export const supabaseClient = createClient(
env.PUBLIC_SUPABASE_URL,
env.PUBLIC_SUPABASE_ANON_KEY
);
export const supabaseClient = createClient(env.PUBLIC_SUPABASE_URL, env.PUBLIC_SUPABASE_ANON_KEY)
```
To make sure the client is initialized on the server and the client, include this file in `src/hooks.server.js` and `src/hooks.client.js`:
```ts
import '$lib/db';
import '$lib/db'
```
### Synchronizing the page store
@@ -76,21 +72,21 @@ Edit your `+layout.svelte` file and set up the client side.
```html title=src/routes/+layout.svelte
<script>
import { supabaseClient } from '$lib/db';
import { invalidate } from '$app/navigation';
import { onMount } from 'svelte';
import { supabaseClient } from '$lib/db'
import { invalidate } from '$app/navigation'
import { onMount } from 'svelte'
onMount(() => {
const {
data: { subscription }
data: { subscription },
} = supabaseClient.auth.onAuthStateChange(() => {
invalidate('supabase:auth');
});
invalidate('supabase:auth')
})
return () => {
subscription.unsubscribe();
};
});
subscription.unsubscribe()
}
})
</script>
<slot />
@@ -105,26 +101,26 @@ If some data is not updated on signin/signout you can fall back to `invalidateAl
To make the session available to the UI (pages, layouts), pass the session in the root layout server load function:
```ts title=src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types';
import { getServerSession } from '@supabase/auth-helpers-sveltekit';
import type { LayoutServerLoad } from './$types'
import { getServerSession } from '@supabase/auth-helpers-sveltekit'
export const load: LayoutServerLoad = async (event) => {
return {
session: await getServerSession(event)
};
};
session: await getServerSession(event),
}
}
```
In addition you can create a layout load function if you are using `invalidate('supabase:auth')`:
```ts title=src/routes/+layout.ts
import type { LayoutLoad } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import type { LayoutLoad } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
export const load: LayoutLoad = async (event) => {
const { session } = await getSupabase(event);
return { session };
};
const { session } = await getSupabase(event)
return { session }
}
```
This results in fewer server calls as the client manages the session on its own.
@@ -134,7 +130,6 @@ This results in fewer server calls as the client manages the session on its own.
In order to get the most out of TypeScript and it´s intellisense, you should import our types into the `app.d.ts` type definition file that comes with your SvelteKit project.
```ts title=src/app.d.ts
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
@@ -142,13 +137,13 @@ In order to get the most out of TypeScript and it´s intellisense, you should im
// and what to do when importing types
declare namespace App {
interface Supabase {
Database: import('./DatabaseDefinitions').Database;
SchemaName: 'public';
Database: import('./DatabaseDefinitions').Database
SchemaName: 'public'
}
// interface Locals {}
interface PageData {
session: import('@supabase/supabase-js').Session | null;
session: import('@supabase/supabase-js').Session | null
}
// interface Error {}
// interface Platform {}
@@ -161,7 +156,7 @@ You can now determine if a user is authenticated on the client-side by checking
```html title=src/routes/+page.svelte
<script>
import { page } from '$app/stores';
import { page } from '$app/stores'
</script>
{#if !$page.data.session}
@@ -178,17 +173,17 @@ For [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) to
```html
<script>
import { supabaseClient } from '$lib/db';
import { page } from '$app/stores';
import { supabaseClient } from '$lib/db'
import { page } from '$app/stores'
let loadedData = [];
let loadedData = []
async function loadData() {
const { data } = await supabaseClient.from('test').select('*').limit(20);
loadedData = data;
const { data } = await supabaseClient.from('test').select('*').limit(20)
loadedData = data
}
$: if ($page.data.session) {
loadData();
loadData()
}
</script>
@@ -203,8 +198,8 @@ For [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) to
```html title=src/routes/profile/+page.svelte
<script>
/** @type {import('./$types').PageData} */
export let data;
$: ({ user, tableData } = data);
export let data
$: ({ user, tableData } = data)
</script>
<div>Protected content for {user.email}</div>
@@ -215,22 +210,22 @@ For [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) to
For [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) to work in a server environment, you need to use the `getSupabase` helper to check if the user is authenticated. The helper requires the `event` and returns `session` and `supabaseClient`:
```ts title=src/routes/profile/+page.ts
import type { PageLoad } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { redirect } from '@sveltejs/kit'
export const load: PageLoad = async (event) => {
const { session, supabaseClient } = await getSupabase(event);
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw redirect(303, '/');
throw redirect(303, '/')
}
const { data: tableData } = await supabaseClient.from('test').select('*');
const { data: tableData } = await supabaseClient.from('test').select('*')
return {
user: session.user,
tableData
};
};
tableData,
}
}
```
## Protecting API routes
@@ -238,19 +233,19 @@ export const load: PageLoad = async (event) => {
Wrap an API Route to check that the user has a valid session. If they're not logged in the session is `null`.
```ts title=src/routes/api/protected-route/+server.ts
import type { RequestHandler } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { json, redirect } from '@sveltejs/kit';
import type { RequestHandler } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { json, redirect } from '@sveltejs/kit'
export const GET: RequestHandler = async (event) => {
const { session, supabaseClient } = await getSupabase(event);
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw redirect(303, '/');
throw redirect(303, '/')
}
const { data } = await supabaseClient.from('test').select('*');
const { data } = await supabaseClient.from('test').select('*')
return json({ data });
};
return json({ data })
}
```
If you visit `/api/protected-route` without a valid session cookie, you will get a 303 response.
@@ -260,36 +255,36 @@ If you visit `/api/protected-route` without a valid session cookie, you will get
Wrap an Action to check that the user has a valid session. If they're not logged in the session is `null`.
```ts title=src/routes/posts/+page.server.ts
import type { Actions } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { error, invalid } from '@sveltejs/kit';
import type { Actions } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { error, invalid } from '@sveltejs/kit'
export const actions: Actions = {
createPost: async (event) => {
const { request } = event;
const { session, supabaseClient } = await getSupabase(event);
const { request } = event
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
// the user is not signed in
throw error(403, { message: 'Unauthorized' });
throw error(403, { message: 'Unauthorized' })
}
// we are save, let the user create the post
const formData = await request.formData();
const content = formData.get('content');
const formData = await request.formData()
const content = formData.get('content')
const { error: createPostError, data: newPost } = await supabaseClient
.from('posts')
.insert({ content });
.insert({ content })
if (createPostError) {
return invalid(500, {
supabaseErrorMessage: createPostError.message
});
supabaseErrorMessage: createPostError.message,
})
}
return {
newPost
};
}
};
newPost,
}
},
}
```
If you try to submit a form with the action `?/createPost` without a valid session cookie, you will get a 403 error response.
@@ -297,50 +292,50 @@ If you try to submit a form with the action `?/createPost` without a valid sessi
## Saving and deleting the session
```ts
import type { Actions } from './$types';
import { invalid, redirect } from '@sveltejs/kit';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import type { Actions } from './$types'
import { invalid, redirect } from '@sveltejs/kit'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
export const actions: Actions = {
signin: async (event) => {
const { request, cookies, url } = event;
const { session, supabaseClient } = await getSupabase(event);
const formData = await request.formData();
const { request, cookies, url } = event
const { session, supabaseClient } = await getSupabase(event)
const formData = await request.formData()
const email = formData.get('email') as string;
const password = formData.get('password') as string;
const email = formData.get('email') as string
const password = formData.get('password') as string
const { error } = await supabaseClient.auth.signInWithPassword({
email,
password
});
password,
})
if (error) {
if (error instanceof AuthApiError && error.status === 400) {
return invalid(400, {
error: 'Invalid credentials.',
values: {
email
}
});
email,
},
})
}
return invalid(500, {
error: 'Server error. Try again later.',
values: {
email
}
});
email,
},
})
}
throw redirect(303, '/dashboard');
throw redirect(303, '/dashboard')
},
signout: async (event) => {
const { supabaseClient } = await getSupabase(event);
await supabaseClient.auth.signOut();
throw redirect(303, '/');
}
};
const { supabaseClient } = await getSupabase(event)
await supabaseClient.auth.signOut()
throw redirect(303, '/')
},
}
```
## Protecting multiple routes
@@ -349,34 +344,31 @@ To avoid writing the same auth logic in every single route you can use the handl
protect multiple routes at once.
```ts title=src/hooks.server.ts
import type { RequestHandler } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { redirect, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { redirect, error } from '@sveltejs/kit'
export const handle: Handle = async ({ event, resolve }) => {
// protect requests to all routes that start with /protected-routes
if (event.url.pathname.startsWith('/protected-routes')) {
const { session, supabaseClient } = await getSupabase(event);
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw redirect(303, '/');
throw redirect(303, '/')
}
}
// protect POST requests to all routes that start with /protected-posts
if (
event.url.pathname.startsWith('/protected-posts') &&
event.request.method === 'POST'
) {
const { session, supabaseClient } = await getSupabase(event);
if (event.url.pathname.startsWith('/protected-posts') && event.request.method === 'POST') {
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw error(303, '/');
throw error(303, '/')
}
}
return resolve(event);
};
return resolve(event)
}
```
## Migrate from 0.7.x to 0.8 {#migration}
@@ -423,10 +415,7 @@ import { env } from '$env/dynamic/public'
// import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
export const supabaseClient = createClient(
env.PUBLIC_SUPABASE_URL,
env.PUBLIC_SUPABASE_ANON_KEY
);
export const supabaseClient = createClient(env.PUBLIC_SUPABASE_URL, env.PUBLIC_SUPABASE_ANON_KEY)
```
</TabPanel>
@@ -465,21 +454,21 @@ export const supabaseClient = createClient(
```html title=src/routes/+layout.svelte
<script>
import { supabaseClient } from '$lib/db';
import { invalidate } from '$app/navigation';
import { onMount } from 'svelte';
import { supabaseClient } from '$lib/db'
import { invalidate } from '$app/navigation'
import { onMount } from 'svelte'
onMount(() => {
const {
data: { subscription }
data: { subscription },
} = supabaseClient.auth.onAuthStateChange(() => {
invalidate('supabase:auth');
});
invalidate('supabase:auth')
})
return () => {
subscription.unsubscribe();
};
});
subscription.unsubscribe()
}
})
</script>
<slot />
@@ -576,13 +565,13 @@ declare namespace App {
// and what to do when importing types
declare namespace App {
interface Supabase {
Database: import('./DatabaseDefinitions').Database;
SchemaName: 'public';
Database: import('./DatabaseDefinitions').Database
SchemaName: 'public'
}
// interface Locals {}
interface PageData {
session: import('@supabase/auth-helpers-sveltekit').SupabaseSession;
session: import('@supabase/auth-helpers-sveltekit').SupabaseSession
}
// interface Error {}
// interface Platform {}
@@ -638,8 +627,8 @@ export const load: PageLoad = withAuth(async ({ session, getSupabaseClient }) =>
```html title=src/routes/protected-route/+page.svelte
<script>
/** @type {import('./$types').PageData} */
export let data;
$: ({ user, tableData } = data);
export let data
$: ({ user, tableData } = data)
</script>
<div>Protected content for {user.email}</div>
@@ -649,22 +638,22 @@ export const load: PageLoad = withAuth(async ({ session, getSupabaseClient }) =>
```ts title=src/routes/protected-route/+page.ts
// src/routes/profile/+page.ts
import type { PageLoad } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { redirect } from '@sveltejs/kit'
export const load: PageLoad = async (event) => {
const { session, supabaseClient } = await getSupabase(event);
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw redirect(303, '/');
throw redirect(303, '/')
}
const { data: tableData } = await supabaseClient.from('test').select('*');
const { data: tableData } = await supabaseClient.from('test').select('*')
return {
user: session.user,
tableData
};
};
tableData,
}
}
```
</TabPanel>
@@ -681,45 +670,43 @@ export const load: PageLoad = async (event) => {
<TabPanel id="older-0-7" label="0.7.x">
```ts title=src/routes/api/protected-route/+server.ts
import type { RequestHandler } from './$types';
import { withAuth } from '@supabase/auth-helpers-sveltekit';
import { json, redirect } from '@sveltejs/kit';
import type { RequestHandler } from './$types'
import { withAuth } from '@supabase/auth-helpers-sveltekit'
import { json, redirect } from '@sveltejs/kit'
interface TestTable {
id: string;
created_at: string;
id: string
created_at: string
}
export const GET: RequestHandler = withAuth(async ({ session, getSupabaseClient }) => {
if (!session.user) {
throw redirect(303, '/');
throw redirect(303, '/')
}
const { data } = await getSupabaseClient()
.from<TestTable>('test')
.select('*');
const { data } = await getSupabaseClient().from<TestTable>('test').select('*')
return json({ data });
});
return json({ data })
})
```
</TabPanel>
<TabPanel id="0.8.0" label="0.8.0">
```ts title=src/routes/api/protected-route/+server.ts
import type { RequestHandler } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { json, redirect } from '@sveltejs/kit';
import type { RequestHandler } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { json, redirect } from '@sveltejs/kit'
export const GET: RequestHandler = async (event) => {
const { session, supabaseClient } = await getSupabase(event);
const { session, supabaseClient } = await getSupabase(event)
if (!session) {
throw redirect(303, '/');
throw redirect(303, '/')
}
const { data } = await supabaseClient.from('test').select('*');
const { data } = await supabaseClient.from('test').select('*')
return json({ data });
};
return json({ data })
}
```
</TabPanel>
@@ -1129,3 +1116,7 @@ export const GET: RequestHandler = withAuth(async ({ session, getSupabaseClient
- [SvelteKit example](https://github.com/supabase/auth-helpers/tree/main/examples/sveltekit)
- [SvelteKit Email/Password example](https://github.com/supabase/auth-helpers/tree/main/examples/sveltekit-email-password)
- [SvelteKit Magiclink example](https://github.com/supabase/auth-helpers/tree/main/examples/sveltekit-magic-link)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-keycloak
title: 'Login with Keycloak'
description: Add Keycloak OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-keycloak',
title: 'Login with Keycloak',
description: 'Add Keycloak OAuth to your Supabase project',
}
To enable Keycloak Auth for your project, you need to set up an Keycloak OAuth application and add the application credentials to your Supabase Dashboard.
@@ -84,3 +83,7 @@ async function signout() {
- You can find the keycloak openid endpoint configuration under the realm settings.
![Keycloak OpenID Endpoint Configuration](/docs/img/guides/auth-keycloak/keycloak-openid-endpoint-config.png)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-linkedin
title: 'Login with LinkedIn'
description: Add LinkedIn OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-linkedin',
title: 'Login with LinkedIn',
description: 'Add LinkedIn OAuth to your Supabase project',
}
To enable LinkedIn Auth for your project, you need to set up a LinkedIn OAuth application and add the application credentials to your Supabase Dashboard.
@@ -86,3 +85,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [LinkedIn Developer Dashboard](https://api.LinkedIn.com/apps)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-magic-link
title: 'Login With Magic Link'
description: Use Supabase to authenticate and authorize your users using magic links.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-magic-link',
title: 'Login With Magic Link',
description: 'Use Supabase to authenticate and authorize your users using magic links.',
}
Magic links are a form of passwordless logins where users click on a link sent to their email address to log in to their accounts.
Magic links only work with email addresses. By default, a user can only request a magic link once every 60 seconds.
@@ -91,3 +90,7 @@ Future<void> signOut() async {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Supabase Flutter Client](https://github.com/supabase/supabase-flutter)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-messagebird
title: Phone Auth with MessageBird
description: How to set up and use Mobile OTP with MessageBird and Supabase.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-messagebird',
title: 'Phone Auth with MessageBird',
description: 'How to set up and use Mobile OTP with MessageBird and Supabase.',
}
## Overview
@@ -281,3 +280,7 @@ The user does not have a password therefore will need to sign in via this method
- [MessageBird Signup](https://dashboard.messagebird.com/en/sign-up)
- [Supabase Dashboard](https://app.supabase.com)
- [Supabase Row Level Security](/docs/guides/auth#row-level-security)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,10 +1,11 @@
---
id: auth-mfa
title: 'Multi-Factor Authentication'
description: Add an additional layer of security to your apps with Supabase Auth multi-factor authentication.
---
import Layout from '~/layouts/DefaultGuideLayout'
import { Mermaid } from 'mdx-mermaid/Mermaid'
export const meta = {
id: 'auth-mfa',
title: 'Multi-Factor Authentication',
description:
'Add an additional layer of security to your apps with Supabase Auth multi-factor authentication.',
}
<Admonition type="note">
@@ -26,9 +27,9 @@ prone to malicious account takeovers. These can be prevented with
MFA because they require the user to provide proof of
both of these:
- Something they know.
- Something they know.
Password, or access to a social-login account.
- Something they have.
- Something they have.
Access to an authenticator app (a.k.a. TOTP), mobile phone or recovery code.
## Overview
@@ -39,9 +40,9 @@ authenticator app in the control of users.
Applications using MFA require two important flows:
1. **Enrollment flow.**
1. **Enrollment flow.**
This lets users set up and control MFA in your app.
2. **Authentication flow.**
2. **Authentication flow.**
This lets users sign in using any factors after the conventional login step.
Supabase Auth provides:
@@ -78,11 +79,11 @@ Level](https://pages.nist.gov/800-63-3-Implementation-Resources/63B/AAL/), a
standard measure about the assurance Supabase Auth has of the user's identity
for that particular session. There are two levels recognized today:
1. **Assurance Level 1: `aal1`**
1. **Assurance Level 1: `aal1`**
Means that the user's identity was verified using a conventional login method
such as email+password, magic link, one-time password, phone auth or social
login.
2. **Assurance Level 2: `aal2`**
2. **Assurance Level 2: `aal2`**
Means that the user's identity was additionally verified using at least one
second factor, such as a TOTP code.
@@ -95,15 +96,15 @@ for your application. JWTs without an `aal` claim are at the `aal1` level.
Adding MFA to your app involves these three steps:
1. **Add enrollment flow.**
1. **Add enrollment flow.**
You need to provide a UI within your app that your users will be able to set-up
MFA in. You can add this right after sign-up, or as part of a separate flow in
the settings portion of your app.
2. **Add challenge step to login.**
2. **Add challenge step to login.**
If a user has set-up MFA, your app's login flow needs to present a challenge
screen to the user asking them to prove they have access to the additional
factor.
3. **Enforce rules for MFA logins.**
3. **Enforce rules for MFA logins.**
Once your users have a way to enroll and log in with MFA, you need to enforce
authorization rules across your app: on the frontend, backend, API servers or
Row-Level Security policies.
@@ -113,12 +114,12 @@ Adding MFA to your app involves these three steps:
An enrollment flow provides a UI for users to set up additional authentication factors.
Most applications add the enrollment flow in two places within their app:
1. Right after login or sign up.
1. Right after login or sign up.
This lets users quickly set up MFA immediately after they log in or create an
account. We recommend encouraging all users to set up MFA if that makes sense
for your application. Many applications offer this as an opt-in step in an
effort to reduce onboarding friction.
2. From within a settings page.
2. From within a settings page.
Allows users to set up, disable or modify their MFA settings.
We recommend building one generic flow that you can reuse in both cases with
@@ -126,15 +127,15 @@ minor modifications.
Enrolling a factor for use with MFA takes three steps:
1. Call `supabase.auth.mfa.enroll()`.
1. Call `supabase.auth.mfa.enroll()`.
This method returns a QR code and a secret. Display the QR
code to the user and ask them to scan it with their authenticator application.
If they are unable to scan the QR code, show the secret in plain text which
they can type or paste into their authenticator app.
2. Calling the `supabase.auth.mfa.challenge()` API.
2. Calling the `supabase.auth.mfa.challenge()` API.
This prepares Supabase Auth to accept a verification code from the user
and returns a challenge ID.
3. Calling the `supabase.auth.mfa.verify()` API.
3. Calling the `supabase.auth.mfa.verify()` API.
This verifies that the user has indeed added the secret from step (1) into
their app and is working correctly. If the verification succeeds, the factor
immediately becomes active for the user account. If not, you should repeat
@@ -400,15 +401,15 @@ application's database, APIs and server-side rendering.
Depending on your application's needs, there are three ways you can choose to
enforce MFA.
1. **Enforce for all users (new and existing).**
Any user account will have to enroll MFA to continue using your app.
1. **Enforce for all users (new and existing).**
Any user account will have to enroll MFA to continue using your app.
The application will not allow access without going through MFA first.
2. **Enforce for new users only.**
2. **Enforce for new users only.**
Only new users will be forced to enroll MFA, while old users will be encouraged
to do so.
to do so.
The application will not allow access for new users without going through MFA
first.
3. **Enforce only for users that have opted-in.**
3. **Enforce only for users that have opted-in.**
Users that want MFA can enroll in it and the application will not allow access
without going through MFA first.
@@ -547,14 +548,14 @@ using Row Level Security policies will give you sufficient protection. In the
event that you have other APIs that you wish to protect, follow these general
guidelines:
1. **Use a good JWT verification and parsing library for your language.**
1. **Use a good JWT verification and parsing library for your language.**
This will let you securely parse JWTs and extract their claims.
2. **Retrieve the `aal` claim from the JWT and compare its value according to
your needs.**
your needs.**
If you've encountered an AAL level that can be increased, ask the user to
continue the login process instead of logging them out.
3. **Use the `https://<project-ref>.supabase.co/rest/v1/auth/factors` REST
endpoint to identify if the user has enrolled any MFA factors.**
endpoint to identify if the user has enrolled any MFA factors.**
Only `verified` factors should be acted upon.
## Frequently asked questions
@@ -627,3 +628,7 @@ Currently recognized methods are:
- `mfa/totp` - a TOTP additional factor.
This list will expand in the future.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-notion
title: 'Login with Notion'
description: Add Notion OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-notion',
title: 'Login with Notion',
description: 'Add Notion OAuth to your Supabase project',
}
To enable Notion Auth for your project, you need to set up a Notion Application and add the Application OAuth credentials to your Supabase Dashboard.
@@ -90,3 +89,7 @@ async function signout() {
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Notion Account](https://notion.so)
- [Notion Developer Portal](https://www.notion.so/my-integrations)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-slack
title: 'Login with Slack'
description: Add Slack OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-slack',
title: 'Login with Slack',
description: 'Add Slack OAuth to your Supabase project',
}
To enable Slack Auth for your project, you need to set up a Slack OAuth application and add the application credentials to your Supabase Dashboard.
@@ -99,3 +98,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Slack Developer Dashboard](https://api.slack.com/apps)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-spotify
title: 'Login with Spotify'
description: Add Spotify OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-spotify',
title: 'Login with Spotify',
description: 'Add Spotify OAuth to your Supabase project',
}
To enable Spotify Auth for your project, you need to set up a Spotify OAuth application and add the application credentials to your Supabase Dashboard.
@@ -94,3 +93,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-twilio
title: Phone Auth with Twilio
description: How to set up and use Mobile OTP with Twilio and Supabase.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-twilio',
title: 'Phone Auth with Twilio',
description: 'How to set up and use Mobile OTP with Twilio and Supabase.',
}
## Overview
@@ -300,3 +299,7 @@ The user does not have a password therefore will need to sign in via this method
- [Twilio Signup](https://www.twilio.com/try-twilio)
- [Supabase Dashboard](https://app.supabase.com)
- [Supabase Row Level Security](/docs/guides/auth#row-level-security)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-twitch
title: 'Login with Twitch'
description: Add Twitch OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-twitch',
title: 'Login with Twitch',
description: 'Add Twitch OAuth to your Supabase project',
}
To enable Twitch Auth for your project, you need to set up a Twitch Application and add the Application OAuth credentials to your Supabase Dashboard.
@@ -106,3 +105,7 @@ async function signout() {
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Twitch Account](https://twitch.tv)
- [Twitch Developer Console](https://dev.twitch.tv/console)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-twitter
title: 'Login with Twitter'
description: Add Twitter OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-twitter',
title: 'Login with Twitter',
description: 'Add Twitter OAuth to your Supabase project',
}
To enable Twitter Auth for your project, you need to set up a Twitter OAuth application and add the application credentials to your Supabase Dashboard.
@@ -95,3 +94,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Twitter Developer Dashboard](https://developer.twitter.com/en/portal/dashboard)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-vonage
title: Phone Auth with Vonage
description: How to set up and use Mobile OTP with Vonage and Supabase.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-vonage',
title: 'Phone Auth with Vonage',
description: 'How to set up and use Mobile OTP with Vonage and Supabase.',
}
## Overview
@@ -272,3 +271,7 @@ The user does not have a password therefore will need to sign in via this method
- [Vonage Signup](https://dashboard.nexmo.com/sign-up)
- [Supabase Dashboard](https://app.supabase.com)
- [Supabase Row Level Security](/docs/guides/auth#row-level-security)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-workos
title: 'Login with WorkOS'
description: Add WorkOS OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-workos',
title: 'Login with WorkOS',
description: 'Add WorkOS OAuth to your Supabase project',
}
To enable WorkOS Auth for your project, you need to set up WorkOS OAuth application and add the application credentials to your Supabase Dashboard.
@@ -88,3 +87,7 @@ async function signout() {
## Resources
- [WorkOS Documentation](https://workos.com/docs/sso/guide)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: auth-zoom
title: 'Login with Zoom'
description: Add Zoom OAuth to your Supabase project
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'auth-zoom',
title: 'Login with Zoom',
description: 'Add Zoom OAuth to your Supabase project',
}
To enable Zoom Auth for your project, you need to set up a Zoom OAuth application and add the application credentials to your Supabase Dashboard.
@@ -95,3 +94,7 @@ async function signout() {
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Zoom App Marketplace](https://marketplace.zoom.us/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: managing-user-data
title: Managing User Data
description: Securing your user data with Row Level Security.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'managing-user-data',
title: 'Managing User Data',
description: 'Securing your user data with Row Level Security.',
}
For security purposes, the `auth` schema is not exposed on the auto-generated API.
@@ -59,9 +61,7 @@ The nice thing about this pattern? We can now query this table via the API and w
```js
// This will return nothing while the user is logged out
const { data } = await supabase
.from('profiles')
.select('id, username, avatar_url, website')
const { data } = await supabase.from('profiles').select('id, username, avatar_url, website')
// After the user is logged in, this will only return
// the logged-in user's data - in this case a single row
@@ -105,3 +105,7 @@ create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: row-level-security
title: Row Level Security
description: Secure your data using Postgres Row Level Security.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'row-level-security',
title: 'Row Level Security',
description: 'Secure your data using Postgres Row Level Security.',
}
When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security (RLS)](https://www.postgresql.org/docs/current/ddl-rowsecurity.html).
@@ -363,3 +365,7 @@ Deprecated. Use `auth.jwt() ->> 'email'` instead.
</Admonition>
Returns the email of the user making the request.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: server-side-rendering
title: Server-Side Rendering
description: Render pages with user information on the server.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'server-side-rendering',
title: 'Server-Side Rendering',
description: 'Render pages with user information on the server.',
}
Single-page apps with server-side rendering (SSR) is a popular way to optimize rendering
performance and leverage advanced caching strategies.
@@ -205,3 +207,7 @@ data belonging to different users!
Also be sure you set proper cache control headers. We recommend invalidating
cache keys every hour or less.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,10 +1,13 @@
---
id: cli
title: Supabase CLI
description: The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform.
sidebar_label: Overview
toc_max_heading_level: 2
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'cli',
title: 'Supabase CLI',
description:
'The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform.',
sidebar_label: 'Overview',
toc_max_heading_level: 2,
}
The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform.
You can also use the CLI to manage your Supabase projects, handle database migrations and CI/CD workflows, and generate types directly from your database schema.
@@ -20,6 +23,7 @@ You can also use the CLI to manage your Supabase projects, handle database migra
<TabPanel id="npm" label="npm">
Install the CLI as dev dependency via [npm](https://www.npmjs.com/package/supabase):
```sh
npm install supabase --save-dev
```
@@ -112,3 +116,7 @@ brew upgrade supabase
- [Supabase CLI Reference](/docs/reference/cli/usage)
- [Local Development](/docs/guides/cli/local-development)
- [Managing Environments](/docs/guides/cli/managing-environments)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: local-development
title: Local Development
description: How to use Supabase on your local development machine.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'local-development',
title: 'Local Development',
description: 'How to use Supabase on your local development machine.',
}
Learn how to use the Supabase CLI to develop your project locally and deploy to the Supabase Platform.
@@ -46,7 +45,7 @@ git init
supabase init
```
Make sure Docker is running. The [start](/docs/reference/cli/usage#supabase-start) command uses Docker to start the Supabase [services](/architecture).
Make sure Docker is running. The [start](/docs/reference/cli/usage#supabase-start) command uses Docker to start the Supabase [services](/docs/architecture).
This command may take a while to run if this is the first time using the CLI.
```bash
@@ -238,3 +237,7 @@ The local development environment is not as feature-complete as the Supabase Pla
```
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: managing-environments
title: Managing Environments
description: How to deploy Supabase schema changes with a CI / CD pipeline.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'managing-environments',
title: 'Managing Environments',
description: 'How to deploy Supabase schema changes with a CI / CD pipeline.',
}
## Overview
@@ -415,3 +414,7 @@ supabase db reset
In case [`reset`](/docs/reference/cli/usage#supabase-db-reset) fails, you can manually resolve conflicts by editing `<t+2>_dev_A.sql` file.
Once validated locally, commit your changes to Git and push to GitHub.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: database
title: Database
description: Use Supabase to manage your data.
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'database',
title: 'Database',
description: 'Use Supabase to manage your data.',
sidebar_label: 'Overview',
}
Every Supabase project comes with a full [Postgres](https://www.postgresql.org/) database, a free and open source
database which is considered one of the world's most stable and advanced databases.
@@ -85,3 +87,7 @@ Read about resetting your database password [here](/docs/guides/database/managin
- Read more about [Postgres](/docs/postgres/server/about)
- Sign in: [app.supabase.com](https://app.supabase.com)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: arrays
title: 'Working With Arrays'
description: How to use arrays in PostgreSQL and the Supabase API.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'arrays',
title: 'Working With Arrays',
description: 'How to use arrays in PostgreSQL and the Supabase API.',
}
PostgreSQL supports flexible [array types](https://www.postgresql.org/docs/12/arrays.html). These arrays are also supported in the Supabase Dashboard and in the JavaScript API.
@@ -160,3 +159,7 @@ returns:
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Supabase Account - Free Tier OK](https://supabase.com)
- [PostgreSQL Arrays](https://www.postgresql.org/docs/12/arrays.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: connecting-to-postgres
title: 'Database Connections'
description: There are various ways to connect to your Postgres database.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'connecting-to-postgres',
title: 'Database Connections',
description: 'There are various ways to connect to your Postgres database.',
}
Supabase provides several options for programmatically connecting to your Postgres database:
@@ -121,7 +123,7 @@ SSL enabled as illustrated below:
psql "sslmode=verify-full sslrootcert=$HOME/Downloads/prod-ca-2021.cer host=db.abcdefghijklm.supabase.co dbname=postgres user=postgres"
```
2. With `pgAdmin`
2. With `pgAdmin`
a. Register a new Postgres server
![Register a new postgres server.](/docs/img/guides/database/register-server-pgAdmin.png)
@@ -133,3 +135,7 @@ psql "sslmode=verify-full sslrootcert=$HOME/Downloads/prod-ca-2021.cer host=db.a
file-picker modal. Select the certificate you downloaded from your Supabase dashboard and save the server details. PgAdmin
should now be able to connect to your Postgres via SSL.
![Add Connection Info.](/docs/img/guides/database/add-ssl-config.png)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,10 @@
---
id: extensions
title: Overview
description: Using Postgres extensions.
---
import Layout from '~/layouts/DefaultGuideLayout'
import ExtensionsComponent from '@site/src/components/Extensions'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'extensions',
title: 'Overview',
description: 'Using Postgres extensions.',
}
Extensions are exactly as they sound - they "extend" the database with functionality which isn't part of the Postgres core.
Supabase has pre-installed some of the most useful open source extensions.
@@ -56,4 +54,8 @@ Enabling some extensions with `create extension <extension-name> with schema ext
Supabase is pre-configured with over 50 extensions. You can also install your own SQL extensions directly in the database through our SQL editor.
<ExtensionsComponent />
<Extensions />
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: http
title: 'http: RESTful Client'
description: An HTTP Client for PostgreSQL Functions.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'http',
title: 'http: RESTful Client',
description: 'An HTTP Client for PostgreSQL Functions.',
}
The `http` extension allows you to call RESTful endpoints within Postgres.
@@ -114,3 +113,7 @@ from
## Resources
- Official [`http` GitHub Repository](https://github.com/pramsey/pgsql-http)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,11 @@
---
id: pgcron
title: 'pg_cron: Job Scheduling'
description: 'pgnet: a simple cron-based job scheduler for PostgreSQL that runs inside the database.'
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'pgcron',
title: 'pg_cron: Job Scheduling',
description:
'pgnet: a simple cron-based job scheduler for PostgreSQL that runs inside the database.',
}
The `pg_cron` extension is a simple cron-based job scheduler for PostgreSQL that runs inside the database.
@@ -96,3 +96,7 @@ SELECT cron.unschedule('nightly-vacuum');
## Resources
- [pg_cron GitHub Repository](https://github.com/citusdata/pg_cron)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: pgnet
title: 'pg_net: Async Networking'
description: 'pg_net: an async networking extension for PostgreSQL.'
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'pgnet',
title: 'pg_net: Async Networking',
description: 'pg_net: an async networking extension for PostgreSQL.',
}
<Admonition type="caution">
@@ -251,3 +250,7 @@ Possible values for `net.http_response_result.status` are `('PENDING', 'SUCCESS'
- Source code: [github.com/supabase/pg_net](https://github.com/supabase/pg_net/)
- Official Docs: [supabase.github.io/pg_net](https://supabase.github.io/pg_net/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: pgtap
title: 'pgTAP: Unit Testing'
description: Unit testing in PostgreSQL.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'pgtap',
title: 'pgTAP: Unit Testing',
description: 'Unit testing in PostgreSQL.',
}
`pgTAP` is a unit testing extension for PostgreSQL.
@@ -156,3 +155,7 @@ API:
## Resources
- Official [`pgTAP` documentation](https://pgtap.org/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: plv8
title: 'plv8: JavaScript Language'
description: JavaScript language for PostgreSQL.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'plv8',
title: 'plv8: JavaScript Language',
description: 'JavaScript language for PostgreSQL.',
}
The `plv8` extension allows you use JavaScript within Postgres.
@@ -142,3 +141,7 @@ $$ language plv8;
- Official [`plv8` documentation](https://plv8.github.io/)
- [plv8 GitHub Repository](https://github.com/plv8/plv8)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: uuid-ossp
title: 'uuid-ossp: Unique Identifiers'
description: A UUID generator for PostgreSQL.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'uuid-ossp',
title: 'uuid-ossp: Unique Identifiers',
description: 'A UUID generator for PostgreSQL.',
}
The `uuid-ossp` extension can be used to generate a `UUID`.
@@ -63,9 +62,10 @@ Once the extension is enabled, you now have access to a `uuid` type.
Creates a UUID value based on the combination of computers MAC address, current timestamp, and a random value.
:::note
UUIDv1 leaks identifiable details, which might make it unsuitable for certain security-sensitive applications.
:::
<Admonition type="note">
UUIDv1 leaks identifiable details, which might make it unsuitable for certain security-sensitive
applications.
</Admonition>
### `uuid_generate_v4()`
@@ -97,3 +97,7 @@ create table contacts (
- [Choosing a Postgres Primary Key](https://supabase.com/blog/choosing-a-postgres-primary-key)
- [The Basics Of PostgreSQL `UUID` Data Type](https://www.postgresqltutorial.com/postgresql-uuid/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: full-text-search
title: 'Full Text Search'
description: How to use full text search in PostgreSQL.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'full-text-search',
title: 'Full Text Search',
description: 'How to use full text search in PostgreSQL.',
}
Postgres has built-in functions to handle `Full Text Search` queries. This is like a "search engine" within Postgres.
@@ -588,3 +587,7 @@ final result = await client
## Resources
- [PostgreSQL: Text Search Functions and Operators](https://www.postgresql.org/docs/12/functions-textsearch.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: functions
title: Database Functions
description: Creating and using Postgres functions.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'functions',
title: 'Database Functions',
description: 'Creating and using Postgres functions.',
}
Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html).
These functions live inside your database, and they can be [used with the API](../../reference/javascript/rpc).
@@ -344,3 +343,7 @@ GRANT EXECUTE ON FUNCTION hello_world TO service_role;
allowFullScreen
></iframe>
</div>
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: json
title: 'JSON'
description: Using the JSON data type in PostgreSQL.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'json',
title: 'JSON',
description: 'Using the JSON data type in PostgreSQL.',
}
PostgreSQL supports [JSON functions and operators](https://www.postgresql.org/docs/current/functions-json.html) which gives flexibility when storing data inside a database column.
@@ -266,3 +265,7 @@ Note that the `->` operator returns JSONB data. If you want TEXT/STRING data ret
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [PostgreSQL: JSON Functions and Operators](https://www.postgresql.org/docs/12/functions-json.html)
- [PostgreSQL JSON types](https://www.postgresql.org/docs/12/datatype-json.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: managing-passwords
title: 'Passwords'
description: How to change your PostgreSQL database password.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'managing-passwords',
title: 'Passwords',
description: 'How to change your PostgreSQL database password.',
}
Your PostgreSQL database is the core of your Supabase project, so it's important that it has a strong, secure password at all times.
@@ -28,3 +27,7 @@ It's absolutely critical that you store your customers' data safely. Here are so
## Resources
- [PostgreSQL `ALTER USER` Documentation](https://www.postgresql.org/docs/12/sql-alteruser.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,11 @@
---
id: managing-timezones
title: 'Timezones'
slug: managing-timezones
description: How to change your database timezone.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'managing-timezones',
title: 'Timezones',
slug: 'managing-timezones',
description: 'How to change your database timezone.',
}
Every Supabase database is set to UTC timezone by default. We strongly recommend keeping it this way, even if your users are in a different location.
This is because it makes it much easier to calculate differences between timezones if you adopt the mental model that "everything in my database is in UTC time".
@@ -75,3 +74,7 @@ where name ilike '%york%';
</TabPanel>
</Tabs>
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: replication
title: 'Replication'
slug: replication
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'replication',
title: 'Replication',
slug: 'replication',
}
Replication is a technique for copying the data from one database to another. Supabase uses replication functionality to provide a real-time API. Replication is useful for:
@@ -22,12 +21,7 @@ Replication is done through _publications_, a method of choosing which changes t
4. Control which tables broadcast changes by selecting **Source** and toggling each table.
<video width="99%" muted playsInline controls="true">
<source
src="/docs/videos/api/api-realtime.mp4"
type="video/mp4"
muted
playsInline
/>
<source src="/docs/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
</video>
## Create a publication
@@ -96,3 +90,7 @@ begin;
create publication publication_name;
commit;
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: sql-to-api
title: 'Converting SQL to JavaScript API'
description: Implementing common SQL patterns in the JavaScript API
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'sql-to-api',
title: 'Converting SQL to JavaScript API',
description: 'Implementing common SQL patterns in the JavaScript API',
}
<!-- @TODO: this one is a very daunting read on first attempt. Need to check what is the purpose of it? -->
@@ -81,3 +80,7 @@ const { data, error } = await supabase
- [Supabase API: JavaScript select](/docs/reference/javascript/select)
- [Supabase API: JavaScript modifiers](/docs/reference/javascript/using-modifiers)
- [Supabase API: JavaScript filters](/docs/reference/javascript/using-filters)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: tables
title: Tables and Data
description: Creating and using Postgres tables.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'tables',
title: 'Tables and Data',
description: 'Creating and using Postgres tables.',
}
Tables are where you store your data.
@@ -504,3 +503,7 @@ Creating a materialized view is not a solution to inefficient queries. You shoul
- [PostgreSQL Tutorial: Create tables](https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-create-table/)
- [PostgreSQL Tutorial: Add column](https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-add-column/)
- [PostgreSQL Tutorial: Views](https://www.postgresqltutorial.com/postgresql-views/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: testing
title: Testing Your Database
description: Test your database schema, tables, functions, and policies.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'testing',
title: 'Testing Your Database',
description: 'Test your database schema, tables, functions, and policies.',
}
You can use the Supabase CLI to test your database. The minimum required version of the CLI is [v1.11.4](https://github.com/supabase/cli/releases). To get started:
@@ -68,3 +67,7 @@ Result: PASS
- [pgTAP extension](/docs/guides/database/extensions/pgtap)
- Official [pgTAP documentation](https://pgtap.org/)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: timeouts
title: Timeouts
description: Timeouts and optimization
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'timeouts',
title: 'Timeouts',
description: 'Timeouts and optimization',
}
By default, Supabase limits the maximum statement execution time to _3 seconds_ for users accessing the API using the anon key, and _8 seconds_ for authenticated users. Additionally, all users are subject to a global limit of _2 minutes_. This serves as a backstop against resource exhaustion due to either poorly written queries, or abusive usage.
@@ -25,3 +27,7 @@ set statement_timeout to 60000; -- 1 minute in milliseconds
All Supabase projects come with the [`pg_stat_statements`](https://www.postgresql.org/docs/current/pgstatstatements.html) extension installed, which tracks planning and execution statistics for all statements executed against it. These statistics can be used in order to diagnose the performance of your project.
This data can further be used in conjunction with the [`explain`](https://www.postgresql.org/docs/current/using-explain.html) functionality of Postgres to optimize your usage.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,11 +1,10 @@
---
id: webhooks
title: 'Database Webhooks'
description: Trigger external payloads on database events.
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'webhooks',
title: 'Database Webhooks',
description: 'Trigger external payloads on database events.',
}
Database Webhooks allow you to send real-time data from your database to another system whenever a table event occurs.
@@ -71,3 +70,7 @@ type DeletePayload = {
## Resources
- [pg_net](/docs/guides/database/extensions/pgnet): an async networking extension for PostgreSQL
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: examples
title: Examples and Resources
description: 'Examples you can use to get started with Supabase'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'examples',
title: 'Examples and Resources',
description: 'Examples you can use to get started with Supabase',
}
<!-- This page is outdated and should not be added to the sidebar until it has been reworked -->
@@ -153,3 +155,7 @@ Build a basic Todo List with Supabase and your favorite frontend framework:
- [Heavy Bit](https://www.heavybit.com/library/podcasts/jamstack-radio/ep-71-open-source-firebase-alternative-with-paul-copplestone-of-supabase/)
- [Log Rocket](https://podrocket.logrocket.com/9)
- [FS Jam](https://fsjam.org/episodes/episode-33-supabase-with-paul-copplestone)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,12 +1,11 @@
---
id: functions
title: Edge Functions
description: 'Globally distributed TypeScript functions.'
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
export const meta = {
id: 'functions',
title: 'Edge Functions',
description: 'Globally distributed TypeScript functions.',
sidebar_label: 'Overview',
}
Edge Functions are server-side TypeScript functions, distributed globally at the edge—close to your users. They can be used for listening to webhooks or integrating your Supabase project with third-parties [like Stripe](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/stripe-webhooks).
@@ -275,3 +274,7 @@ Edge Functions supports `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, and `OPTIONS`.
- Edge Functions
- Local development - only one function at a time
- Serving of HTML content is not supported (`GET` requests that return `text/html` will be rewritten to `text/plain`).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: auth
title: Auth
description: Supabase Edge Functions and Auth.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Auth',
description: 'Supabase Edge Functions and Auth.',
}
Edge Functions work seamlessly with [Supabase Auth](/docs/guides/auth), allowing you to identify which user called your function.
@@ -56,3 +58,7 @@ serve(async (req: Request) => {
```
See the [example on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,10 @@
---
id: cicd-workflow
title: CI / CD Workflow
description: How to deploy Supabase Edge Functions with a CI / CD pipeline.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'cicd-workflow',
title: 'CI / CD Workflow',
description: 'How to deploy Supabase Edge Functions with a CI / CD pipeline.',
}
As described in the Supabase CLI [Environments Guide](/docs/guides/cli/managing-environments), you can use the [`setup-cli` GitHub Action](https://github.com/marketplace/actions/supabase-cli-action) to run Supabase CLI commands in your GitHub Actions, for example to deploy a Supabase Edge Function:
@@ -34,3 +36,7 @@ jobs:
```
See the [example on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/.github/workflows/deploy.yaml).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -0,0 +1,17 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'examples',
title: 'Examples',
description: 'Useful Supabase Edge Functions Examples',
}
You can find a list of useful [Edge Function Examples](https://github.com/supabase/supabase/tree/master/examples/edge-functions) in our GitHub repository.
<div className="container" style={{ padding: 0 }}>
<FunctionsExamples />
</div>
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: docker
title: Self-hosting with Docker
description: How to configure and deploy Supabase.
sidebar_label: Docker
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'docker',
title: 'Self-hosting with Docker',
description: 'How to configure and deploy Supabase.',
sidebar_label: 'Docker',
}
Docker is the easiest way to get started with self-hosted Supabase.
@@ -112,3 +114,7 @@ See the following guides to deploy Docker Compose setup using your preferred too
- Got a question? [Ask here](https://github.com/supabase/supabase/discussions).
- Sign in: [app.supabase.com](https://app.supabase.com)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: overview
title: Self Hosting
sidebar_label: Overview
description: Getting started with Self Hosting.
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'overview',
title: 'Self Hosting',
sidebar_label: 'Overview',
description: 'Getting started with Self Hosting.',
}
There are several ways to use Supabase:
@@ -153,3 +155,7 @@ While Supabase officially supports Docker, we have several other deployment stra
- [supabase-kubernetes](https://github.com/supabase-community/supabase-kubernetes) (Unofficial)
- [supabase-terraform](https://github.com/supabase-community/supabase-terraform) (Unofficial)
- [supabase-traefik](https://github.com/supabase-community/supabase-traefik) (Unofficial)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,9 +1,11 @@
---
id: platform
title: Supabase Platform
description: Getting started with the Supabase Platform.
sidebar_label: Overview
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'platform',
title: 'Supabase Platform',
description: 'Getting started with the Supabase Platform.',
sidebar_label: 'Overview',
}
Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure.
@@ -29,12 +31,7 @@ Organizations are a way to group your projects. Each organization can be configu
You can invite your team members into your organizations to collaborate on projects.
<video width="99%" muted playsInline controls="true">
<source
src="/docs/videos/invite-team.mp4"
type="video/mp4"
muted
playsInline
/>
<source src="/docs/videos/invite-team.mp4" type="video/mp4" muted playsInline />
</video>
You can also assign roles to your team members with different access levels. The table below shows the corresponding permissions for each available role in the Dashboard.
@@ -83,3 +80,7 @@ If Supabase experiences outages, we keep you as informed as possible, as early a
- Slack Alerts: You can receive updates via the RSS feed, using Slack's [built-in RSS functionality](https://slack.com/help/articles/218688467-Add-RSS-feeds-to-Slack) <br />`/feed subscribe https://status.supabase.com/history.atom`
Make sure to review our [SLA](/docs/company/sla) for details on our commitment to Platform Stability.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,11 @@
---
id: appsmith
title: 'Appsmith'
description: 'Get started with Supabase and Appsmith, an open-source framework for building internal tools.'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'appsmith',
title: 'Appsmith',
description:
'Get started with Supabase and Appsmith, an open-source framework for building internal tools.',
}
This guide explains how to quickly build a Support Dashboard by connecting a Supabase back-end to an Appsmith front-end.
@@ -164,3 +167,7 @@ SELECT * FROM public."tickets";
- [Appsmith](https://www.appsmith.com/) official website.
- [Appsmith GitHub](https://github.com/appsmithorg).
- [Appsmith](https://docs.appsmith.com/) documentation.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,11 @@
---
id: auth0
title: 'Auth0'
description: 'Swap out Supabase authentication with Auth0. Let Auth0 handle tokens and signing users in and out, while Supabase enforces authorization policies with Row Level Security (RLS).'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth0',
title: 'Auth0',
description:
'Swap out Supabase authentication with Auth0. Let Auth0 handle tokens and signing users in and out, while Supabase enforces authorization policies with Row Level Security (RLS).',
}
This guide steps through building a Next.js application with Auth0 and Supabase. We configure Auth0 to handle authenticating users and managing tokens, while writing our authorization logic in Supabase - using Row Level Security policies.
@@ -461,3 +464,7 @@ Now when we refresh our application, we should finally see our list of `todos`!
- [Using Next.js and Auth0 with Supabase article](https://auth0.com/blog/using-nextjs-and-auth0-with-supabase/).
- [Auth0 community](https://community.auth0.com/).
- [Auth0 documentation](https://auth0.com/docs/).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

View File

@@ -1,8 +1,11 @@
---
id: authsignal
title: 'Authsignal'
description: 'Add an MFA step after sign-in. Use Supabase Auth to sign in with email and password and Authsignal to initiate an Authenticator App challenge.'
---
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'authsignal',
title: 'Authsignal',
description:
'Add an MFA step after sign-in. Use Supabase Auth to sign in with email and password and Authsignal to initiate an Authenticator App challenge.',
}
This guide shows how to integrate [Authsignal](https://www.authsignal.com/) with [Next.js](https://nextjs.org/) and [Supabase](https://supabase.com/) in order to add an MFA step after sign-in.
@@ -580,3 +583,7 @@ Then if you sign out, you'll be prompted to complete an MFA challenge when signi
- To learn more about Authsignal take a look at the [API Documentation](https://docs.authsignal.com/).
- You can customize the look and feel of the Authsignal Prebuilt MFA page [here](https://portal.authsignal.com/organisations/tenants/customizations).
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page

Some files were not shown because too many files have changed in this diff Show More