Merge branch 'master' into feat/improve-column-creating-experience

This commit is contained in:
Terry Sutton committed 2022-09-26 11:25:15 -02:30
commit bdda1e970e
2095 files changed
+470454 -211238

No files matched your search

+2
View File
@@ -1,2 +1,4 @@
/studio/ @supabase/frontend
/apps/www/ @supabase/frontend
/apps/reference/ @supabase/docs
/spec/ @supabase/docs
+3 -9
View File
@@ -4,12 +4,10 @@
name: Docs Compilation Check
on:
push:
branches: [master]
pull_request:
branches: [master]
paths:
- 'web/**'
- 'apps/reference/**'
jobs:
build:
@@ -37,12 +35,8 @@ jobs:
- name: Install Deps
run: npm ci
working-directory: ./web
- name: Pull Specs
run: make
working-directory: ./web/spec
working-directory: ./apps/reference
- name: Build
run: npm run build
working-directory: ./web
working-directory: ./apps/reference
+1 -1
View File
@@ -48,9 +48,9 @@ jobs:
- name: Run Test
run: npm run test
continue-on-error: true
- name: Stop infrastructure
if: always()
run: npm run docker:down
- name: Get Allure history
-35
View File
@@ -1,35 +0,0 @@
name: Publish to Docker Hub
on:
push:
branches:
- studio
paths:
- 'studio/**'
workflow_dispatch:
jobs:
publish:
name: Publish to Docker Hub
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
with:
platforms: amd64,arm64
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/build-push-action@v2
with:
context: studio
platforms: linux/amd64,linux/arm64
push: true
tags: supabase/studio:latest
target: production
+57
View File
@@ -0,0 +1,57 @@
name: Publish to Image Registry
on:
push:
tags:
- '*'
workflow_dispatch:
inputs:
version:
description: 'Image tag'
required: true
type: string
jobs:
publish:
runs-on: ubuntu-latest
steps:
- id: meta
uses: docker/metadata-action@v4
with:
images: |
supabase/studio
public.ecr.aws/t3w2s2c9/studio
flavor: |
latest=false
tags: |
type=ref,event=tag
type=raw,value=${{ inputs.version }},enable=${{ github.event_name != 'push' }}
- uses: docker/setup-qemu-action@v2
with:
platforms: amd64,arm64
- uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to ECR
uses: docker/login-action@v2
with:
registry: public.ecr.aws
username: ${{ secrets.PROD_ACCESS_KEY_ID }}
password: ${{ secrets.PROD_SECRET_ACCESS_KEY }}
- uses: docker/build-push-action@v3
with:
push: true
context: '{{defaultContext}}:studio'
target: production
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
node-version: [14.x]
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
+3 -3
View File
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
node-version: [14.x]
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
@@ -28,8 +28,8 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install deps
run: npm i
working-directory: ./studio
run: npm install
working-directory: ./
- name: Run tests
run: npm test
working-directory: ./studio
Executable
+1
View File
@@ -0,0 +1 @@
cookie
+62 -72
View File
@@ -1,64 +1,60 @@
# Developing Supabase
- [Development Setup](#development-setup)
- [Installing Dependencies](#installing-dependencies)
- [Forking Supabase on GitHub](#forking-supabase-on-github)
- [Building Supabase](#building-supabase)
- [Choosing Directory](#choosing-directory)
- [Start a Development Server](#start-a-development-server)
- [Supabase Website Development Server](#supabase-website-development-server)
- [Supabase Docs Development Server](#supabase-docs-development-server)
- [Supabase Studio Development Server](#supabase-studio-development-server)
1. [Development setup](#development-setup)
- [Install dependencies](#install-dependencies)
- [Fork the repository](#fork-the-repository)
1. [Build Supabase](#build-supabase)
- [Choose a directory](#choose-a-directory)
1. [Start a development server](#start-a-development-server)
- [Supabase Website](#supabase-website)
- [Supabase Docs](#supabase-docs)
- [Supabase Studio](#supabase-studio)
1. [Create a pull request](#create-a-pull-request)
- [Common tasks](#common-tasks)
- [Add a redirect](#add-a-redirect)
- [Monorepo](#monorepo)
- [Getting started](#getting-started)
- [Shared components](#shared-components)
- [Installing packages](#installing-packages)
- [Development](#development)
- [Common Tasks](#common-tasks)
- [Adding redirects](#adding-redirects)
- [Finally](#finally)
- [Community Channels](#community-channels)
- [Community channels](#community-channels)
## Development Setup
## Development setup
First off, thanks for your interest in Supabase and for wanting to contribute! before you begin, read the
Thanks for your interest in Supabase and for wanting to contribute! Before you begin, read the
[code of conduct](https://github.com/supabase/.github/blob/main/CODE_OF_CONDUCT.md) and check out the
[existing issues](https://github.com/supabase/supabase/issues).
This document describes how to set up your development environment to build and test Supabase.
### Installing Dependencies
### Install dependencies
Before you can build Supabase, you must install and configure the following dependencies on your
machine:
You need to install and configure the following dependencies on your machine to build Supabase:
- [Git](http://git-scm.com/)
- [Node.js v16.x (LTS)](http://nodejs.org)
- [npm](https://www.npmjs.com/) version 7+ or [Yarn](https://yarnpkg.com/)
- [npm](https://www.npmjs.com/) version 7+.
### Fork the repository
### Forking Supabase on GitHub
To contribute code to Supabase, you must fork the [Supabase Repository](https://github.com/supabase/supabase).
To contribute code to Supabase, you must fork the [Supabase Repository](https://github.com/supabase/supabase). After you fork the repository, you may now begin editing the source code.
## Build Supabase
## Building Supabase
To build Supabase, you clone the source code repository:
2. Clone your GitHub forked repository:
1. Clone your GitHub forked repository:
```sh
git clone https://github.com/<github_username>/supabase.git
```
3. Go to the Supabase directory:
1. Go to the Supabase directory:
```sh
cd supabase
```
### Choosing Directory
### Choose a directory
Before you start a development server, you must choose if you want to work on the [Supabase Website](https://supabase.com), [Supabase Docs](https://supabase.com/docs), or [Supabase Studio](https://app.supabase.com).
Choose if you want to work on the [Supabase Website](https://supabase.com), [Supabase Docs](https://supabase.com/docs), or [Supabase Studio](https://app.supabase.com).
1. Go to the [Supabase Website](https://supabase.com) directory
@@ -69,7 +65,7 @@ Before you start a development server, you must choose if you want to work on th
Go to the [Supabase Docs](https://supabase.com/docs) directory
```sh
cd web
cd apps/reference
```
Go to the [Supabase Studio](https://app.supabase.com) directory
@@ -78,7 +74,7 @@ Before you start a development server, you must choose if you want to work on th
cd studio
```
2. Install npm dependencies:
1. Install npm/yarn dependencies:
npm
@@ -92,19 +88,19 @@ Before you start a development server, you must choose if you want to work on th
yarn install
```
## Start a Development Server
## Start a development server
To debug code, and to see changes in real time, it is often useful to have a local HTTP server. Click one of the three links below to choose which development server you want to start.
To debug code and to see your changes in real time, it is often useful to have a local HTTP server. Click one of the three links below to choose which development server you want to start.
- [Supabase Website](#Supabase-Website-Development-Server)
- [Supabase Docs](#Supabase-Docs-Development-Server)
- [Supabase Studio](#Supabase-Studio-Development-Server)
- [Supabase Website](#supabase-website)
- [Supabase Docs](#supabase-docs)
- [Supabase Studio](#supabase-studio)
### Supabase Website Development Server
### Supabase Website
The website is moving to a new monorepo setup. See the [Monorepo](#monorepo) section below.
### Supabase Docs Development Server
### Supabase Docs
1. Build development server
@@ -120,7 +116,7 @@ The website is moving to a new monorepo setup. See the [Monorepo](#monorepo) sec
yarn build
```
2. Start development server
1. Start development server
npm
@@ -134,13 +130,9 @@ The website is moving to a new monorepo setup. See the [Monorepo](#monorepo) sec
yarn start
```
3. To access the local server, enter the following URL into your web browser:
1. Access the local server in your web browser at http://localhost:3010/docs.
```sh
http://localhost:3005/docs
```
### Supabase Studio Development Server
### Supabase Studio
1. Start development server
@@ -156,13 +148,22 @@ The website is moving to a new monorepo setup. See the [Monorepo](#monorepo) sec
yarn dev
```
2. To access the local server, enter the following URL into your web browser:
1. Access the local server in your web browser at http://localhost:8082/.
See the [Supabase Studio readme](./studio/README.md) for more information.
```sh
http://localhost:8082/
```
## Create a pull request
For more information on Supabase Studio, see the [Supabase Studio readme](./studio/README.md).
After making your changes, open a pull request (PR). Once you submit your pull request, others from the Supabase team/community will review it with you.
Did you have an issue, like a merge conflict, or don't know how to open a pull request? Check out [GitHub's pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests) tutorial on how to resolve merge conflicts and other issues. Once your PR has been merged, you will be proudly listed as a contributor in the [contributor chart](https://github.com/supabase/supabase/graphs/contributors).
---
## Common tasks
### Add a redirect
Create a new entry in the [`next.config.js`](https://github.com/supabase/supabase/blob/master/apps/www/next.config.js) file in our main site.
## Monorepo
@@ -179,14 +180,12 @@ npm run dev # start all the applications
Then edit and visit any of the following sites:
- `/apps/www`: http://localhost:3000
- The main website.
- `/apps/temp-docs`: http://localhost:3001
- We are migrating the docs to a Next.js application.
- `/apps/temp-community-forum`: http://localhost:3002
- pulls all our github discussions into a nextjs site. Temporary/POC
- `/apps/temp-community-tutorials`: http://localhost:3003
- pulls all our DEV articles (which community members can write) into a nextjs site. Temporary/POC
Site | Directory | Description | Local development server
---- | --------- | ----------- | ------------------------
[supabase.com](https://supabase.com) | `/apps/www` | The main website | http://localhost:3000
[supabase.com/docs](https://supabase.com/docs) | `apps/reference` | Guides and Reference documentaion | http://localhost:3010/docs
[POC] Community forum | `/apps/temp-community-forum` | GitHub Discussions in a Next.js site | http://localhost:3002
[POC] DEV articles site | `/apps/temp-community-tutorials` | A Next.js site for our DEV articles (which community members can write) | http://localhost:3003
### Shared components
@@ -194,6 +193,7 @@ The monorepo has a set of shared components under `/packages`:
- `/packages/common`: Common React code, shared between all sites.
- `/packages/config`: All shared config
- `/packages/spec`: Generates documentation using spec files.
- `/packages/tsconfig`: Shared Typescript settings
### Installing packages
@@ -213,18 +213,8 @@ You do not need to install `devDependencies` in each workspace. These can all be
`npm run dev`
## Common Tasks
---
### Adding Redirects
## Community channels
To add a redirect, simple create a new entry in the [`next.config.js`](https://github.com/supabase/supabase/blob/master/apps/www/next.config.js) file in our main site.
## Finally
After making your changes to the file(s) you'd like to update, it's time to open a pull request. Once you submit your pull request, others from the Supabase team/community will review it with you.
Did you have an issue, like a merge conflict, or don't know how to open a pull request? Check out [GitHub's pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests) tutorial on how to resolve merge conflicts and other issues. Once your PR has been merged, you will be proudly listed as a contributor in the [contributor chart](https://github.com/supabase/supabase/graphs/contributors)
## Community Channels
Stuck somewhere? Have any questions? please join the [Discord Community Server](https://discord.supabase.com/) or the [Github Discussions](https://github.com/supabase/supabase/discussions). We are here to help!
Stuck somewhere? Have any questions? Join the [Discord Community Server](https://discord.supabase.com/) or the [Github Discussions](https://github.com/supabase/supabase/discussions). We are here to help!
+21 -8
View File
@@ -1,6 +1,6 @@
<p align="center">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/apps/www/public/images/supabase-logo-wordmark--light.svg?sanitize=true#gh-light-mode-only">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/apps/www/public/images/supabase-logo-wordmark--dark.svg?sanitize=true#gh-dark-mode-only">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg#gh-light-mode-only">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg#gh-dark-mode-only">
</p>
---
@@ -45,7 +45,7 @@ To see how to Contribute, visit [Getting Started](./DEVELOPERS.md)
We are currently in Public Beta. Watch "releases" of this repo to get notified of major updates.
<kbd><img src="https://gitcdn.link/repo/supabase/supabase/master/web/static/watch-repo.gif" alt="Watch this repo"/></kbd>
<kbd><img src="https://raw.githubusercontent.com/supabase/supabase/d5f7f413ab356dc1a92075cb3cee4e40a957d5b1/web/static/watch-repo.gif" alt="Watch this repo"/></kbd>
---
@@ -58,7 +58,7 @@ Supabase is a combination of open source tools. We’re building the features of
Supabase is a [hosted platform](https://app.supabase.com). You can sign up and start using Supabase without installing anything.
You can also [self-host](https://supabase.com/docs/guides/hosting/overview) and [develop locally](https://supabase.com/docs/guides/local-development).
![Architecture](https://supabase.com/docs/assets/images/supabase-architecture-9050a7317e9ec7efb7807f5194122e48.png)
![Architecture](https://user-images.githubusercontent.com/70828596/187547862-ffa9d058-0c3a-4851-a3e7-92ccfca4b596.png)
- [PostgreSQL](https://www.postgresql.org/) is an object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.
- [Realtime](https://github.com/supabase/realtime) is an Elixir server that allows you to listen to PostgreSQL inserts, updates, and deletes using websockets. Realtime polls Postgres' built-in replication functionality for database changes, converts changes to JSON, then broadcasts the JSON over websockets to authorized clients.
@@ -76,7 +76,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<tr>
<th>Language</th>
<th>Client</th>
<th colspan="4">Feature-Clients (bundled in Supabase client)</th>
<th colspan="5">Feature-Clients (bundled in Supabase client)</th>
</tr>
<tr>
<th></th>
@@ -85,6 +85,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<th><a href="https://github.com/supabase/gotrue" target="_blank" rel="noopener noreferrer">GoTrue</a></th>
<th><a href="https://github.com/supabase/realtime" target="_blank" rel="noopener noreferrer">Realtime</a></th>
<th><a href="https://github.com/supabase/storage-api" target="_blank" rel="noopener noreferrer">Storage</a></th>
<th>Functions</th>
</tr>
<!-- TEMPLATE FOR NEW ROW -->
<!-- START ROW
@@ -97,7 +98,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/storage-lang" target="_blank" rel="noopener noreferrer">storage-lang</a></td>
</tr>
END ROW -->
<th colspan="6">⚡️ Official ⚡️</th>
<th colspan="7">⚡️ Official ⚡️</th>
<tr>
<td>JavaScript (TypeScript)</td>
<td><a href="https://github.com/supabase/supabase-js" target="_blank" rel="noopener noreferrer">supabase-js</a></td>
@@ -105,8 +106,9 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase/gotrue-js" target="_blank" rel="noopener noreferrer">gotrue-js</a></td>
<td><a href="https://github.com/supabase/realtime-js" target="_blank" rel="noopener noreferrer">realtime-js</a></td>
<td><a href="https://github.com/supabase/storage-js" target="_blank" rel="noopener noreferrer">storage-js</a></td>
<td><a href="https://github.com/supabase/functions-js" target="_blank" rel="noopener noreferrer">functions-js</a></td>
</tr>
<th colspan="6">💚 Community 💚</th>
<th colspan="7">💚 Community 💚</th>
<tr>
<td>C#</td>
<td><a href="https://github.com/supabase-community/supabase-csharp" target="_blank" rel="noopener noreferrer">supabase-csharp</a></td>
@@ -114,6 +116,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/gotrue-csharp" target="_blank" rel="noopener noreferrer">gotrue-csharp</a></td>
<td><a href="https://github.com/supabase-community/realtime-csharp" target="_blank" rel="noopener noreferrer">realtime-csharp</a></td>
<td><a href="https://github.com/supabase-community/storage-csharp" target="_blank" rel="noopener noreferrer">storage-csharp</a></td>
<td><a href="https://github.com/supabase-community/functions-csharp" target="_blank" rel="noopener noreferrer">functions-csharp</a></td>
</tr>
<tr>
<td>Dart (Flutter)</td>
@@ -122,6 +125,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase/gotrue-dart" target="_blank" rel="noopener noreferrer">gotrue-dart</a></td>
<td><a href="https://github.com/supabase/realtime-dart" target="_blank" rel="noopener noreferrer">realtime-dart</a></td>
<td><a href="https://github.com/supabase/storage-dart" target="_blank" rel="noopener noreferrer">storage-dart</a></td>
<td><a href="https://github.com/supabase-community/functions-dart" target="_blank" rel="noopener noreferrer">functions-dart</a></td>
</tr>
<tr>
<td>Go</td>
@@ -129,6 +133,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/postgrest-go" target="_blank" rel="noopener noreferrer">postgrest-go</a></td>
<td>-</td>
<td>-</td>
<td><a href="https://github.com/supabase-community/storage-go" target="_blank" rel="noopener noreferrer">storage-go</a></td>
<td>-</td>
</tr>
<tr>
@@ -138,6 +143,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/gotrue-java" target="_blank" rel="noopener noreferrer">gotrue-java</a></td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Kotlin</td>
@@ -146,6 +152,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/gotrue-kt" target="_blank" rel="noopener noreferrer">gotrue-kt</a></td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Python</td>
@@ -153,7 +160,8 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/postgrest-py" target="_blank" rel="noopener noreferrer">postgrest-py</a></td>
<td><a href="https://github.com/supabase-community/gotrue-py" target="_blank" rel="noopener noreferrer">gotrue-py</a></td>
<td><a href="https://github.com/supabase-community/realtime-py" target="_blank" rel="noopener noreferrer">realtime-py</a></td>
<td>-</td>
<td><a href="https://github.com/supabase-community/storage-py" target="_blank" rel="noopener noreferrer">storage-py</a></td>
<td><a href="https://github.com/supabase-community/functions-py" target="_blank" rel="noopener noreferrer">functions-py</a></td>
</tr>
<tr>
<td>Ruby</td>
@@ -162,6 +170,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Rust</td>
@@ -170,6 +179,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Swift</td>
@@ -178,6 +188,7 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/gotrue-swift" target="_blank" rel="noopener noreferrer">gotrue-swift</a></td>
<td><a href="https://github.com/supabase-community/realtime-swift" target="_blank" rel="noopener noreferrer">realtime-swift</a></td>
<td><a href="https://github.com/supabase-community/storage-swift" target="_blank" rel="noopener noreferrer">storage-swift</a></td>
<td>-</td>
</tr>
</table>
@@ -189,10 +200,12 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
- [Arabic | العربية](/i18n/README.ar.md)
- [Albanian / Shqip](/i18n/README.sq.md)
- [Bangla / বাংলা](/i18n/README.bn.md)
- [Bulgarian / Български](/i18n/README.bg.md)
- [Catalan / Català](/i18n/README.ca.md)
- [Danish / Dansk](/i18n/README.da.md)
- [Dutch / Nederlands](/i18n/README.nl.md)
- [English](https://github.com/supabase/supabase)
- [Finnish / Suomalainen](/i18n/README.fi.md)
- [French / Français](/i18n/README.fr.md)
- [German / Deutsch](/i18n/README.de.md)
- [Greek / Ελληνικά](/i18n/README.gr.md)
+1 -1
View File
@@ -1 +1 @@
web/static/.well-known/security.txt
apps/reference/static/.well-known/security.txt
+1 -1
View File
@@ -1,3 +1,3 @@
Supabase is an open source Firebase alternative. We're backed by Y Combinator, Mozilla, Coatue, and a bunch of [amazing developers](https://supabase.com/blog/2021/03/25/angels-of-supabase).
Supabase is an open source Firebase alternative. We're backed by Y Combinator, Mozilla, Coatue, and a bunch of [amazing developers](https://supabase.com/blog/angels-of-supabase).
Supabase is a platform which makes it incredibly easy to build _and_ scale your projects.
+1 -3
View File
@@ -46,14 +46,12 @@ Help us maintain the community guidelines in our GitHub and Community-led commun
- Access to a Supabase Discord channel providing direct communication with the team, Discord badges, and elevated privileges.
- Special AMA sessions with members of the Supabase team.
- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.com/blog/2021/03/25/angels-of-supabase)), where you can learn from the best.
- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.com/blog/angels-of-supabase)), where you can learn from the best.
- We'll help you build your audience by promoting content via the Supabase social channels.
- Featured profile on Supabase website.
- Early access to new features (and the opportunity to provide feedback to the team!).
- Free credits that you can use for Squad efforts.
- Direct access to members of the Supabase team for questions, suggestions, etc.
- Help shape the future of the program.
- Invited to the [SupaSquad GitHub Org](https://github.com/supasquad) to collaborate with the other squad members.
- Exclusive Supabase Team swag drops usually exclusively reserved to the Supabase core team.
## How to join
+67 -16
View File
@@ -1753,6 +1753,49 @@
"@hapi/hoek": "^9.0.0"
}
},
"@jridgewell/gen-mapping": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
"requires": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.9"
}
},
"@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
},
"@jridgewell/set-array": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
},
"@jridgewell/source-map": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
"requires": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
}
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"@kiwicopple/prism-react-renderer": {
"version": "git+ssh://git@github.com/kiwicopple/prism-react-renderer.git#4a09100a587bce2d94d7ac8ed3564a61c6e70781",
"from": "@kiwicopple/prism-react-renderer@github:kiwicopple/prism-react-renderer",
@@ -12865,9 +12908,9 @@
"integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="
},
"terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
"integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
@@ -12902,6 +12945,11 @@
"webpack-sources": "^1.4.3"
},
"dependencies": {
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -12996,21 +13044,24 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"terser": {
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.3.8.tgz",
"integrity": "sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ==",
"source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"terser": {
"version": "5.14.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
"requires": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
"commander": "^2.20.0",
"source-map": "~0.7.2",
"source-map-support": "~0.5.19"
},
"dependencies": {
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
}
"source-map-support": "~0.5.20"
}
}
}
+6 -6
View File
@@ -1,5 +1,5 @@
/*
Font import
/*
Font import
*/
@import url('https://rsms.me/inter/inter.css');
@@ -30,7 +30,7 @@
:root[data-theme='dark'] {
/* See theme-specific "--custom" vars below */
/*
/*
Customization here for both Light and Dark themes
*/
--custom-font-base: 'Inter', BlinkMacSystemFont, -apple-system, 'Segoe UI', 'Roboto', 'Oxygen',
@@ -71,7 +71,7 @@
--custom-shadow-tl: 0 12px 28px 0 rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
--custom-shadow-xl: 0 30px 60px 0 rgba(0, 0, 0, 0.1);
/*
/*
Infirma overrides with customization
*/
/* Colors */
@@ -542,8 +542,8 @@ a.card:hover {
line-height: calc(var(--ifm-spacing-vertical) * 1);
}
/*
Link chevrons
/*
Link chevrons
*/
.menu .menu__link.menu__link--sublist::after {
background-image: url('data:image/svg+xml;utf8,<svg alt="Arrow" xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 38 38"><path fill="inherit" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path></svg>');
+22
View File
@@ -0,0 +1,22 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*/generated
+20
View File
@@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+45
View File
@@ -0,0 +1,45 @@
# Reference Docs
Supabase Reference Docs
## Maintainers
If you are a maintainer of any tools in the Supabase ecosystem, you can use this site to provide documentation for the tools & libraries that you maintain.
## Types of docs
There are many types of docs:
1. Guides: teach developers how to use a product. "I have XX problem, how do I solve it?"
2. Tutorials: walk-throughs, have a large outcome. "Build a React application with Supabase".
3. Explanations: teach developers about a broad topic. "What is a database?"
4. Reference: technical descriptions of tools and how to use them. "What errors does the API return?"
In these docs, you should focus only on the fourth type: "Reference Docs".
## Versioning
All tools have versioned docs, which are kept in separate folders. For example, the CLI has the following folders and files:
- `cli`: the "next" release.
- `cli_spec`: contains the DocSpec for the "next" release (see below).
- `cli_versioned_docs`: a version of the documentation for every release (including the most current version).
- `cli_versioned_sidebars`: a version of the sidebar for every release (including the most current version).
When you release a new version of a tool, you should also release a new version of the docs. You can do this via the command line. For example, if you just released the CLI version `1.0.1`:
```
npm run cli:version 1.0.1
```
## DocSpec
We use documentation specifications which can be used to generate human-readable docs.
- OpenAPI: for documenting API endpoints.
- SDKSpec (custom to Supabase): for SDKs and client libraries.
- ConfigSpec (custom to Supabase): for configuration options.
- CLISpec (custom to Supabase): for CLI commands and usage.
The benefit of using custom specifications is that we can generate many other types from a strict schema (eg, HTML and manpages).
It also means that we can switch any documentation system we want. On this site we use Docusaurus, but in Supabase's official website we use a custom React site and expose only a subset of the available API for each tool.
+37
View File
@@ -0,0 +1,37 @@
---
slug: /
sidebar_position: 1
sidebar_label: Supabase API
---
# Supabase API
The Supabase API allows you to manage your projects programmatically.
## Status
The Supabase API is in `beta`. It is usable in it's current state, but it's likely that there will be breaking changes.
## Authentication
All API requests require a Supabase Personal token to be included in the Authorization header: `Authorization Bearer <supabase_personal_token`.
To generate or manage your API token, visit your [account](https://app.supabase.com/account/tokens) page.
Your API tokens carry the same privileges as your user account, so be sure to keep it secret.
```bash
$ curl https://api.supabase.com/v1/projects \
-H "Authorization: Bearer sbp_bdd0••••••••••••••••••••••••••••••••4f23"
```
All API requests must be authenticated and made over HTTPS.
## Rate limits
The API is currently subject to our fair-use policy. In the future, are likely to introduce rate limits.
All resources created via the API are subject to the pricing detailed on our [Pricing](https://supabase.com/pricing) pages.
## Additional links
- [OpenAPI Docs](https://api.supabase.com/api/v1)
- [OpenAPI Spec](https://api.supabase.com/api/v1-json)
- Reporting bugs and issues: [github.com/supabase/supabase](https://github.com/supabase/supabase)
+12
View File
@@ -0,0 +1,12 @@
---
id: release-notes
---
# Release Notes
## v1.0.0 {#1.0.0}
Adds the following routes:
- `/v1/organizations`: Manage Supabase organizations
- `/v1/projects`: Manage Supabase projects
File diff suppressed because it is too large. Load diff
File renamed without changes.
File renamed without changes.
+17
View File
@@ -0,0 +1,17 @@
---
slug: /
sidebar_label: Auth Helpers
---
# Auth Helpers
A collection of framework specific Auth utilities for working with Supabase.
## Status
The Auth Helpers are in `beta`. They are usable in their current state, but it's likely that there will be breaking changes.
## Additional Links
- [Source code](https://github.com/supabase/auth-helpers)
- [Known bugs and issues](https://github.com/supabase/auth-helpers/issues)
+315
View File
@@ -0,0 +1,315 @@
---
id: next-js
slug: next-js
sidebar_label: With Next.js
---
# Supabase Auth with Next.js
This submodule provides convenience helpers for implementing user authentication in Next.js applications.
## Installation
Using [npm](https://npmjs.org):
```sh
npm install @supabase/auth-helpers-nextjs
# Main components and hooks for React based frameworks (optional)
npm install @supabase/auth-helpers-react
```
Using [yarn](https://yarnpkg.com/):
```sh
yarn add @supabase/auth-helpers-nextjs
# Main components and hooks for React based frameworks (optional)
yarn add @supabase/auth-helpers-react
```
This library supports the following tooling versions:
- Node.js: `^10.13.0 || >=12.0.0`
- Next.js: `>=10`
## Getting Started
### Configuration
Set up the following env vars. For local development you can set them in a `.env.local` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/nextjs/.env.local.example).
```bash
# Find these in your Supabase project settings > API
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```
### Basic Setup
- Create an `auth` directory under the `/pages/api/` directory.
- Create a `[...supabase].js` file under the newly created `auth` directory.
The path to your dynamic API route file would be `/pages/api/auth/[...supabase].js`. Populate that file as follows:
```js
import { handleAuth } from '@supabase/auth-helpers-nextjs'
export default handleAuth({ logout: { returnTo: '/' } })
```
Executing `handleAuth()` creates the following route handlers under the hood that perform different parts of the authentication flow:
- `/api/auth/callback`: The `UserProvider` forwards the session details here every time `onAuthStateChange` fires on the client side. This is needed to set up the cookies for your application so that SSR works seamlessly.
- `/api/auth/user`: You can fetch user profile information in JSON format.
- `/api/auth/logout`: Your Next.js application logs out the user. You can optionally pass a `returnTo` parameter to return to a custom relative URL after logout, eg `/api/auth/logout?returnTo=/login`. This will overwrite the logout `returnTo` option specified `handleAuth()`
Wrap your `pages/_app.js` component with the `UserProvider` component:
```jsx
// pages/_app.js
import React from 'react'
import { UserProvider } from '@supabase/auth-helpers-react'
import { supabaseClient } from '@supabase/auth-helpers-nextjs'
export default function App({ Component, pageProps }) {
return (
<UserProvider supabaseClient={supabaseClient}>
<Component {...pageProps} />
</UserProvider>
)
}
```
You can now determine if a user is authenticated by checking that the `user` object returned by the `useUser()` hook is defined.
## Client-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work properly when fetching data client-side, you need to make sure to import the `{ supabaseClient }` from `# @supabase/auth-helpers-nextjs` and only run your query once the user is defined client-side in the `useUser()` hook:
```js
import { Auth } from '@supabase/ui'
import { useUser } from '@supabase/auth-helpers-react'
import { supabaseClient } from '@supabase/auth-helpers-nextjs'
import { useEffect, useState } from 'react'
const LoginPage = () => {
const { user, error } = useUser()
const [data, setData] = useState()
useEffect(() => {
async function loadData() {
const { data } = await supabaseClient.from('test').select('*')
setData(data)
}
// Only run query once user is logged in.
if (user) loadData()
}, [user])
if (!user)
return (
<>
{error && <p>{error.message}</p>}
<Auth
supabaseClient={supabaseClient}
providers={['google', 'github']}
socialLayout="horizontal"
socialButtonSize="xlarge"
/>
</>
)
return (
<>
<button onClick={() => supabaseClient.auth.signOut()}>Sign out</button>
<p>user:</p>
<pre>{JSON.stringify(user, null, 2)}</pre>
<p>client-side data fetching with RLS</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default LoginPage
```
### Server-side rendering (SSR) - withPageAuth
If you wrap your `getServerSideProps` with `withPageAuth` your props object will be augmented with the user object.
```js
// pages/profile.js
import { withPageAuth } from '@supabase/auth-helpers-nextjs'
export default function Profile({ user }) {
return <div>Hello {user.name}</div>
}
export const getServerSideProps = withPageAuth({ redirectTo: '/login' })
```
If there is no authenticated user, they will be redirect to your home page, unless you specify the `redirectTo` option.
You can pass in your own `getServerSideProps` method, the props returned from this will be merged with the
user props. You can also access the user session data by calling `getUser` inside of this method, eg:
```js
// pages/protected-page.js
import { withPageAuth, getUser } from '@supabase/auth-helpers-nextjs'
export default function ProtectedPage({ user, customProp }) {
return <div>Protected content</div>
}
export const getServerSideProps = withPageAuth({
redirectTo: '/foo',
async getServerSideProps(ctx) {
// Access the user object
const { user, accessToken } = await getUser(ctx)
return { props: { email: user?.email } }
},
})
```
### Server-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work in a server environment, you need to inject the request context into the supabase client:
```js
import {
User,
withPageAuth,
supabaseServerClient,
} from '@supabase/auth-helpers-nextjs'
export default function ProtectedPage({
user,
data,
}: {
user: User,
data: any,
}) {
return (
<>
<div>Protected content for {user.email}</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<pre>{JSON.stringify(user, null, 2)}</pre>
</>
)
}
export const getServerSideProps = withPageAuth({
redirectTo: '/',
async getServerSideProps(ctx) {
// Run queries with RLS on the server
const { data } = await supabaseServerClient(ctx).from('test').select('*')
return { props: { data } }
},
})
```
### Server-side data fetching to OAuth APIs using `provider_token`
When using third-party auth providers, sessions are initiated with an additional `provider_token` field which is persisted as an HTTPOnly cookie upon logging in to enabled usage on the server side. The `provider_token` can be used to make API requests to the OAuth provider's API endpoints on behalf of the logged-in user. In the following example, we fetch the user's full profile from the third-party API during SSR using their id and auth token:
```js
import { User, withPageAuth, getUser } from '@supabase/auth-helpers-nextjs'
interface Profile {
/* ... */
}
export default function ProtectedPage({
user,
data,
}: {
user: User,
profile: Profile,
}) {
return <div>Protected content</div>
}
export const getServerSideProps = withPageAuth({
redirectTo: '/',
async getServerSideProps(ctx) {
// Retrieve provider_token from cookies
const provider_token = ctx.req.cookies['sb-provider-token']
// Get logged in user's third-party id from metadata
const { user } = await getUser(ctx)
const userId = user?.user_metadata.provider_id
const profile: Profile = await (
await fetch(`https://api.example.com/users/${userId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${provider_token}`,
},
})
).json()
return { props: { profile } }
},
})
```
## Protecting API routes
Wrap an API Route to check that the user has a valid session. If they're not logged in the handler will return a
401 Unauthorized.
```js
// pages/api/protected-route.js
import {
withApiAuth,
supabaseServerClient,
} from '@supabase/auth-helpers-nextjs'
export default withApiAuth(async function ProtectedRoute(req, res) {
// Run queries with RLS on the server
const { data } = await supabaseServerClient({ req, res })
.from('test')
.select('*')
res.json(data)
})
```
If you visit `/api/protected-route` without a valid session cookie, you will get a 401 response.
## Protecting routes with [Nextjs Middleware](https://nextjs.org/docs/middleware)
As an alternative to protecting individual pages using `getServerSideProps` with `withPageAuth`, `withMiddlewareAuth` can be used from inside a `_middleware` file to protect an entire directory. In the following example, all requests to `/protected/*` will check whether a user is signed in, if successful the request will be forwarded to the destination route, otherwise the user will be redirected to `/login` (defaults to: `/`) with a 307 Temporary Redirect response status:
```ts
// pages/protected/_middleware.ts
import { withMiddlewareAuth } from '@supabase/auth-helpers-nextjs/middleware'
export const middleware = withMiddlewareAuth({ redirectTo: '/login' })
```
It is also possible to add finer granularity based on the user logged in. I.e. you can specify a promise to determine if a specific user has permission or not.
```ts
// pages/protected/_middleware.ts
import { withMiddlewareAuth } from '@supabase/auth-helpers-nextjs/dist/middleware'
export const middleware = withMiddlewareAuth({
redirectTo: '/login',
authGuard: {
isPermitted: async (user) => user.email?.endsWith('@example.com') ?? false,
redirectTo: '/insufficient-permissions',
},
})
```
## Migrating from @supabase/supabase-auth-helpers to @supabase/auth-helpers
This is a step by step guide on migrating away from the `@supabase/supabase-auth-helpers` to the newly released `@supabase/auth-helpers`.
1. Install `@supabase/supabase-js`, `@supabase/auth-helpers-nextjs` and `@supabase/auth-helpers-react` libraries from npm.
2. Replace all imports of `@supabase/supabase-auth-helpers/nextjs` in your project with `@supabase/auth-helpers-nextjs`.
3. Replace all imports of `@supabase/supabase-auth-helpers/react` in your project with `@supabase/auth-helpers-react`.
4. Replace all instances of `withAuthRequired` in any of your NextJS pages with `withPageAuth`.
5. Replace all instances of `withAuthRequired` in any of your NextJS API endpoints with `withApiAuth`.
6. Uninstall `@supabase/supabase-auth-helpers`.
+303
View File
@@ -0,0 +1,303 @@
---
id: sveltekit
slug: sveltekit
sidebar_label: With SvelteKit
---
# Supabase Auth with SvelteKit
This submodule provides convenience helpers for implementing user authentication in [SvelteKit](https://kit.svelte.dev/) applications.
## Installation
Using [npm](https://npmjs.org):
```sh
npm install @supabase/auth-helpers-sveltekit
# Main component for Svelte based frameworks (optional but recommended)
npm install @supabase/auth-helpers-svelte
```
Using [yarn](https://yarnpkg.com/):
```sh
yarn add @supabase/auth-helpers-sveltekit
# Main component for Svelte based frameworks (optional but recommended)
yarn add @supabase/auth-helpers-svelte
```
This library supports the following tooling versions:
- Node.js: `^16.15.0`
## Getting Started
### Configuration
Set up the fillowing env vars. For local development you can set them in a `.env` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/sveltekit/.env.example).
```bash
# Find these in your Supabase project settings > API
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
```
### SupabaseClient and SupaAuthHelper component setup
We will start off by creating a `db.ts` file inside of our `src/lib` directory. Now lets instantiate our `supabaseClient` by using our `createSupabaseClient` function from the `@supabase/auth-helpers-sveltekit` library.
```ts
// src/lib/db.ts
import { createSupabaseClient } from '@supabase/auth-helpers-sveltekit'
const { supabaseClient } = createSupabaseClient(
import.meta.env.VITE_SUPABASE_URL as string,
import.meta.env.VITE_SUPABASE_ANON_KEY as string
)
export { supabaseClient }
```
Edit your `__layout.svelte` file and add import the `SupaAuthHelper` component, the `supabaseClient` we just instantiated and the `session` store.
```html
// src/routes/__layout.svelte
<script>
import { session } from '$app/stores'
import { supabaseClient } from '$lib/db'
import { SupaAuthHelper } from '@supabase/auth-helpers-svelte'
</script>
<SupaAuthHelper {supabaseClient} {session}>
<slot />
</SupaAuthHelper>
```
### Hooks setup
Our `hooks.ts` file is where the heavy lifting of this library happens, we need to import our function to handle the sign in, signing out and cookie creation phase. we can import all the hooks using `handleAuth` function and destructure its returned data.
```ts
// src/hooks.ts
import { handleAuth } from '@supabase/auth-helpers-sveltekit'
import type { GetSession, Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
export const handle: Handle = sequence(...handleAuth())
export const getSession: GetSession = async (event) => {
const { user, accessToken, error } = event.locals
return {
user,
accessToken,
error,
}
}
```
These will create the handlers under the hood that perform different parts of the authentication flow:
- `/api/auth/callback`: The `UserHelper` forwards the session details here every time `onAuthStateChange` fires on the client side. This is needed to set up the cookies for your application so that SSR works seamlessly.
- `/api/auth/user`: You can fetch user profile information in JSON format.
- `/api/auth/logout`: You can logout the user.
### Typings
In order to get the most out of TypeScript and its intellisense, you should import our types into the `app.d.ts` type definition file that comes with your SvelteKit project.
```ts
// src/app.d.ts
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare namespace App {
interface UserSession {
user: import('@supabase/supabase-js').User
accessToken?: string
}
interface Locals extends UserSession {
error: import('@supabase/supabase-js').ApiError
}
interface Session extends UserSession {} // interface Platform {} // interface Stuff {}
}
```
### Signing out
This library has provided a dedicated endpoint for you to use to sign a user out. This endpoint will sign the user out of the Gotrue server, clear the cookies that were set when the user logged in and redirect the user to a configurable path.
The logout handler endpoint is `/api/auth/logout`, this will take a `GET` request which means it can be used as the href for a normal `a` tag in your html.
```html
<a href="/api/auth/logout">Sign out</a>
```
### Logout handler configuration
In your `src/hooks.ts` file the logout handler is already setup and you can configure the redirect path from here.
> By default the redirect path after logging out will be `/`.
```ts
export const handle = sequence(
...handleAuth({
logout: { returnTo: '/auth/signin' },
})
)
```
### Basic Setup
You can now determine if a user is authenticated on the client-side by checking that the `user` object returned by the `$session` store is defined.
```html
// example
<script>
import { session } from '$app/stores'
</script>
{#if !$session.user}
<h1>I am not logged in</h1>
{:else}
<h1>Welcome {$session.user.email}</h1>
<p>I am logged in!</p>
{/if}
```
## Client-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work properly when fetching data client-side, you need to make sure to import the `{ supabaseClient }` from `@supabase/auth-helpers-sveltekit` and only run your query once the user is defined client-side in the `$session`:
```html
<script>
import Auth from 'supabase-ui-svelte';
import { error, isLoading } from '@supabase/auth-helpers-svelte';
import { supabaseClient } from '$lib/db';
import { session } from '$app/stores';
let loadedData = [];
async function loadData() {
const { data } = await supabaseClient.from('test').select('*').single();
loadedData = data
}
$: {
if ($session.user && $session.user.id) {
loadData();
}
}
</script>
{#if !$session.user}
{#if $error}
<p>{$error.message}</p>
{/if}
<h1>{$isLoading ? `Loading...` : `Loaded!`}</h1>
<Auth
supabaseClient={supabaseClient}
providers={['google', 'github']}
/>
{:else}
<a href=="/api/auth/logout">Sign out</a>
<p>user:</p>
<pre>{JSON.stringify($session.user, null, 2)}</pre>
<p>client-side data fetching with RLS</p>
<pre>{JSON.stringify(loadedData, null, 2)}</pre>
{/if}
```
### Server-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work in a server environment, you need to inject the request context into the supabase client:
```html
<!-- src/routes/profile.svelte -->
<script>
export let user
export let data
</script>
<div>Protected content for {user.email}</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<pre>{JSON.stringify(user, null, 2)}</pre>
```
```ts
// src/routes/profile.ts
import {
supabaseServerClient,
withApiAuth,
} from '@supabase/auth-helpers-sveltekit'
import type { RequestHandler } from './__types/profile'
interface TestTable {
id: string
created_at: string
}
interface GetOutput {
user: User
data: TestTable[]
}
export const GET: RequestHandler<GetOutput> = async ({ locals }) =>
withApiAuth(
{
redirectTo: '/',
user: locals.user,
},
async () => {
const { data } = await supabaseServerClient(session.accessToken)
.from<TestTable>('test')
.select('*')
return {
body: {
user: locals.user,
data,
},
}
}
)
```
## Protecting API routes
Wrap an API Route to check that the user has a valid session. If they're not logged in the handler will return a
303 and redirect header.
```ts
// src/routes/api/protected-route.ts
import {
supabaseServerClient,
withApiAuth,
} from '@supabase/auth-helpers-sveltekit'
import type { RequestHandler } from './__types/protected-route'
interface TestTable {
id: string
created_at: string
}
interface GetOutput {
data: TestTable[]
}
export const GET: RequestHandler<GetOutput> = async ({ locals, request }) =>
withApiAuth({ user: locals.user }, async () => {
// Run queries with RLS on the server
const { data } = await supabaseServerClient(request)
.from('test')
.select('*')
return {
status: 200,
body: { data },
}
})
```
If you visit `/api/protected-route` without a valid session cookie, you will get a 303 response.
File renamed without changes.
+26
View File
@@ -0,0 +1,26 @@
---
id: intro
slug: /
sidebar_position: 1
sidebar_label: Supabase CLI
hide_table_of_contents: true
---
# Supabase CLI
The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform.
The CLI is still under development, but it contains all the functionality for working with your Supabase projects and the Supabase Platform.
- Run Supabase locally: [`supabase start`](https://supabase.com/docs/reference/cli/usage#supabase-start)
- Manage database migrations: [`supabase migration`](https://supabase.com/docs/reference/cli/usage#supabase-migration)
- CI/CD for releasing to production: [`supabase db push`](https://supabase.com/docs/reference/cli/usage#supabase-db-push)
- Manage your Supabase projects: [`supabase projects`](https://supabase.com/docs/reference/cli/usage#supabase-projects)
- Generate types directly from your database schema: [`supabase gen types`](https://supabase.com/docs/reference/cli/usage#supabase-gen)
## Additional Links
- [Install the Supabase CLI](/docs/guides/cli)
- [Source code](https://github.com/supabase/cli)
- [Known bugs and issues](https://github.com/supabase/cli/issues)
- [Supabase CLI v1 and Admin API Beta](https://supabase.com/blog/supabase-cli-v1-and-admin-api-beta)
- [The CLI team announcing CLI V1 and Admin API Beta - Video](https://www.youtube.com/watch?v=OpPOaJI_Z28)
+7
View File
@@ -0,0 +1,7 @@
---
id: release-notes
---
# Release Notes
All release notes can be found in the [GitHub Releases page](https://github.com/supabase/cli/releases).
+1
View File
@@ -0,0 +1 @@
[]
+35
View File
@@ -0,0 +1,35 @@
---
id: config
slug: /config
title: Configuration
toc_max_heading_level: 3
---
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY -->
A `config.toml` file is generated after running `supabase init`.
This file is located in the `supabase` folder under `supabase/config.toml`.
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY -->
## General {#general}
### `project_id` {#project_id}
A string used to distinguish different Supabase projects on the same host. Defaults to the working directory name when running `supabase init`.
<ul>
<li>Required: <code>true</code></li>
<li>Default: <code>None</code></li>
</ul>
<br />
+22
View File
@@ -0,0 +1,22 @@
---
slug: /
sidebar_position: 1
sidebar_label: Auth Server
---
# Supabase Auth Server
The Supabase Auth Server (GoTrue) is a JSON Web Token (JWT)-based API for managing users and issuing access tokens.
GoTrue is an open-source API written in Golang, that acts as a self-standing API service for handling user registration and authentication for JAM projects. It's based on OAuth2 and JWT and handles user signup, authentication, and custom user data.
## Client libraries
- [JavaScript](https://github.com/supabase/gotrue-js)
- [Dart](https://github.com/supabase/gotrue-dart)
## Additional Links
- [Source Code](https://github.com/supabase/gotrue)
- [Known bugs and issues](https://github.com/supabase/gotrue/issues)
- [Auth Guides](https://supabase.com/docs/guides/auth)
+7
View File
@@ -0,0 +1,7 @@
---
id: release-notes
---
# Release Notes
All release notes can be found in the [GitHub Releases](https://github.com/supabase/gotrue/releases) page.
Whitespace-only changes.
Whitespace-only changes.
+1
View File
@@ -0,0 +1 @@
[]
Whitespace-only changes.
+28
View File
@@ -0,0 +1,28 @@
---
slug: /
sidebar_position: 1
sidebar_label: Storage Server
---
# Supabase Storage Server
An S3 compatible object storage service that integrates with Postgres.
- Uses Postgres as it's datastore for storing metadata
- Authorization rules are written as Postgres Row Level Security policies
- Integrates with S3 as the storage backend (with more in the pipeline!)
- Extremely lightweight and performant
Read [this post](https://supabase.com/blog/supabase-storage) on why we decided to build a new object storage service.
## Client libraries
- [JavaScript](https://github.com/supabase/storage-js)
- [Dart](https://github.com/supabase/storage-dart)
## Additional Links
- [Source Code](https://github.com/supabase/storage-api)
- [Known bugs and issues](https://github.com/supabase/storage-js/issues)
- [Storage Guides](https://supabase.com/docs/guides/storage)
- [OpenAPI Docs](https://supabase.github.io/storage-api/)
@@ -0,0 +1,7 @@
---
id: release-notes
---
# Release Notes
All release notes can be found in the [GitHub Releases](https://github.com/supabase/storage-api/releases) page.
Whitespace-only changes.
Whitespace-only changes.
+1
View File
@@ -0,0 +1 @@
[]
Whitespace-only changes.
@@ -0,0 +1,36 @@
---
id: initializing
title: 'Initializing'
slug: initializing
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
## Dart
You can initialize a new Supabase client using the `SupabaseClient()` method.
The Supabase client is your entrypoint to the rest of the Supabase functionality
and is the easiest way to interact with everything we offer within the Supabase ecosystem.
## Flutter
For `supabase_flutter`, you will be using the static `initialize()` method on `Supabase` class.
## Examples
### Dart `SupabaseClient()`
```dart
final supabase = SupabaseClient('https://xyzcompany.supabase.co', 'public-anon-key');
```
### Flutter `initialize()`
```dart title="main.dart"
Future<void> main() async {
await Supabase.initialize(url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key');
runApp(MyApp());
}
```
@@ -0,0 +1,31 @@
---
id: installing
title: 'Installing'
slug: installing
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
## Dart
Dart libraries are built and supported by the community.
```bash
dart pub add supabase
```
Find the source code on [GitHub](https://github.com/supabase/supabase-dart).
## Flutter
For Flutter project, you can use [supabase_flutter](https://github.com/supabase/supabase-flutter).
```bash
flutter pub add supabase_flutter
```
`supabase_flutter` plugin uses `supabase` plugin internally, and it adds some Flutter specific functionality such as handling deeplinks coming back from magic link verifications.
If you are creating a Flutter application, we recommend using `supabase_flutter` instead of `supabase`.
For the most part `supabase_flutter` shares the same API as `supabase` with few exceptions such as initialization or OAuth sign in.
+30
View File
@@ -0,0 +1,30 @@
---
id: intro
slug: /
sidebar_label: Supabase Dart Library
---
# Supabase Dart Library
:::note
You're viewing the Supabase docs for a developer preview version.
Refer to the `v0` docs for the previous release.
:::
This reference documents every object and method available in Supabase's isomorphic Dart library, `supabase-dart`.
You can use the `supabase-dart` library to:
- interact with your Postgres database
- listen to database changes
- invoke Deno Edge Functions
- build login and user management functionality
- manage large files
## Additional Links
- Source Code: [github.com/supabase/supabase-dart](https://github.com/supabase/supabase-dart)
- [Known bugs and issues](https://github.com/supabase/supabase-flutter/issues)
@@ -0,0 +1,22 @@
---
id: intro
slug: /
sidebar_label: Supabase Dart Library
---
# Supabase Dart Library
This reference documents every object and method available in Supabase's isomorphic Dart library, `supabase-dart`.
You can use the `supabase-dart` library to:
- interact with your Postgres database
- listen to database changes
- invoke Deno Edge Functions
- build login and user management functionality
- manage large files
## Additional Links
- Source Code: [github.com/supabase/supabase-dart](https://github.com/supabase/supabase-dart)
- [Known bugs and issues](https://github.com/supabase/supabase-dart/issues)
@@ -0,0 +1,120 @@
{
"sidebar": [
{
"type": "category",
"label": "Getting Started",
"items": ["intro", "generated/installing", "generated/initializing"],
"collapsed": true
},
{
"type": "category",
"label": "Auth",
"items": [
"generated/auth-signup",
"generated/auth-signin",
"generated/auth-signinwithprovider",
"generated/auth-signout",
"generated/auth-session",
"generated/auth-user",
"generated/auth-update",
"generated/auth-onauthstatechange",
"generated/reset-password-email"
],
"collapsed": true
},
{
"type": "category",
"label": "Functions",
"items": ["generated/invoke"],
"collapsed": true
},
{
"type": "category",
"label": "Database",
"items": [
"generated/select",
"generated/insert",
"generated/update",
"generated/upsert",
"generated/delete",
"generated/rpc"
],
"collapsed": true
},
{
"type": "category",
"label": "Realtime",
"items": [
"generated/subscribe",
"generated/removesubscription",
"generated/getsubscriptions",
"generated/stream"
],
"collapsed": true
},
{
"type": "category",
"label": "Storage",
"items": [
"generated/storage-createbucket",
"generated/storage-getbucket",
"generated/storage-listbuckets",
"generated/storage-updatebucket",
"generated/storage-deletebucket",
"generated/storage-emptybucket",
"generated/storage-from-upload",
"generated/storage-from-download",
"generated/storage-from-list",
"generated/storage-from-update",
"generated/storage-from-move",
"generated/storage-from-remove",
"generated/storage-from-createsignedurl",
"generated/storage-from-getpublicurl"
],
"collapsed": true
},
{
"type": "category",
"label": "Modifiers",
"items": [
"generated/using-modifiers",
"generated/limit",
"generated/order",
"generated/range",
"generated/single"
],
"collapsed": true
},
{
"type": "category",
"label": "Filters",
"items": [
"generated/using-filters",
"generated/or",
"generated/not",
"generated/match",
"generated/eq",
"generated/neq",
"generated/gt",
"generated/gte",
"generated/lt",
"generated/lte",
"generated/like",
"generated/ilike",
"generated/is_",
"generated/in_",
"generated/contains",
"generated/containedby",
"generated/rangelt",
"generated/rangegt",
"generated/rangegte",
"generated/rangelte",
"generated/rangeadjacent",
"generated/overlaps",
"generated/textsearch",
"generated/filter"
],
"collapsed": true
}
]
}
@@ -0,0 +1 @@
["v0"]
Whitespace-only changes.
@@ -0,0 +1,37 @@
---
id: installing
title: 'Installing'
slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
All JavaScript libraries are built directly by the Supabase team.
Other languages are built by the community and supported by Supabase.
## JavaScript
Via NPM
```bash
npm install @supabase/supabase-js
```
Via Yarn
```bash
yarn add @supabase/supabase-js
```
Find the source code on [GitHub](https://github.com/supabase/supabase-js).
Or via CDN
```js
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js"></script>
//or
<script src="https://unpkg.com/@supabase/supabase-js"></script>
```
+33
View File
@@ -0,0 +1,33 @@
---
slug: /
sidebar_position: 1
sidebar_label: Supabase JavaScript Library
hide_table_of_contents: true
---
# Supabase JavaScript Library
:::note
You're viewing the Supabase docs for the next version of our library which is not yet released.
Refer to the `v1` docs for a stable release.
:::
This reference documents every object and method available in Supabase's isomorphic JavaScript library, `supabase-js`.
You can use the `supabase-js` library to:
- interact with your Postgres database
- listen to database changes
- invoke Deno Edge Functions
- build login and user management functionality
- manage large files
## Additional Links
- Source Code: [github.com/supabase/supabase-js](https://github.com/supabase/supabase-js)
- TypeDoc: [supabase.github.io/supabase-js](https://supabase.github.io/supabase-js)
- NPM: [npmjs.com/package/@supabase/supabase-js](https://www.npmjs.com/package/@supabase/supabase-js)
- [Known bugs and issues](https://github.com/supabase/supabase-js/issues)
@@ -0,0 +1,212 @@
---
id: release-notes
---
# Release Notes
Supabase.js v2 release notes.
## 2.0.0 Release Candidate
Install the latest with `npm install @supabase/supabase-js@rc`.
### Explicit constructor options
All client specific options within the constructor are keyed to the library: [PR](https://github.com/supabase/supabase-js/pull/458):
```jsx
const supabase = createClient(apiURL, apiKey, {
db: {
schema: 'public',
},
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
realtime: {
channels,
endpoint,
},
global: {
fetch: customFetch,
headers: DEFAULT_HEADERS,
},
})
```
### Typescript support
The libraries now support typescript.
```ts
// v2 - definitions are injected in `createClient()`
import type { Database } from './DatabaseDefinitions'
const supabase = createClient<Database>(SUPABASE_URL, ANON_KEY)
const { data } = await supabase.from('messages').select().match({ id: 1 })
// v1 -- previously definitions were injected in the `from()` method
supabase.from<Definitions['Message']>('messages').select('*')
```
Types can be generated via the CLI:
```bash
supabase start
supabase gen types typescript --local > DatabaseDefinitions.ts
```
### Data operations return minimal
`.insert()` / `.upsert()` / `.update()` / `.delete()` don't return rows by default: [PR](https://github.com/supabase/postgrest-js/pull/276).
Previously, these methods return inserted/updated/deleted rows by default (which caused [some confusion](https://github.com/supabase/supabase/discussions/1548)), and you can opt to not return it by specifying `returning: 'minimal'`. Now the default behavior is to not return rows. To return inserted/updated/deleted rows, add a `.select()` call at the end, e.g.:
```sql
const { data, error } = await supabase
.from('my_table')
.delete()
.eq('id', 1)
.select()
```
### New ordering defaults
`.order()` now defaults to Postgres’s default: [PR](https://github.com/supabase/postgrest-js/pull/283).
Previously `nullsFirst` defaults to `false` , meaning `null`s are ordered last. This is bad for performance if e.g. the column uses an index with `NULLS FIRST` (which is the default direction for indexes).
### Cookies and localstorage namespace
Storage key name in the Auth library has changed to include project reference which means that existing websites that had their JWT expiry set to a longer time could find their users logged out with this upgrade.
```jsx
const defaultStorageKey = `sb-${
new URL(this.authUrl).hostname.split('.')[0]
}-auth-token`
```
### New Auth Types
Typescript typings have been reworked. `Session` interface now guarantees that it will always have an `access_token`, `refresh_token` and `user`
```jsx
interface Session {
provider_token?: string | null
access_token: string
expires_in?: number
expires_at?: number
refresh_token: string
token_type: string
user: User
}
```
### New Auth methods
We're removing the `signIn()` method in favor of more explicit function signatures:
`signInWithPassword()`, `signInWithPasswordless()`, and `signInWithOtp()`.
```ts
// v2
const { data } = await supabase.auth.signInWithPassword({
email: 'hello@example',
password: 'pass',
})
// v1
const { data } = await supabase.auth.signIn({
email: 'hello@example',
password: 'pass',
})
```
### New Realtime methods
There is a new `channel()` method in the Realtime library, which will be used for our Multiplayer updates.
```ts
supabaseClient
.channel('any_string_you_want')
.on('presence', { event: 'track' }, (payload) => {
console.log(payload)
})
.subscribe()
supabaseClient
.channel('any_string_you_want')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'movies',
},
(payload) => {
console.log(payload)
}
)
.subscribe()
```
We will deprecate the `.from().on().subscribe()` method previosuly used for listening to postgres changes.
### Deprecated setAuth()
Deprecated and removed `setAuth()` . To set a custom `access_token` jwt instead, pass the custom header into the `createClient()` method provided: ([PR](https://github.com/supabase/gotrue-js/pull/340))
### All changes
- `supabase-js`
- `shouldThrowOnError` has been removed until all the client libraries support this option ([PR](https://github.com/supabase/supabase-js/pull/490)).
- `postgrest-js`
- TypeScript typings have been reworked [PR](https://github.com/supabase/postgrest-js/pull/279)
- Use `undefined` instead of `null` for function params, types, etc. (https://github.com/supabase/postgrest-js/pull/278)
- Some features are now obsolete: (https://github.com/supabase/postgrest-js/pull/275)
- filter shorthands (e.g. `cs` vs. `contains`)
- `body` in response (vs. `data`)
- `upsert`ing through the `.insert()` method
- `auth` method on `PostgrestClient`
- client-level `throwOnError`
- `gotrue-js`
- `supabase-js` client allows passing a `storageKey` param which will allow the user to set the key used in local storage for storing the session. By default, this will be namespace-d with the supabase project ref. ([PR](https://github.com/supabase/supabase-js/pull/460))
- `signIn` method is now split into `signInWithPassword` , `signInWithPasswordless` , `signInWithOAuth` ([PR](https://github.com/supabase/gotrue-js/pull/304))
- Deprecated and removed `session()` , `user()` in favour of using `getSession()` instead. `getSession()` will always return a valid session if a user is already logged in, meaning no more random logouts. ([PR](https://github.com/supabase/gotrue-js/pull/299))
- Deprecated and removed setting for `multitab` support because `getSession()` and gotrue’s reuse interval setting takes care of session management across multiple tabs ([PR](https://github.com/supabase/gotrue-js/pull/366))
- No more throwing of random errors, gotrue-js v2 always returns a custom error type: ([PR](https://github.com/supabase/gotrue-js/pull/341))
- `AuthSessionMissingError`
- Indicates that a session is expected but missing
- `AuthNoCookieError`
- Indicates that a cookie is expected but missing
- `AuthInvalidCredentialsError`
- Indicates that the incorrect credentials were passed
- Renamed the `api` namespace to `admin` , the `admin` namespace will only contain methods that should only be used in a trusted server-side environment with the service role key
- Moved `resetPasswordForEmail` , `getUser` and `updateUser` to the `GoTrueClient` which means they will be accessible from the `supabase.auth` namespace in `supabase-js` instead of having to do `supabase.auth.api` to access them
- Removed `sendMobileOTP` , `sendMagicLinkEmail` in favor of `signInWithOtp`
- Removed `signInWithEmail`, `signInWithPhone` in favor of `signInWithPassword`
- Removed `signUpWithEmail` , `signUpWithPhone` in favor of `signUp`
- Replaced `update` with `updateUser`
- `storage-js`
- Return types are more strict. Functions types used to indicate that the data returned could be null even if there was no error. We now make use of union types which only mark the data as null if there is an error and vice versa. ([PR](https://github.com/supabase/storage-js/pull/60))
- The `upload` and `update` function returns the path of the object uploaded as the `path` parameter. Previously the returned value had the bucket name prepended to the path which made it harder to pass the value on to other storage-js methods since all methods take the bucket name and path separately. We also chose to call the returned value `path` instead of `Key` ([PR](https://github.com/supabase/storage-js/pull/75))
- `getPublicURL` only returns the public URL inside the data object. This keeps it consistent with our other methods of returning only within the data object. No error is returned since this method cannot does not throw an error ([PR](https://github.com/supabase/storage-js/pull/93))
- signed urls are returned as `signedUrl` instead of `signedURL` in both `createSignedUrl` and `createSignedUrls` ([PR](https://github.com/supabase/storage-js/pull/94))
- Encodes URLs returned by `createSignedUrl`, `createSignedUrls` and `getPublicUrl` ([PR](https://github.com/supabase/storage-js/pull/86))
- `createsignedUrl` used to return a url directly and and within the data object. This was inconsistent. Now we always return values only inside the data object across all methods. ([PR](https://www.notion.so/LW5-supabase-js-v2-7b0bfcdf571d4f20b9b7a9308883f24b))
- `createBucket` returns a data object instead of the name of the bucket directly. ([PR](https://github.com/supabase/storage-js/pull/89))
- Fixed types for metadata ([PR](https://github.com/supabase/storage-js/pull/90))
- Better error types make it easier to track down what went wrong quicker.
- `SupabaseStorageClient` is no longer exported. Use `StorageClient` instead. ([PR](https://github.com/supabase/storage-js/pull/92)).
- `realtime-js`
- `RealtimeSubscription` class no longer exists and replaced by `RealtimeChannel`.
- `RealtimeClient`'s `disconnect` method now returns type of `void` . It used to return type of `Promise<{ error: Error | null; data: boolean }`.
- Removed `removeAllSubscriptions` and `removeSubscription` methods from `SupabaseClient` class.
- Removed `SupabaseRealtimeClient` class.
- Removed `SupabaseQueryBuilder` class.
- Removed `SupabaseEventTypes` type.
- Thinking about renaming this to something like `RealtimePostgresChangeEvents` and moving it to `realtime-js` v2.
- Removed `.from(’table’).on(’INSERT’, () ⇒ {}).subscribe()` in favor of new Realtime client API.
- `functions-js`
- supabase-js v1 only threw an error if the fetch call itself threw an error (network errors, etc) and not if the function returned HTTP errors like 400s or 500s. We have changed this behaviour to return an error if your function throws an error.
- We have introduced new error types to distinguish between different kinds of errors. A `FunctionsHttpError` error is returned if your function throws an error, `FunctionsRelayError` if the Supabase Relay has an error processing your function and `FunctionsFetchError` if there is a network error in calling your function.
- The correct content-type headers are automatically attached when sending the request if you don’t pass in a `Content-Type` header and pass in an argument to your function. We automatically attach the content type for `Blob`, `ArrayBuffer`, `File`, `FormData` ,`String` . If it doesn’t match any of these we assume the payload is `json` , we serialise the payload as JSON and attach the content type as `application/json`.
- `responseType` does not need to be explicitly passed in. We parse the response based on the `Content-Type` response header sent by the function. We support parsing the responses as `text`, `json`, `blob`, `form-data` and are parsed as `text` by default.
@@ -0,0 +1,84 @@
---
id: typescript-support
---
# Typescript Support
`supabase-js` supports Typescript.
## Generating types
You can use our CLI to generate types:
```bash
supabase start
supabase gen types typescript --local > lib/database.types.ts
```
These types are generated directly from your database. Given a table `public.movies`, the definition will provide the following data:
```ts
interface Database {
public: {
Tables: {
movies: {
Row: {} // The data expected to be returned from a "select" statement.
Insert: {} // The data expected passed to an "insert" statement.
Update: {} // The data expected passed to an "update" statement.
}
}
}
}
```
There is a difference between `selects`, `inserts`, and `updates`, because often you will set default values in your database for specific columns.
With default values you do not need to send any data over the network, even if that column is a "required" field. Our type system is granular
enough to handle these situations.
## Injecting type definitions
You can enrich the supabase client with the types you generated with Supabase.
```ts
import { createClient } from '@supabase/supabase-js'
import { Database } from 'lib/database.types'
const supabase = createClient<Database>(
process.env.SUPABASE_URL,
process.env.SUPABASE_ANON_KEY
)
```
## Type hints
`supabase-js` always returns a `data` object (for success), and an `error` response (for unsuccessful requests).
This provides a simple interface to get the relevant types returned from any function:
```ts
export async function getMovies() {
return await supabase.from('movies').select(`id, title`)
}
type MoviesResponse = Awaited<ReturnType<typeof getMovies>>
export type MoviesResponseSuccess = MoviesResponse['data']
export type MoviesResponseError = MoviesResponse['error']
```
## Nested tables
For advanced queries such as nested tables, you may want to construct your own types.
```ts
import supabase from '~/lib/supabase'
import type { Database } from '~/lib/database.types'
async function getMovies() {
return await supabase.from('movies').select('id, title, actors(*)')
}
type actors = Database['public']['Tables']['actors']['Row']
type MoviesResponse = Awaited<ReturnType<typeof getMovies>>
type MoviesResponseSuccess = MoviesResponse['data'] & {
actors: actors[]
}
```
Whitespace-only changes.
@@ -0,0 +1,42 @@
---
id: generating-types
title: "Generating Types"
slug: generating-types
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1_legacy.yml
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript [through third-party tools](/docs/guides/api/generating-types).
## Usage with TypeScript
`supabase-js` ships with type definitions for usage with TypeScript and for convenient IntelliSense auto-complete and documentation in your editor.
When using TypeScript, you can pass the type of database row as a type parameter to the `from` method to get better auto-completion support down the chain.
If you don't provide a type for the row you need to explicitly pass `from<any>('tableName')`.
```ts
type Message = {
id: number;
inserted_at: string;
message: string;
user_id: string;
channel_id: number;
author: { username: string };
}
const response = await supabase
.from<Message>('messages') // Message maps to the type of the row in your database.
.select('*, author:user_id(username)')
.match({ channel_id: 2 }) // Your IDE will be able to help with auto-completion.
response.data // Response data will be of type Array<Message>.
// If you don't provide a type for the row you need to explicitly pass `from<any>('tableName')`.
const response = await supabase
.from<any>('messages')
.select('*, author:user_id(username)')
.match({ channel_id: 2 })
response.data // Response data will be of type Array<any>.
```
@@ -0,0 +1,12 @@
---
id: index
title: "Supabase Client"
slug: supabase-client
custom_edit_url: ../../spec/supabase_js_v1_legacy.yml
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Supabase JavaScript.
@@ -0,0 +1,163 @@
---
id: initializing
title: "Initializing"
slug: initializing
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1_legacy.yml
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
You can initialize a new Supabase client using the `createClient()` method.
The Supabase client is your entrypoint to the rest of the Supabase functionality
and is the easiest way to interact with everything we offer within the Supabase ecosystem.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
supabaseUrl
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
<code>string</code>
</span>
</h4>
<div class="method-list-item-description">
The unique Supabase URL which is supplied when you create a new project in your project dashboard.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
supabaseKey
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
<code>string</code>
</span>
</h4>
<div class="method-list-item-description">
The unique Supabase Key which is supplied when you create a new project in your project dashboard.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
options
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
<code>SupabaseClientOptions</code>
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
</ul>
## Examples
### createClient()
```js
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')
```
### With additional parameters
```js
import { createClient } from '@supabase/supabase-js'
const options = {
schema: 'public',
headers: { 'x-my-custom-header': 'my-app-name' },
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true
}
const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key", options)
```
### API schemas
```js
import { createClient } from '@supabase/supabase-js'
// Provide a custom schema. Defaults to "public".
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', {
schema: 'other_schema'
})
```
By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
Go to `Settings > API > Schema` and add the schema which you want to expose to the API.
Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
### Custom `fetch` implementation
```js
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', {
fetch: fetch.bind(globalThis)
})
```
`supabase-js` uses the [`cross-fetch`](https://www.npmjs.com/package/cross-fetch) library to make HTTP requests,
but an alternative `fetch` implementation can be provided as an option.
This is most useful in environments where `cross-fetch` is not compatible (for instance Cloudflare Workers).
@@ -0,0 +1,34 @@
---
id: installing
title: "Installing"
slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1_legacy.yml
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
All JavaScript libraries are built directly by the Supabase team.
Other languages are built by the community and supported by Supabase.
## JavaScript
Via NPM
```bash
npm install @supabase/supabase-js
```
Via Yarn
```bash
yarn add @supabase/supabase-js
```
Find the source code on [GitHub](https://github.com/supabase/supabase-js).
Or via CDN
```js
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js"></script>
//or
<script src="https://unpkg.com/@supabase/supabase-js"></script>
```
@@ -0,0 +1,16 @@
---
id: intro
title: 'Supabase JavaScript Library'
slug: /
sidebar_label: Supabase JavaScript Library
---
This reference documents every object and method available in Supabase's isomorphic JavaScript library, `supabase-js`.
You can use the `supabase-js` library to:
- interact with your Postgres database
- listen to database changes
- invoke Deno Edge Functions
- build login and user management functionality
- manage large files
Whitespace-only changes.
@@ -0,0 +1,138 @@
{
"sidebar": [
{
"type": "category",
"label": "Getting Started",
"items": ["intro", "installing", "initializing", "generating-types"],
"collapsed": false
},
{
"type": "category",
"label": "Auth",
"items": [
"generated/auth-signup",
"generated/auth-signin",
"generated/auth-signout",
"generated/auth-session",
"generated/auth-user",
"generated/auth-update",
"generated/auth-setauth",
"generated/auth-onauthstatechange",
"generated/auth-api-getuser",
"generated/auth-api-resetpasswordforemail"
],
"collapsed": true
},
{
"type": "category",
"label": "Auth (Server Only)",
"items": [
"generated/auth-api-listusers",
"generated/auth-api-createuser",
"generated/auth-api-deleteuser",
"generated/auth-api-generatelink",
"generated/auth-api-inviteuserbyemail",
"generated/auth-api-sendmobileotp",
"generated/auth-api-updateuserbyid"
],
"collapsed": true
},
{
"type": "category",
"label": "Functions",
"items": ["generated/invoke"],
"collapsed": true
},
{
"type": "category",
"label": "Database",
"items": [
"generated/select",
"generated/insert",
"generated/update",
"generated/upsert",
"generated/delete",
"generated/rpc"
],
"collapsed": true
},
{
"type": "category",
"label": "Realtime",
"items": [
"generated/subscribe",
"generated/removesubscription",
"generated/removeallsubscriptions",
"generated/getsubscriptions"
],
"collapsed": true
},
{
"type": "category",
"label": "Storage",
"items": [
"generated/storage-createbucket",
"generated/storage-getbucket",
"generated/storage-listbuckets",
"generated/storage-updatebucket",
"generated/storage-deletebucket",
"generated/storage-emptybucket",
"generated/storage-from-upload",
"generated/storage-from-download",
"generated/storage-from-list",
"generated/storage-from-update",
"generated/storage-from-move",
"generated/storage-from-copy",
"generated/storage-from-remove",
"generated/storage-from-createsignedurl",
"generated/storage-from-createsignedurls",
"generated/storage-from-getpublicurl"
],
"collapsed": true
},
{
"type": "category",
"label": "Modifiers",
"items": [
"generated/using-modifiers",
"generated/limit",
"generated/order",
"generated/range",
"generated/single",
"generated/maybesingle"
],
"collapsed": true
},
{
"type": "category",
"label": "Filters",
"items": [
"generated/using-filters",
"generated/or",
"generated/not",
"generated/match",
"generated/eq",
"generated/neq",
"generated/gt",
"generated/gte",
"generated/lt",
"generated/lte",
"generated/like",
"generated/ilike",
"generated/is",
"generated/in",
"generated/contains",
"generated/containedby",
"generated/rangelt",
"generated/rangegt",
"generated/rangegte",
"generated/rangelte",
"generated/rangeadjacent",
"generated/overlaps",
"generated/textsearch",
"generated/filter"
],
"collapsed": true
}
]
}
@@ -0,0 +1 @@
["v1"]
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
}
+184
View File
@@ -0,0 +1,184 @@
---
id: about
title: Introduction
description: 'What is Supabase?'
slug: /
hide_table_of_contents: true
pagination_next: null
---
import ThemedImage from '@theme/ThemedImage'
import AngularLogo from '@site/static/img/libraries/angular-icon.svg'
import ExpoLogo from '@site/static/img/libraries/expo-icon.svg'
import DartLogo from '@site/static/img/libraries/dart-icon.svg'
import JavascriptLogo from '@site/static/img/libraries/javascript-icon.svg'
import NextjsDarkLogo from '@site/static/img/libraries/nextjs-dark-icon.svg'
import NextjsLightLogo from '@site/static/img/libraries/nextjs-light-icon.svg'
import ReactLogo from '@site/static/img/libraries/react-icon.svg'
import SolidJSLogo from '@site/static/img/libraries/solidjs-icon.svg'
import RedwoodJsLogo from '@site/static/img/libraries/redwoodjs-icon.svg'
import SvelteLogo from '@site/static/img/libraries/svelte-icon.svg'
import VuejsLogo from '@site/static/img/libraries/vuejs-icon.svg'
import useBaseUrl from '@docusaurus/useBaseUrl'
import Link from '@docusaurus/Link'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import ButtonCard from '@site/src/components/ButtonCard'
const frameworks = [
{
name: 'Angular',
logo: AngularLogo,
href: '/guides/with-angular',
},
{
name: 'Expo',
logo: ExpoLogo,
href: 'https://github.com/supabase/examples/tree/main/supabase-js-v1/todo-list/expo-todo-list',
},
{ name: 'Flutter', logo: DartLogo, href: '/guides/with-flutter' },
{
name: 'JavaScript',
logo: JavascriptLogo,
href: 'https://github.com/supabase/examples/tree/main/supabase-js-v1/auth/javascript-auth',
},
{
name: 'Next.js',
themed: true,
logo: {
dark: '/img/libraries/nextjs-dark-icon.svg',
light: '/img/libraries/nextjs-light-icon.svg',
},
href: '/guides/with-nextjs',
},
{ name: 'React', logo: ReactLogo, href: '/guides/with-react' },
{
name: 'RedwoodJS',
logo: RedwoodJsLogo,
href: '/guides/with-redwoodjs',
},
{ name: 'SolidJS', logo: SolidJSLogo, href: '/guides/with-solidjs' },
{ name: 'Svelte', logo: SvelteLogo, href: '/guides/with-svelte' },
{ name: 'Vue', logo: VuejsLogo, href: '/guides/with-vue-3' },
]
Supabase is an open source Firebase alternative providing all the backend features you need to build a product.
You can use it completely, or just the features you need.
[Start a project](https://app.supabase.com) with the hosted platform or learn how to [host Supabase](/docs/guides/hosting/overview) yourself.
## Learn about features
<div class="container" style={{ padding: 0 }}>
<div class="row is-multiline">
{/* Auth */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/auth')}
title={'Auth'}
description={'User management with Row Level Security.'}
style={{ height: '100%' }}
/>
</div>
{/* Auto-generated APIs */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/api')}
title={'Auto-generated APIs'}
description={'Instantly generate APIs for your database.'}
style={{ height: '100%' }}
/>
</div>
{/* Database */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/database')}
title={'Database'}
description={'A dedicated, scalable Postgres database.'}
style={{ height: '100%' }}
/>
</div>
{/* Edge Functions */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/functions')}
title={'Edge Functions'}
description={'Server-side functions, distributed globally.'}
style={{ height: '100%' }}
/>
</div>
{/* Realtime */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/realtime')}
title={'Realtime'}
description={'Build with Broadcast, Presence, and Postgres Changes.'}
style={{ height: '100%' }}
/>
</div>
{/* File Storage */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/storage')}
title={'File Storage'}
description={'Store, organize, and serve large files.'}
style={{ height: '100%' }}
/>
</div>
{/* Observability */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/platform/logs')}
title={'Observability'}
description={'Monitor and debug your infrastucture.'}
style={{ height: '100%' }}
/>
</div>
</div>
</div>
## Start with a framework
Supabase is just Postgres, which makes it compatible with a large number of tools and frameworks.
<div>
<div class="row is-multiline">
{frameworks.map((x) => (
<div key={x.name} class="col col--3">
<ButtonCard
layout="horizontal"
icon={
x.logo && !x.themed ? (
<x.logo
width="20"
alt={x.name}
style={{ display: 'block', maxHeight: 20, minWidth: 20 }}
/>
) : (
<ThemedImage
style={{ display: 'block', maxHeight: 20, minWidth: 20, margin: 0 }}
alt={x.name}
width="20"
sources={{
light: useBaseUrl(x.logo.light),
dark: useBaseUrl(x.logo.dark),
}}
/>
)
}
class="card"
to={useBaseUrl(x.href)}
title={x.name}
description={x.description}
style={{ height: '100%' }}
/>
</div>
))}
</div>
</div>
+39
View File
@@ -0,0 +1,39 @@
---
id: architecture
title: Architecture
description: 'Supabase design and architecture'
# hide_table_of_contents: true
---
Supabase is open source. Wherever possible, we use and support existing tools rather than developing from scratch.
We choose open source tools which are scalable and we make them simple to use.
![Supabase Architecture](/img/supabase-architecture.png)
Supabase is not a 1-to-1 mapping of Firebase. While we are building many of the features that Firebase offers, we are not going about it the same way.
Our technological choices are quite different from Firebase. Everything we use is open source. Wherever possible, we use and support existing tools rather than developing from scratch.
Most notably, we use Postgres rather than a NoSQL store. This choice was deliberate. We believe that no other database offers the scalability and functionality required to compete with Firebase.
## Feature Status
| Product | Feature | Stage | Docs |
| -------------------------- | ---------------------- | ----- | ------------------------------------------------ |
| Database | Postgres | GA | [Link](/docs/guides/database) |
| Database | Webhooks | Alpha | |
| Database | Point in time Recovery | Alpha | |
| Realtime | Postgres Changes | Beta | [Link](/docs/guides/realtime/postgres-changes) |
| Realtime | Broadcast | Alpha | [Link](/docs/guides/realtime/broadcast) |
| Realtime | Presence | Alpha | [Link](/docs/guides/realtime/presence) |
| Storage | | Beta | [Link](/docs/guides/storage) |
| Storage | CDN | Beta | [Link](/docs/guides/storage-cdn) |
| Edge Functions | | Beta | [Link](/docs/guides/functions) |
| Auth | OAuth Providers | Beta | [Link](/docs/guides/auth/auth-apple) |
| Auth | Passwordless | Beta | [Link](/guides/auth/auth-magic-link) |
| Auth | Next.js Auth Helpers | Alpha | [Link](/docs/guides/auth/auth-helpers/nextjs) |
| Auth | SvelteKit Auth Helpers | Alpha | [Link](/docs/guides/auth/auth-helpers/sveltekit) |
| Public API | | Beta | [Link](/docs/reference/api) |
| CLI | | Beta | [Link](/docs/guides/cli) |
| Client Library: JavaScript | | GA | [Link](/docs/reference/javascript/next/) |
| Client Library: Dart | | Beta | [Link](/docs/reference/dart) |
File renamed without changes.
File renamed without changes.
@@ -3,21 +3,21 @@ id: sla
title: Service Level Agreement
---
The following Service Level Agreement, which is incorporated into and forms part of the Subscription Agreement between Supabase, Inc. ("Supabase") and Customer (the "Agreement"), will apply to the Services for Enterprise Customers specified in an Order Form during the applicable Subscription Term:
The following Service Level Agreement, which is incorporated into and forms part of the Subscription Agreement between Supabase, Inc. ("Supabase") and Customer (the "Agreement"), will apply to the Services for Enterprise Customers specified in an Order Form during the applicable Subscription Term:
## Platform
### 1. Uptime Commitment
Supabase will provide Actual Availability for at least ninety-nine and nine tenths percent (99.9%) of the total time in each calendar month during the Subscription Term, as measured by Supabase (the **"Uptime Commitment"**).
### 2. Service Credits
If the Uptime Commitment is not met during any particular calendar month during the Subscription Term, then Customer will be eligible for a service credit ("Service Credit"), provided that Customer reports to Supabase such failure to meet the Uptime Commitment and requests such Service Credit in accordance with this Exhibit. The amount of any Service Credit due hereunder shall be calculated as follows:
X * Y, where X = the total fees due from Customer to Supabase for the affected Services for the relevant calendar month (regardless of when billed or payable), and Y = the Credit Percentage corresponding with the Actual Availability provided (as a percentage of total time) for the relevant calendar month, as set forth in the table below.
If the Uptime Commitment is not met during any particular calendar month during the Subscription Term, then Customer will be eligible for a service credit ("Service Credit"), provided that Customer reports to Supabase such failure to meet the Uptime Commitment and requests such Service Credit in accordance with this Exhibit. The amount of any Service Credit due hereunder shall be calculated as follows:
X \* Y, where X = the total fees due from Customer to Supabase for the affected Services for the relevant calendar month (regardless of when billed or payable), and Y = the Credit Percentage corresponding with the Actual Availability provided (as a percentage of total time) for the relevant calendar month, as set forth in the table below.
| Actual Availability | Credit Percentage |
|----------------------------------------------------|-------------------|
| -------------------------------------------------- | ----------------- |
| Less than 99.9% but greater than or equal to 99.0% | 10% |
| Less than 99.0% but greater than or equal to 98.0% | 15% |
| Less than 98.0% but greater than or equal to 96.0% | 20% |
@@ -33,7 +33,7 @@ All capitalized words used but not defined in this Service Level Agreement have
#### 4.1 Scheduled Availability
"Scheduled Availability" means the time, in minutes, that the applicable Services are generally accessible and available to Customer’s Permitted Users.
"Scheduled Availability" means the time, in minutes, that the applicable Services are generally accessible and available to Customer’s Permitted Users.
#### 4.2 Unscheduled Downtime
@@ -41,7 +41,7 @@ All capitalized words used but not defined in this Service Level Agreement have
#### 4.3 Actual Availability
"Actual Availability" means Scheduled Availability less Unscheduled Downtime.
"Actual Availability" means Scheduled Availability less Unscheduled Downtime.
## Support
@@ -51,39 +51,38 @@ Supabase Support Service Level Agreements.
**Critical Issue**
Defect resulting in full or partial system outage or a condition that makes Supabase unusable
or unavailable in production for all of Customer’s Users.
Defect resulting in full or partial system outage or a condition that makes Supabase unusable
or unavailable in production for all of Customer’s Users.
### 2. High
**Significant Business Disruption**
Issue resulting in a situation meaning major functionality is impacted and
significant performance degradation is experienced. Issue impacts significant proportion of user base and / or major
Supabase functionality.
Issue resulting in a situation meaning major functionality is impacted and
significant performance degradation is experienced. Issue impacts significant proportion of user base and / or major
Supabase functionality.
### 3. Normal
**Minor Feature or Functional Issue / General Question**
Issue results in a component of Supabase not
performing as expected or documented. An inquiry by a Customer representative regarding a general technical issue
or general question.
Issue results in a component of Supabase not
performing as expected or documented. An inquiry by a Customer representative regarding a general technical issue
or general question.
### 4. Low
**Minor Issue / Feature Request**
An Information request about Supabase or feature request.
An Information request about Supabase or feature request.
## Target response times
| Severity Level | Standard | Priority | Priority Plus |
|----------------|--------------------------------------------|----------------------------------|-----------------------------------|
| 1. Urgent | 1 business hour<br />24/7 × 365 | 1 business hour<br />24/7 × 365 | 1 business hour<br />24/7 × 365 |
| Severity Level | Standard | Priority | Priority Plus |
| -------------- | ------------------------------------- | ------------------------------------- | -------------------------------------- |
| 1. Urgent | 1 business hour<br />24/7 × 365 | 1 business hour<br />24/7 × 365 | 1 business hour<br />24/7 × 365 |
| 2. High | 4 business hours<br />Monday - Friday | 2 business hours<br />Monday - Friday | 2 business hours<br />24/7 × 365 |
| 3. Normal | 1 business day<br />Monday - Friday | 1 business day<br />Monday - Friday | 12 business hours<br />Monday - Friday |
| 4. Low | 2 business days<br />Monday - Friday | 2 business days<br />Monday - Friday | 1 business day<br />Monday - Friday |
Business hours are from 6am to 6pm (local time), except where otherwise stated.
File renamed without changes.
@@ -14,17 +14,17 @@ Self-hosting Supabase is free. If you wish to use our cloud-platform, we provide
### How do I host Supabase?
You can use the docker-compose script [here](https://github.com/supabase/supabase/tree/master/docker), and find detailed instructions [here](/docs/guides/hosting/overview).
You can use the docker-compose script [here](https://github.com/supabase/supabase/tree/master/docker), and find detailed instructions [here](/docs/guides/hosting/overview).
Supabase is an amalgamation of open source tools. Some of these tools are made by Supabase (like our [Realtime Server](https://github.com/supabase/realtime)), some we support directly (like [PostgREST](http://postgrest.org/en/v7.0.0/)), and some are third-party tools (like [KonSupabase is an amalgamation open sourceg](https://github.com/Kong/kong)).
Supabase is an amalgamation of open source tools. Some of these tools are made by Supabase (like our [Realtime Server](https://github.com/supabase/realtime)), some we support directly (like [PostgREST](http://postgrest.org/en/v7.0.0/)), and some are third-party tools (like [KonSupabase is an amalgamation open sourceg](https://github.com/Kong/kong)).
All of the tools we use in Supabase are MIT, Apache 2.0, or PostgreSQL licensed. This is one of the requirements to be considered for the Supabase stack.
### How can you be a Firebase alternative if you're built with a relational database?
We started Supabase because we love the functionality of Firebase, but we personally experienced the scaling issues that many others experienced. We chose Postgres because it's well-trusted, with phenomenal scalability.
We started Supabase because we love the functionality of Firebase, but we personally experienced the scaling issues that many others experienced. We chose Postgres because it's well-trusted, with phenomenal scalability.
Our goal is to make Postgres as easy to use as Firebase, so that you no longer have to choose between usability and scalability.
Our goal is to make Postgres as easy to use as Firebase, so that you no longer have to choose between usability and scalability.
We're sure that once you start using Postgres, you'll love it more than any other database.
### Do you support `[some other database]`?
@@ -33,7 +33,6 @@ We only support PostgreSQL. It's unlikely we'll ever move away from Postgres; ho
### Do you have a library for `[some other language]`?
We officially support [JavaScript](/docs/reference/javascript/supabase-client) and [Dart](/docs/reference/dart/installing).
We officially support [JavaScript](/docs/reference/javascript/installing) and [Dart](/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).
@@ -47,17 +47,6 @@ After developing your project and deciding it's time to Go Live With Real Users,
- Nightly backups for Pro tier projects are available on the Supabase dashboard for up to 7 days.
- Upgrading to the Supabase Pro Tier will give you access to email support on support@supabase.io
## Platform status
If Supabase experiences outages, we keep you as informed as possible, as early as possible. We provide the following feedback channels:
- Status page: [status.supabase.com](https://status.supabase.com/)
- RSS Feed: [status.supabase.com/history.rss](https://status.supabase.com/history.rss)
- Atom Feed: [status.supabase.com/history.atom](https://status.supabase.com/history.atom)
- 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.
## Next steps
This checklist is always growing so be sure to check back frequently, and also feel free to suggest additions and amendments by making a PR on [GitHub](https://github.com/supabase/supabase).
Whitespace-only changes.
@@ -205,6 +205,10 @@ Controls the minimum amount of time that must pass before sending another signup
If you do not require email confirmation, you may set this to `true`. Defaults to `false`.
`MAILER_SECURE_EMAIL_CHANGE_ENABLED` - `bool`
If `true`, send an email to both the user's current and new email with a confirmation link, otherwise send an email with confirmation link only to new email. Defaults to `true`.
`MAILER_URLPATHS_INVITE` - `string`
URL path to use in the user invite email. Defaults to `/`.
@@ -252,7 +256,8 @@ Default Content (if template is unavailable):
<h2>You have been invited</h2>
<p>
You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invite:
You have been invited to create a user on {{ .SiteURL }}. Follow this link to
accept the invite:
</p>
<p><a href="{{ .ConfirmationURL }}">Accept the invite</a></p>
```
@@ -309,7 +314,10 @@ Default Content (if template is unavailable):
```html
<h2>Confirm Change of Email</h2>
<p>Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:</p>
<p>
Follow this link to confirm the update of your email from {{ .Email }} to {{
.NewEmail }}:
</p>
<p><a href="{{ .ConfirmationURL }}">Change Email</a></p>
```
@@ -631,7 +639,6 @@ Returns:
}
```
### **PUT /admin/users/{user_id}**
Updates a user. Requires your `service_role` API key and thus should only be
@@ -666,6 +673,23 @@ Returns:
}
```
### **POST /admin/generate_link**
Returns the corresponding email action link based on the type specified. The response also contains the query params of the action link as separate JSON fields for convenience (along with the email OTP from which the corresponding token is generated).
Returns:
```js
{
"action_link": "http://localhost:9999/verify?token=TOKEN&type=TYPE&redirect_to=REDIRECT_URL",
"email_otp": "EMAIL_OTP",
"hashed_token": "TOKEN",
"verification_type": "TYPE",
"redirect_to": "REDIRECT_URL",
...
}
```
### **DELETE /admin/users/{user_id}**
Deletes a user. Requires your `service_role` API key and thus should only be
@@ -2,100 +2,103 @@
id: api
title: APIs
description: Auto-generating and Realtime APIs.
sidebar_label: Overview
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import useBaseUrl from '@docusaurus/useBaseUrl'
## Overview
Supabase generates three types of API directly from your database schema.
Supabase generates three types of API directly from your database schema.
- REST - interact with your database through a restful interface.
- Realtime - listen to database changes.
- GraphQL - [in beta](https://supabase.com/blog/2021/12/03/pg-graphql).
- GraphQL - [in beta](https://supabase.com/blog/pg-graphql).
The APIs are:
- **Instant and auto-generated.** <br />As you update your database the changes are immediately accessible through your API.
- **Self documenting.** <br />Supabase generates documentation in the Dashboard which updates as you make database changes.
- **Secure.** <br />The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled.
- **Instant and auto-generated.** <br />As you update your database the changes are immediately accessible through your API.
- **Self documenting.** <br />Supabase generates documentation in the Dashboard which updates as you make database changes.
- **Secure.** <br />The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled.
- **Fast.** <br />Our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting.
- **Scalable.** <br />The API can serve thousands of simultaneous requests, and works well for Serverless workloads.
### REST API {#rest-api-overview}
### REST API
Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres.
Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres.
It provides everything you need from a CRUD API:
- Basic CRUD operations
- Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch
- Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch
- Works with Postgres Views
- Works with Postgres Functions
- Works with Postgres Functions
- Works with the Postgres security model - including Row Level Security, Roles, and Grants.
<iframe
className="w-full video-with-border"
width="640"
height="480"
src="https://www.youtube-nocookie.com/embed/rPAJJFdtPw0"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/rPAJJFdtPw0"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
### GraphQL API
### GraphQL API {#graphql-api-overview}
:::note
GraphQL is in Beta, and may have breaking changes. It is only available on self-hosted setups and Supabase projects created after 28th March 2022.
GraphQL is in Beta, and may have breaking changes. It is only available on self-hosted setups and Supabase projects created after 28th March 2022.
:::
GraphQL in Supabase works through [pg_graphql](https://supabase.com/blog/2021/12/03/pg-graphql), an open source PostgreSQL extension for GraphQL.
GraphQL in Supabase works through [pg_graphql](https://supabase.com/blog/pg-graphql), an open source PostgreSQL extension for GraphQL.
### Realtime API
### Realtime API {#realtime-api-overview}
Supabase provides a Realtime API using [Realtime](https://github.com/supabase/realtime). You can use this to listen to database changes over websockets.
Supabase provides a Realtime API using [Realtime](https://github.com/supabase/realtime). You can use this to listen to database changes over websockets.
Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications.
## Getting started
All APIs are auto-created from Database tables. After you have added tables or functions to your database, you can use the APIs provided.
All APIs are auto-created from Database tables. After you have added tables or functions to your database, you can use the APIs provided.
### Creating API Routes
API routes are automatically created when you create Postgres Tables, Views, or Functions.
API routes are automatically created when you create Postgres Tables, Views, or Functions.
Let's create our first
API route by creating a table called `todos` (which will store some public user information).
This will create a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests.
Let's create our first
API route by creating a table called `todos` to store tasks.
This creates a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Table editor" section.
2. Click "New Table".
3. Enter the table name "todos".
4. Click "Save".
5. Click "New Column".
6. Enter the column name "task" and make the type "text".
7. Click "Save".
```
<TabItem value="dashboard">
1. Go to the [Table editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
1. Click **New Table** and create a table with the name `todos`.
1. Click **Save**.
1. Click **New Column** and create a column with the name `task` and type `text`.
1. Click **Save**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
<source
src={useBaseUrl('/videos/api/api-create-table-sm.mp4')}
type="video/mp4"
muted
playsInline
/>
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table called "todos" with a column to store tasks.
@@ -113,19 +116,20 @@ create table todos (
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings/general) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src={useBaseUrl('/videos/api/api-url-and-key.mp4')}
type="video/mp4"
muted
playsInline
/>
</video>
The REST API and the GraphQL API are both accessible through this URL:
The REST API and the GraphQL API are both accessible through this URL:
- REST: `https://<project_ref>.supabase.co/rest/v1`
- GraphQL: `https://<project_ref>.supabase.co/graphql/v1`
@@ -134,43 +138,32 @@ Both of these routes require the `anon` key to be passed through an `apikey` hea
#### API Keys
You can find the Keys inside the Dashboard in the same location as the URL above.
You are provided with two keys:
- an `anon` key, which is safe to be used in a browser context.
- a `service_role` key, which should only be used on a server. This key can bypass Row Level Security. NEVER use this key in a browser.
### Accessing the docs in the Dashboard
### Accessing the Docs
#### REST API {#rest-api-dashboard-docs}
#### REST API
Supabase generates documentation in the Dashboard which updates as you make database changes.
Supabase generates documentation in the [Dashboard](https://app.supabase.com) which updates as you make database changes.
Let's view the documentation for a `countries` table which we created in our database.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "API" section.
2. Find "todos" in the "Tables and Views" section.
1. Go to the [API](https://app.supabase.com/project/_/api) page in the Dashboard.
2. Find the `countries` table under **Tables and Views** in the sidebar.
3. Switch between the JavaScript and the cURL docs using the tabs.
```
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-docs.mp4" type="video/mp4" muted playsInline />
<source
src={useBaseUrl('/videos/api/api-docs.mp4')}
type="video/mp4"
muted
playsInline
/>
</video>
</TabItem>
</Tabs>
#### GraphQL
#### GraphQL
The GraphQL Endpoint that we provide (`https://<project_ref>.supabase.co/graphql/v1`) is compatible with any GraphiQL implementation that can pass an `apikey` header.
Some suggested applications:
@@ -182,22 +175,22 @@ Some suggested applications:
## Using the API
### REST API
### REST API
You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide.
Let's see how to make a request to the `todos` table which we created in the first step,
Let's see how to make a request to the `todos` table which we created in the first step,
using the API URL (`SUPABASE_URL`) and Key (`SUPABASE_ANON_KEY`) we provided:
<Tabs
defaultValue="JavaScript"
values={[
{label: 'JavaScript', value: 'JavaScript'},
{label: 'cURL', value: 'cURL'},
]}>
<TabItem value="JavaScript">
groupId="language"
defaultValue="javascript"
values={[
{label: 'JavaScript', value: 'javascript'},
{label: 'cURL', value: 'curl'},
]}>
<TabItem value="javascript">
```javascript
// Initialize the JS client
@@ -205,13 +198,11 @@ import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
// Make a request
const { data: todos, error } = await supabase
.from('todos')
.select('*')
const { data: todos, error } = await supabase.from('todos').select('*')
```
</TabItem>
<TabItem value="cURL">
<TabItem value="curl">
```bash
# Append /rest/v1/ to your URL, and then use the table name as the route
@@ -223,32 +214,33 @@ curl '<SUPABASE_URL>/rest/v1/todos' \
</TabItem>
</Tabs>
JS Reference: [select()](/docs/reference/javascript/select),
[insert()](/docs/reference/javascript/insert),
[update()](/docs/reference/javascript/update),
[upsert()](/docs/reference/javascript/upsert),
[delete()](/docs/reference/javascript/delete),
[rpc()](/docs/reference/javascript/rpc) (call Postgres functions).
JS Reference: [select()](../reference/javascript/select),
[insert()](../reference/javascript/insert),
[update()](../reference/javascript/update),
[upsert()](../reference/javascript/upsert),
[delete()](../reference/javascript/delete),
[rpc()](../reference/javascript/rpc) (call Postgres functions).
### GraphQL API
### GraphQL API
:::note
:::note
To rebuild your GraphQL schema from the SQL schema, call `select graphql.rebuild_schema();`.
Be sure to rebuild the GraphQL schema after altering the SQL schema.
:::
You can use any GraphQL client with the Supabase GraphQL API. For our GraphQL example we will use [urql](https://formidable.com/open-source/urql/docs/).
You can use any GraphQL client with the Supabase GraphQL API. For our GraphQL example we will use [urql](https://formidable.com/open-source/urql/docs/).
<Tabs
defaultValue="Javascript"
values={[
{label: 'Javascript', value: 'Javascript'},
{label: 'cURL', value: 'cURL'},
]}>
<TabItem value="Javascript">
groupId="language"
defaultValue="javascript"
values={[
{label: 'JavaScript', value: 'javascript'},
{label: 'cURL', value: 'curl'},
]}>
<TabItem value="javascript">
```javascript
import { createClient, useQuery } from 'urql'
@@ -263,7 +255,7 @@ const headers = {
// See: https://formidable.com/open-source/urql/docs/basics/react-preact/#setting-up-the-client
const client = createClient({
url: '<SUPABASE_URL>/graphql/v1',
fetchOptions: function createFetchOptions() {
fetchOptions: function createFetchOptions() {
return { headers }
},
})
@@ -292,7 +284,7 @@ const { data, fetching, error } = result
```
</TabItem>
<TabItem value="cURL">
<TabItem value="curl">
```bash
# Append /graphql/v1/ to your URL, and then use the table name as the route
@@ -305,32 +297,36 @@ curl --request POST '<SUPABASE_URL>/graphql/v1' \
</TabItem>
</Tabs>
### Realtime API
By default Realtime is disabled on your database. Let's turn on Realtime for the `todos` table.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Database" section.
2. Click on "Replication" in the sidebar.
3. Control which database events are sent by toggling the Insert/Update/Delete toggles.
4. Control which tables broadcast changes by clicking into the "Source" and toggling the tables.
```
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Replication** in the sidebar.
3. Control which database events are sent by toggling **Insert**, **Update**, and **Delete**.
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={useBaseUrl('/videos/api/api-realtime.mp4')}
type="video/mp4"
muted
playsInline
/>
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
alter publication supabase_realtime add table todos;
@@ -339,14 +335,7 @@ alter publication supabase_realtime add table todos;
</TabItem>
</Tabs>
Now we can listen to any new data that is inserted into the `todos` table:
<Tabs
defaultValue="Javascript"
values={[
{label: 'Javascript', value: 'Javascript'}
]}>
<TabItem value="Javascript">
From the client, we can listen to any new data that is inserted into the `todos` table:
```javascript
// Initialize the JS client
@@ -358,46 +347,41 @@ const handleInserts = (payload) => {
console.log('Change received!', payload)
}
// Listen to unserts
// Listen to inserts
const { data: todos, error } = await supabase
.from('todos')
.on('INSERT', handleUpdates)
.on('INSERT', handleInserts)
.subscribe()
```
</TabItem>
</Tabs>
Use [subscribe()](/docs/reference/javascript/subscribe) to listen to database changes.
Use [subscribe()](/docs/reference/javascript/subscribe) to listen to database changes.
The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a [publication](/docs/guides/database/replication#publications)
called `supabase_realtime`, and by managing this publication you can control which data is broadcast.
## API Security
### Securing your Routes
### Securing your Routes
Your API is designed to work with Postgres Row Level Security. 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. Make sure you secure it by [enabling RLS](/docs/guides/api#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).
When you create a table in Postgres, Row Level Security is disabled by default. To enable RLS:
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Authentication" section.
2. Click on "Policies" in the sidebar.
3. Click "Enable RLS" to enable Row Level Security.
```
<TabItem value="dashboard">
1. Go to the [Authentication](https://app.supabase.com/project/_/auth/users) page in the Dashboard.
2. Click on **Policies** in the sidebar.
3. Select **Enable RLS** to enable Row Level Security.
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
alter table todos enable row level security;
@@ -406,24 +390,25 @@ alter table todos enable row level security;
</TabItem>
</Tabs>
### The `service_role` key
### The `service_role` key
Never expose the `service_role` key in a browser or anywhere where a user can see it. This Key is designed to bypass Row Level Security - so it should only be used on a private server.
Never expose the `service_role` key in a browser or anywhere where a user can see it. This Key can is designed to bypass Row Level Security - so it should only be used on a private server.
We have [partnered with GitHub](https://supabase.com/blog/2022/03/28/community-day#supabase-is-now-a-github-secret-scanning-partner) to scan for Supabase `service_role` keys pushed to public repositories.
We have [partnered with GitHub](https://github.blog/changelog/2022-03-28-supabase-is-now-a-github-secret-scanning-partner/) to scan for Supabase `service_role` keys pushed to public repositories.
If they detect any keys with service_role privileges being pushed to GitHub, they will forward the API key to us, so that we can automatically revoke the detected secrets and notify you, protecting your data against malicious actors.
### Safeguards towards accidental deletes and updates
For all projects, by default, the Postgres extension [safeupdate](https://github.com/eradman/pg-safeupdate) is enabled for all queries coming from the API.
For all projects, by default, the Postgres extension [safeupdate](https://github.com/eradman/pg-safeupdate) is enabled for all queries coming from the API.
This ensures that any `delete()` or `update()` would fail if there are no accompanying filters provided.
To confirm that safeupdate is enabled for queries going through the API of your project, the following query could be run:
```sql
select usename,useconfig from pg_shadow where usename = 'authenticator' ;
```
The expected value for `useconfig` should be:
```
["session_preload_libraries=supautils, safeupdate"]
```
@@ -1,6 +1,6 @@
---
id: generating-types
title: "Generating Types"
title: 'Generating Types'
description: How to generate types for your API and Supabase libraries.
---
@@ -31,9 +31,9 @@ Important notes:
After you have generated your types, you can use them in your TypeScript projects:
```ts
import { NextApiRequest, NextApiResponse } from "next"
import { createClient } from "@supabase/supabase-js"
import { definitions } from "../../types/supabase"
import { NextApiRequest, NextApiResponse } from 'next'
import { createClient } from '@supabase/supabase-js'
import { definitions } from '../../types/supabase'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
@@ -42,11 +42,11 @@ const supabase = createClient(
export default async (req: NextApiRequest, res: NextApiResponse) => {
const allOnlineUsers = await supabase
.from<definitions["users"]>("users")
.select("*")
.eq("status", "ONLINE")
.from<definitions['users']>('users')
.select('*')
.eq('status', 'ONLINE')
res.status(200).json(allOnlineUsers)
};
}
```
For more advance type-support, check out [`postgrest-js-tools`](https://github.com/mzalevski/postgrest-js-tools).
@@ -56,6 +56,7 @@ For more advance type-support, check out [`postgrest-js-tools`](https://github.c
One way to keep your type definitions in sync with your database is to set up a GitHub action that runs on a schedule.
The following script can be run in your terminal to produce the file `types/database/index.ts`.
```
npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/database/index.ts
```
@@ -67,7 +68,7 @@ You can add this script to your `package.json` and run it using `npm run update-
```
You can use GitHub actions to generate this file automatically. This script will commit the change to your repo every night.
Create a file `.github/workflows/update-types.yml` and add the following snippet into this file to define the action along with the environment variables.
Create a file `.github/workflows/update-types.yml` and add the following snippet into this file to define the action along with the environment variables.
```yml
name: Update database types
@@ -115,4 +116,4 @@ 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)
- [Generating Supabase types with GitHub Actions](https://blog.esteetey.dev/how-to-create-and-test-a-github-action-that-generates-types-from-supabase-database)
@@ -2,22 +2,15 @@
id: auth
title: Auth
description: Use Supabase to Authenticate and Authorize your users.
sidebar_label: Overview
---
import Link from '@docusaurus/Link'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import providers from '@site/src/data/authProviders'
<iframe
className="w-full video-with-border"
width="640"
height="480"
src="https://www.youtube-nocookie.com/embed/6ow_jW4epf8"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
import ButtonCard from '@site/src/components/ButtonCard'
import useBaseUrl from '@docusaurus/useBaseUrl'
## Overview
@@ -26,9 +19,20 @@ There are two parts to every Auth system:
- **Authentication:** should this person be allowed in? If yes, who are they?
- **Authorization:** once they are in, what are they allowed to do?
Supabase Auth is designed to work either as a standalone product, or deeply integrated with the other Supabase products.
Supabase Auth is designed to work either as a standalone product, or deeply integrated with the other Supabase products.
Postgres is at the heart of everything we do, and the Auth system follows this principle. We leverage Postgres' built-in Auth functionality wherever possible.
Here's a quick, 2 minute tour of the Auth features built-in to Supabase:
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/6ow_jW4epf8"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
## Authentication
You can authenticate your users in several ways:
@@ -38,64 +42,86 @@ You can authenticate your users in several ways:
- Social providers.
- Phone logins.
### Providers
### Providers
We provide a suite of Providers and login methods.
We provide a suite of Providers and login methods, as well as [Auth helpers](/docs/guides/auth/auth-helpers/).
<div class="container" style={{ padding: 0 }}>
<div class="row is-multiline">
{providers.map((x) => (
<div key={x.name} class="col col--6">
<Link class="card" to={x.href}>
<div class="card__body">
<div class="" style={{ display: 'flex', justifyContent: 'space-between', gap: 10 }}>
<ButtonCard
class="card"
to={useBaseUrl(x.href)}
title={x.name}
style={{ height: '100%' }}
>
<div class="button-card__inner">
<div
class=""
style={{
display: 'flex',
justifyContent: 'space-between',
gap: 10,
}}
>
{x.logo && <img src={x.logo} alt={x.name} width="20" />}
<p>{x.name}</p>
<p>
{x.official ? <span class={`badge badge--official`}>
Official
</span>:
<span class={`badge badge--unofficial`}>
Unofficial
</span>
}
{x.official ? (
<span class={`badge badge--official`}>Official</span>
) : (
<span class={`badge badge--unofficial`}>Unofficial</span>
)}
</p>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
<div class="code-block" style={{ width: '100%', display: 'flex', justifyContent: 'space-between', fontSize: '0.7rem' }}>
<div
class="code-block"
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
fontSize: '0.7rem',
}}
>
<span>Platform:</span>
<span>{x.platform.toString()}</span>
</div>
<div class="code-block" style={{ width: '100%', display: 'flex', justifyContent: 'space-between', fontSize: '0.7rem' }}>
<div
class="code-block"
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
fontSize: '0.7rem',
}}
>
<span>Self-Hosted:</span>
<span>{x.selfHosted.toString()}</span>
</div>
</div>
</div>
</Link>
</ButtonCard>
</div>
))}
</div>
</div>
### Configure third-party providers
### Simple interface
You can enable third-providers with the click of a button by navigating to Authentication > Settings > External OAuth Providers and inputting your `Client ID` and `Secret` for each.
You can enable third-party providers with the click of a button by navigating to Authentication > Settings > Auth Providers and inputting your `Client ID` and `Secret` for each.
![OAuth Logins.](/img/supabase-oauth-logins.png)
## Authorization
When you need granular authorization rules, nothing beats PostgreSQL's Row Level Security (RLS).
Policies are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs.
Get started with our [Row Level Security Guides](/docs/guides/auth/row-level-security).
### Row Level Security
Authentication only gets you so far. When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security (RLS)](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). Supabase makes it simple to turn RLS on and off.
@@ -109,7 +135,12 @@ Authentication only gets you so far. When you need granular authorization rules,
[Policies](https://www.postgresql.org/docs/current/sql-createpolicy.html) are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/policies-zoom2.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/policies-zoom2.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
With policies, your database becomes the rules engine. Instead of repetitively filtering your queries, like this ...
@@ -134,7 +165,6 @@ let { data, error } = await supabase.from('users').select('user_id, name')
// Still => { id: 'd0714948', name: 'Jane' }
```
### How It Works
1. A user signs up. Supabase creates a new user in the `auth.users` table.
@@ -145,14 +175,17 @@ let { data, error } = await supabase.from('users').select('user_id, name')
Supabase provides a special function in Postgres, `auth.uid()`, which extracts the user's UID from the JWT. This is especially useful when creating policies.
## User Management
Supabase makes it simple to manage your users.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/auth-zoom2.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/auth-zoom2.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
When users sign up, Supabase assigns them a unique ID. You can reference this ID anywhere in your database. For example, you might create a `profiles` table referencing `id` in the `auth.users` table using a `user_id` field.
@@ -160,7 +193,6 @@ When users sign up, Supabase assigns them a unique ID. You can reference this ID
Supabase provides the routes to [sign up](/docs/reference/javascript/auth-signup), [log in](/docs/reference/javascript/auth-signin),
[log out](/docs/reference/javascript/auth-signout), and manage users in your apps and websites.
## Next Steps
- Sign in: [app.supabase.com](https://app.supabase.com)
@@ -71,7 +71,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Configure your Services ID
@@ -40,7 +40,7 @@ Azure OAuth consists of four broad steps:
This will serve as the `client_id` when you make API calls to authenticate the user.
- Once your app has been registered, the client id can be found under the [list of app registrations](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) under the column titled "Application (client) ID".
- Once your app has been registered, the client id can be found under the [list of app registrations](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) under the column titled "Application (client) ID".
![Obtain the client id](/img/guides/auth-azure/azure-client-id.png)
@@ -52,10 +52,19 @@ This will serve as the `client_secret` when you make API calls to authenticate t
- Under "Essentials", click on "Client credentials".
- Navigate to the "Client secrets" tab and select "New client secret".
- Enter a description and choose your preferred expiry for the secret.
- Once the secret is generated, save the value (not the secret ID).
- Once the secret is generated, save the `value` (not the secret ID).
![Obtain the client secret](/img/guides/auth-azure/azure-client-secret.png)
## Obtain the Tenant URL
This will allow your users to use your custom Azure login page when logging in.
- Select the Directory (Tenant) ID value.
- The Azure Tenant URL should look like this: `https://login.microsoftonline.com/<tenant-id>`
![Obtain the tenant url](/img/guides/auth-azure/azure-tenant-url.png)
### Add login code to your client app
The JavaScript client code is documented in the [Supabase OAuth Reference](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers).
@@ -70,11 +79,14 @@ Add a function which you can call from a button, link, or UI element.
```js
async function signInWithAzure() {
const { user, session, error } = await supabase.auth.signIn({
provider: 'azure',
}, {
const { user, session, error } = await supabase.auth.signIn(
{
provider: 'azure',
},
{
scopes: 'email',
})
}
)
}
```
@@ -39,7 +39,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create a Bitbucket OAuth app
@@ -43,7 +43,12 @@ In the next step you require a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create a Discord Application
@@ -76,6 +81,12 @@ const { user, session, error } = await supabase.auth.signIn({
})
```
:::note
If you call `signIn()` when already logged in, Discord will prompt the user again for authorization.
:::
Add this function which you can call from a button, link, or UI element.
```js
@@ -96,7 +96,7 @@ async function signInWithEmail() {
```dart
Future<void> signInWithEmail() async {
await supabase.auth.signIn(
email: 'example@email.com',
email: 'example@email.com',
password: 'example-password'
);
}
@@ -47,7 +47,12 @@ The next step requires a callback URI, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Set up FaceBook Login for your Facebook App
@@ -48,7 +48,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Register a new OAuth application
@@ -39,7 +39,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create your GitLab Application
@@ -62,12 +62,17 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create your credentials
### Create your Google credentials
- Click `Credentials` at the left to go to the `Credentials` page
- Click `Credentials` at the left to go to the `Credentials` page on the Google Cloud Platform console.
- Click `Create Credentials` near the top then select `OAuth client ID`
- On the `Create OAuth client ID` page, select your application type. If you're not sure, choose `Web application`.
- Fill in your app name.
@@ -0,0 +1,297 @@
---
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.
<video width="99%" muted playsInline controls="true">
<source
src="https://supabase.com/images/blog/lw5-one-more/auth-ui-demo.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
## Set up Auth UI
Install the latest version of [supabase-js](/docs/reference/javascript/next/) and the Auth UI package:
```bash
npm install @supabase/supabase-js@rc @supabase/auth-ui-react
```
### Import the Auth component
Pass `supabaseClient` from `@supabase/supabase-js` as a prop to the component.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => <Auth supabaseClient={supabase} />
```
This renders the Auth component without any styling.
We recommend using one of the predefined themes to style the UI.
Import the theme you want to use and pass it to the `appearence.theme` prop.
```diff js title="/src/index.js"
import {
Auth,
// highlight-next-line
ThemeSupa
} from '@supabase/auth-ui-react'
const App = () => (
<Auth
supabaseClient={supabase}
// highlight-next-line
appearance={{ theme: ThemeSupa }}
/>
)
```
## Customization
There are several ways to customize Auth UI:
- Use one of the [predefined themes](#predefined-themes) that comes with Auth UI
- Extend a theme by [overriding the variable tokens](#override-themes) in a theme
- [Create your own theme](#create-theme)
- [Use your own CSS classes](#custom-css-classes)
- [Use inline styles](#custom-inline-styles)
- [Use your own labels](#custom-labels)
### Predefined themes
Auth UI comes with several themes to customize the appearance. Each predefined theme comes with at least two variations, a `default` variation, and a `dark` variation. You can switch between these themes using the `theme` prop. Import the theme you want to use and pass it to the `appearence.theme` prop.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
//highlight-next-line
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
// highlight-next-line
appearance={{ theme: ThemeSupa }}
/>
)
```
:::info
Currently there is only one predefined theme available, but we plan to add more.
:::
### Switch theme variations
Auth UI comes with two theme variations: `default` and `dark`. You can switch between these themes with the `theme` prop.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
appearance={{ theme: ThemeSupa }}
// highlight-next-line
theme="dark"
/>
)
```
If you don't pass a value to `theme` it uses the `"default"` theme. You can pass `"dark"` to the theme prop to switch to the `dark` theme. If your theme has other variations, use the name of the variation in this prop.
### Override themes
Auth UI themes can be overridden using variable tokens. See the [list of variable tokens](https://github.com/supabase-community/auth-ui/blob/main/packages/react/common/theming/Themes.tsx).
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
appearance={{
theme: ThemeSupa,
// highlight-start
variables: {
default: {
colors: {
brand: 'red',
brandAccent: 'darkred',
},
},
},
// highlight-end
}}
/>
)
```
If you created your own theme, you may not need to override any of the them.
### Create your own theme {#create-theme}
You can create your own theme by following the same structure within a `appearance.theme` property.
See the list of [tokens within a theme](https://github.com/supabase-community/auth-ui/blob/main/packages/react/common/theming/Themes.tsx).
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const customTheme = {
default: {
colors: {
brand: 'hsl(153 60.0% 53.0%)',
brandAccent: 'hsl(154 54.8% 45.1%)',
brandButtonText: 'white',
// ..
},
dark: {
colors: {
brandButtonText: 'white',
defaultButtonBackground: '#2e2e2e',
defaultButtonBackgroundHover: '#3e3e3e',
//..
},
},
// You can also add more theme variations with different names.
evenDarker: {
colors: {
brandButtonText: 'white',
defaultButtonBackground: '#1e1e1e',
defaultButtonBackgroundHover: '#2e2e2e',
//..
},
},
}
const App = () => (
<Auth
supabaseClient={supabase}
theme="default" // can also be "dark" or "evenDarker"
appearance={{ theme: customTheme}}
/>
)
```
You can swich between different variations of your theme with the ["theme" prop](#switch-theme-variations).
### Custom CSS classes {#custom-css-classes}
You can use custom CSS classes for the following elements:
`"button"`, `"container"`, `"anchor"`, `"divider"`, `"label"`, `"input"`, `"loader"`, `"message"`.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
appearance={{
className: {
anchor: 'my-awesome-anchor',
button: 'my-awesome-button',
//..
},
}}
/>
)
```
### Custom inline CSS {#custom-inline-styles}
You can use custom CSS inline styles for the following elements:
`"button"`, `"container"`, `"anchor"`, `"divider"`, `"label"`, `"input"`, `"loader"`, `"message"`.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
appearance={{
style: {
button: { background: 'red', color: 'white' },
anchor: { color: 'blue' },
//..
},
}}
/>
)
```
### Custom labels {#custom-labels}
You can use custom labels with `localization.variables`. See the [list of labels](https://github.com/supabase-community/auth-ui/blob/main/packages/react/common/lib/Localization/en.json) that can be overwritten.
```js title="/src/index.js"
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
const supabase = createClient(
'<INSERT PROJECT URL>',
'<INSERT PROJECT ANON API KEY>'
)
const App = () => (
<Auth
supabaseClient={supabase}
//highlight-start
localization={{
variables: {
sign_in: {
email_label: 'Your email address',
password_label: 'Your strong password',
},
},
}}
//highlight-end
/>
)
```
@@ -0,0 +1,55 @@
---
id: index
title: Auth Helpers
description: A collection of framework-specific Auth utilities for working with Supabase.
sidebar_label: Overview
---
import useBaseUrl from '@docusaurus/useBaseUrl'
import ButtonCard from '@site/src/components/ButtonCard'
A collection of framework-specific Auth utilities for working with Supabase.
<div class="container" style={{ padding: 0 }}>
<div class="row is-multiline">
{/* Auth UI */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/auth/auth-helpers/auth-ui')}
title={'Auth UI'}
description={'A pre-built React component for authenticating users.'}
style={{ height: '100%' }}
/>
</div>
{/* Next.js */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/auth/auth-helpers/nextjs')}
title={'Next.js'}
description={'Helpers for authenticating users in Next.js applications.'}
style={{ height: '100%' }}
/>
</div>
{/* SvelteKit */}
<div class="col col--4">
<ButtonCard
class="card"
to={useBaseUrl('/guides/auth/auth-helpers/sveltekit')}
title={'SvelteKit'}
description={'Helpers for authenticating users in SvelteKit applications.'}
style={{ height: '100%' }}
/>
</div>
</div>
</div>
## Status
The Auth Helpers are in `beta`. They are usable in their current state, but it's likely that there will be breaking changes.
## Additional Links
- [Source code](https://github.com/supabase/auth-helpers)
- [Known bugs and issues](https://github.com/supabase/auth-helpers/issues)
@@ -0,0 +1,319 @@
---
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.
## Installation
Using [npm](https://npmjs.org):
```sh
npm install @supabase/auth-helpers-nextjs
# Main components and hooks for React based frameworks (optional)
npm install @supabase/auth-helpers-react
```
Using [yarn](https://yarnpkg.com/):
```sh
yarn add @supabase/auth-helpers-nextjs
# Main components and hooks for React based frameworks (optional)
yarn add @supabase/auth-helpers-react
```
This library supports the following tooling versions:
- Node.js: `^10.13.0 || >=12.0.0`
- Next.js: `>=10`
## Getting Started
### Configuration
Set up the following env vars. For local development you can set them in a `.env.local` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/nextjs/.env.local.example).
```bash
# Find these in your Supabase project settings > API
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```
### Basic Setup
- Create an `auth` directory under the `/pages/api/` directory.
- Create a `[...supabase].js` file under the newly created `auth` directory.
The path to your dynamic API route file would be `/pages/api/auth/[...supabase].js`. Populate that file as follows:
```js
import { handleAuth } from '@supabase/auth-helpers-nextjs'
export default handleAuth({ logout: { returnTo: '/' } })
```
Executing `handleAuth()` creates the following route handlers under the hood that perform different parts of the authentication flow:
- `/api/auth/callback`: The `UserProvider` forwards the session details here every time `onAuthStateChange` fires on the client side. This is needed to set up the cookies for your application so that SSR works seamlessly.
- `/api/auth/user`: You can fetch user profile information in JSON format.
- `/api/auth/logout`: Your Next.js application logs out the user. You can optionally pass a `returnTo` parameter to return to a custom relative URL after logout, eg `/api/auth/logout?returnTo=/login`. This will overwrite the logout `returnTo` option specified `handleAuth()`
Wrap your `pages/_app.js` component with the `UserProvider` component:
```jsx
// pages/_app.js
import React from 'react'
import { UserProvider } from '@supabase/auth-helpers-react'
import { supabaseClient } from '@supabase/auth-helpers-nextjs'
export default function App({ Component, pageProps }) {
return (
<UserProvider supabaseClient={supabaseClient}>
<Component {...pageProps} />
</UserProvider>
)
}
```
You can now determine if a user is authenticated by checking that the `user` object returned by the `useUser()` hook is defined.
## Client-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work properly when fetching data client-side, you need to make sure to import the `{ supabaseClient }` from `# @supabase/auth-helpers-nextjs` and only run your query once the user is defined client-side in the `useUser()` hook:
```js
import { Auth } from '@supabase/ui'
import { useUser } from '@supabase/auth-helpers-react'
import { supabaseClient } from '@supabase/auth-helpers-nextjs'
import { useEffect, useState } from 'react'
const LoginPage = () => {
const { user, error } = useUser()
const [data, setData] = useState()
useEffect(() => {
async function loadData() {
const { data } = await supabaseClient.from('test').select('*')
setData(data)
}
// Only run query once user is logged in.
if (user) loadData()
}, [user])
if (!user)
return (
<>
{error && <p>{error.message}</p>}
<Auth
supabaseClient={supabaseClient}
providers={['google', 'github']}
socialLayout="horizontal"
socialButtonSize="xlarge"
/>
</>
)
return (
<>
<button onClick={() => supabaseClient.auth.signOut()}>Sign out</button>
<p>user:</p>
<pre>{JSON.stringify(user, null, 2)}</pre>
<p>client-side data fetching with RLS</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default LoginPage
```
### Server-side rendering (SSR) - withPageAuth
If you wrap your `getServerSideProps` with `withPageAuth` your props object will be augmented with the user object.
```js
// pages/profile.js
import { withPageAuth } from '@supabase/auth-helpers-nextjs'
export default function Profile({ user }) {
return <div>Hello {user.name}</div>
}
export const getServerSideProps = withPageAuth({ redirectTo: '/login' })
```
If there is no authenticated user, they will be redirect to your home page, unless you specify the `redirectTo` option.
You can pass in your own `getServerSideProps` method, the props returned from this will be merged with the
user props. You can also access the user session data by calling `getUser` inside of this method, eg:
```js
// pages/protected-page.js
import { withPageAuth, getUser } from '@supabase/auth-helpers-nextjs'
export default function ProtectedPage({ user, customProp }) {
return <div>Protected content</div>
}
export const getServerSideProps = withPageAuth({
redirectTo: '/foo',
async getServerSideProps(ctx) {
// Access the user object
const { user, accessToken } = await getUser(ctx)
return { props: { email: user?.email } }
},
})
```
### Server-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work in a server environment, you need to inject the request context into the supabase client:
```js
import {
User,
withPageAuth,
supabaseServerClient,
} from '@supabase/auth-helpers-nextjs'
export default function ProtectedPage({
user,
data,
}: {
user: User,
data: any,
}) {
return (
<>
<div>Protected content for {user.email}</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<pre>{JSON.stringify(user, null, 2)}</pre>
</>
)
}
export const getServerSideProps = withPageAuth({
redirectTo: '/',
async getServerSideProps(ctx) {
// Run queries with RLS on the server
const { data } = await supabaseServerClient(ctx).from('test').select('*')
return { props: { data } }
},
})
```
### Server-side data fetching to OAuth APIs using `provider_token`
When using third-party auth providers, sessions are initiated with an additional `provider_token` field which is persisted as an HTTPOnly cookie upon logging in to enabled usage on the server side. The `provider_token` can be used to make API requests to the OAuth provider's API endpoints on behalf of the logged-in user. In the following example, we fetch the user's full profile from the third-party API during SSR using their id and auth token:
```js
import { User, withPageAuth, getUser } from '@supabase/auth-helpers-nextjs'
interface Profile {
/* ... */
}
export default function ProtectedPage({
user,
data,
}: {
user: User,
profile: Profile,
}) {
return <div>Protected content</div>
}
export const getServerSideProps = withPageAuth({
redirectTo: '/',
async getServerSideProps(ctx) {
// Retrieve provider_token from cookies
const provider_token = ctx.req.cookies['sb-provider-token']
// Get logged in user's third-party id from metadata
const { user } = await getUser(ctx)
const userId = user?.user_metadata.provider_id
const profile: Profile = await (
await fetch(`https://api.example.com/users/${userId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${provider_token}`,
},
})
).json()
return { props: { profile } }
},
})
```
## Protecting API routes
Wrap an API Route to check that the user has a valid session. If they're not logged in the handler will return a
401 Unauthorized.
```js
// pages/api/protected-route.js
import {
withApiAuth,
supabaseServerClient,
} from '@supabase/auth-helpers-nextjs'
export default withApiAuth(async function ProtectedRoute(req, res) {
// Run queries with RLS on the server
const { data } = await supabaseServerClient({ req, res })
.from('test')
.select('*')
res.json(data)
})
```
If you visit `/api/protected-route` without a valid session cookie, you will get a 401 response.
## Protecting routes with [Nextjs Middleware](https://nextjs.org/docs/middleware)
As an alternative to protecting individual pages using `getServerSideProps` with `withPageAuth`, `withMiddlewareAuth` can be used from inside a `_middleware` file to protect an entire directory. In the following example, all requests to `/protected/*` will check whether a user is signed in, if successful the request will be forwarded to the destination route, otherwise the user will be redirected to `/login` (defaults to: `/`) with a 307 Temporary Redirect response status:
```ts
// pages/protected/_middleware.ts
import { withMiddlewareAuth } from '@supabase/auth-helpers-nextjs/middleware'
export const middleware = withMiddlewareAuth({ redirectTo: '/login' })
```
It is also possible to add finer granularity based on the user logged in. I.e. you can specify a promise to determine if a specific user has permission or not.
```ts
// pages/protected/_middleware.ts
import { withMiddlewareAuth } from '@supabase/auth-helpers-nextjs/dist/middleware'
export const middleware = withMiddlewareAuth({
redirectTo: '/login',
authGuard: {
isPermitted: async (user) => user.email?.endsWith('@example.com') ?? false,
redirectTo: '/insufficient-permissions',
},
})
```
## Migrating from @supabase/supabase-auth-helpers to @supabase/auth-helpers
This is a step by step guide on migrating away from the `@supabase/supabase-auth-helpers` to the newly released `@supabase/auth-helpers`.
1. Install `@supabase/supabase-js`, `@supabase/auth-helpers-nextjs` and `@supabase/auth-helpers-react` libraries from npm.
2. Replace all imports of `@supabase/supabase-auth-helpers/nextjs` in your project with `@supabase/auth-helpers-nextjs`.
3. Replace all imports of `@supabase/supabase-auth-helpers/react` in your project with `@supabase/auth-helpers-react`.
4. Replace all instances of `withAuthRequired` in any of your NextJS pages with `withPageAuth`.
5. Replace all instances of `withAuthRequired` in any of your NextJS API endpoints with `withApiAuth`.
6. Uninstall `@supabase/supabase-auth-helpers`.
## Additional Links
- [Auth Helpers Source code](https://github.com/supabase/auth-helpers)
- [Next.js example](https://github.com/supabase/auth-helpers/tree/main/examples/nextjs)
@@ -0,0 +1,309 @@
---
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.
## Installation
Using [npm](https://npmjs.org):
```sh
npm install @supabase/auth-helpers-sveltekit
# Main component for Svelte based frameworks (optional but recommended)
npm install @supabase/auth-helpers-svelte
```
Using [yarn](https://yarnpkg.com/):
```sh
yarn add @supabase/auth-helpers-sveltekit
# Main component for Svelte based frameworks (optional but recommended)
yarn add @supabase/auth-helpers-svelte
```
This library supports the following tooling versions:
- Node.js: `^16.15.0`
## Getting Started
### Configuration
Set up the fillowing env vars. For local development you can set them in a `.env` file. See an [example](https://github.com/supabase/auth-helpers/blob/main/examples/sveltekit/.env.example).
```bash
# Find these in your Supabase project settings > API
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
```
### SupabaseClient and SupaAuthHelper component setup
We will start off by creating a `db.ts` file inside of our `src/lib` directory. Now lets instantiate our `supabaseClient` by using our `createSupabaseClient` function from the `@supabase/auth-helpers-sveltekit` library.
```ts
// src/lib/db.ts
import { createSupabaseClient } from '@supabase/auth-helpers-sveltekit'
const { supabaseClient } = createSupabaseClient(
import.meta.env.VITE_SUPABASE_URL as string,
import.meta.env.VITE_SUPABASE_ANON_KEY as string
)
export { supabaseClient }
```
Edit your `__layout.svelte` file and add import the `SupaAuthHelper` component, the `supabaseClient` we just instantiated and the `session` store.
```html
// src/routes/__layout.svelte
<script>
import { session } from '$app/stores'
import { supabaseClient } from '$lib/db'
import { SupaAuthHelper } from '@supabase/auth-helpers-svelte'
</script>
<SupaAuthHelper {supabaseClient} {session}>
<slot />
</SupaAuthHelper>
```
### Hooks setup
Our `hooks.ts` file is where the heavy lifting of this library happens, we need to import our function to handle the sign in, signing out and cookie creation phase. we can import all the hooks using `handleAuth` function and destructure its returned data.
```ts
// src/hooks.ts
import { handleAuth } from '@supabase/auth-helpers-sveltekit'
import type { GetSession, Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
export const handle: Handle = sequence(...handleAuth())
export const getSession: GetSession = async (event) => {
const { user, accessToken, error } = event.locals
return {
user,
accessToken,
error,
}
}
```
These will create the handlers under the hood that perform different parts of the authentication flow:
- `/api/auth/callback`: The `UserHelper` forwards the session details here every time `onAuthStateChange` fires on the client side. This is needed to set up the cookies for your application so that SSR works seamlessly.
- `/api/auth/user`: You can fetch user profile information in JSON format.
- `/api/auth/logout`: You can logout the user.
### Typings
In order to get the most out of TypeScript and its intellisense, you should import our types into the `app.d.ts` type definition file that comes with your SvelteKit project.
```ts
// src/app.d.ts
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare namespace App {
interface UserSession {
user: import('@supabase/supabase-js').User
accessToken?: string
}
interface Locals extends UserSession {
error: import('@supabase/supabase-js').ApiError
}
interface Session extends UserSession {} // interface Platform {} // interface Stuff {}
}
```
### Signing out
This library has provided a dedicated endpoint for you to use to sign a user out. This endpoint will sign the user out of the Gotrue server, clear the cookies that were set when the user logged in and redirect the user to a configurable path.
The logout handler endpoint is `/api/auth/logout`, this will take a `GET` request which means it can be used as the href for a normal `a` tag in your html.
```html
<a href="/api/auth/logout">Sign out</a>
```
### Logout handler configuration
In your `src/hooks.ts` file the logout handler is already setup and you can configure the redirect path from here.
> By default the redirect path after logging out will be `/`.
```ts
export const handle = sequence(
...handleAuth({
logout: { returnTo: '/auth/signin' },
})
)
```
### Basic Setup
You can now determine if a user is authenticated on the client-side by checking that the `user` object returned by the `$session` store is defined.
```html
// example
<script>
import { session } from '$app/stores'
</script>
{#if !$session.user}
<h1>I am not logged in</h1>
{:else}
<h1>Welcome {$session.user.email}</h1>
<p>I am logged in!</p>
{/if}
```
## Client-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work properly when fetching data client-side, you need to make sure to import the `{ supabaseClient }` from `@supabase/auth-helpers-sveltekit` and only run your query once the user is defined client-side in the `$session`:
```html
<script>
import Auth from 'supabase-ui-svelte';
import { error, isLoading } from '@supabase/auth-helpers-svelte';
import { supabaseClient } from '$lib/db';
import { session } from '$app/stores';
let loadedData = [];
async function loadData() {
const { data } = await supabaseClient.from('test').select('*').single();
loadedData = data
}
$: {
if ($session.user && $session.user.id) {
loadData();
}
}
</script>
{#if !$session.user}
{#if $error}
<p>{$error.message}</p>
{/if}
<h1>{$isLoading ? `Loading...` : `Loaded!`}</h1>
<Auth
supabaseClient={supabaseClient}
providers={['google', 'github']}
/>
{:else}
<a href=="/api/auth/logout">Sign out</a>
<p>user:</p>
<pre>{JSON.stringify($session.user, null, 2)}</pre>
<p>client-side data fetching with RLS</p>
<pre>{JSON.stringify(loadedData, null, 2)}</pre>
{/if}
```
### Server-side data fetching with RLS
For [row level security](https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security) to work in a server environment, you need to inject the request context into the supabase client:
```html
<!-- src/routes/profile.svelte -->
<script>
export let user
export let data
</script>
<div>Protected content for {user.email}</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<pre>{JSON.stringify(user, null, 2)}</pre>
```
```ts
// src/routes/profile.ts
import {
supabaseServerClient,
withApiAuth,
} from '@supabase/auth-helpers-sveltekit'
import type { RequestHandler } from './__types/profile'
interface TestTable {
id: string
created_at: string
}
interface GetOutput {
user: User
data: TestTable[]
}
export const GET: RequestHandler<GetOutput> = async ({ locals }) =>
withApiAuth(
{
redirectTo: '/',
user: locals.user,
},
async () => {
const { data } = await supabaseServerClient(session.accessToken)
.from<TestTable>('test')
.select('*')
return {
body: {
user: locals.user,
data,
},
}
}
)
```
## Protecting API routes
Wrap an API Route to check that the user has a valid session. If they're not logged in the handler will return a
303 and redirect header.
```ts
// src/routes/api/protected-route.ts
import {
supabaseServerClient,
withApiAuth,
} from '@supabase/auth-helpers-sveltekit'
import type { RequestHandler } from './__types/protected-route'
interface TestTable {
id: string
created_at: string
}
interface GetOutput {
data: TestTable[]
}
export const GET: RequestHandler<GetOutput> = async ({ locals, request }) =>
withApiAuth({ user: locals.user }, async () => {
// Run queries with RLS on the server
const { data } = await supabaseServerClient(request)
.from('test')
.select('*')
return {
status: 200,
body: { data },
}
})
```
If you visit `/api/protected-route` without a valid session cookie, you will get a 303 response.
## Additional Links
- [Auth Helpers Source code](https://github.com/supabase/auth-helpers)
- [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)
@@ -11,7 +11,7 @@ To enable Keycloak Auth for your project, you need to set up an Keycloak OAuth a
## Overview
To get started with Keycloak, you can run it in a docker container with: `docker run -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -p 8080:8080 jboss/keycloak:latest`
To get started with Keycloak, you can run it in a docker container with: `docker run -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -p 8080:8080 jboss/keycloak:latest`
This guide will be assuming that you are running keycloak in a docker container as described in the command above.
@@ -28,13 +28,13 @@ Keycloak OAuth consists of five broad steps:
### Access your Keycloak Admin console
- Login by visiting [`http://localhost:8080`](http://localhost:8080) and clicking on "Administration Console".
- Login by visiting [`http://localhost:8080`](http://localhost:8080) and clicking on "Administration Console".
### Create a Keycloak Realm
- Once you've logged in to the Keycloak console, you can add a realm from the side panel. The default realm should be named "Master".
- After you've added a new realm, you can retrieve the `issuer` from the "OpenID Endpoint Configuration" endpoint. The `issuer` will be used as the `Keycloak URL`.
- You can find this endpoint from the realm settings under the "General Tab" or visit [`http://localhost:8080/auth/realms/my_realm_name/.well-known/openid-configuration`](http://localhost:8080/auth/realms/my_realm_name/.well-known/openid-configuration)
- After you've added a new realm, you can retrieve the `issuer` from the "OpenID Endpoint Configuration" endpoint. The `issuer` will be used as the `Keycloak URL`.
- You can find this endpoint from the realm settings under the "General Tab" or visit [`http://localhost:8080/realms/my_realm_name/.well-known/openid-configuration`](http://localhost:8080/realms/my_realm_name/.well-known/openid-configuration)
![Add a Keycloak Realm.](/img/guides/auth-keycloak/keycloak-create-realm.png)
@@ -47,6 +47,7 @@ The "Client ID" of the created client will serve as the `client_id` when you mak
### Client Settings
After you've created the client successfully, ensure that you set the following settings:
1. The "Client Protocol" should be set to "openid-connect".
2. The "Access Type" should be set to "confidential".
3. The "Valid Redirect URIs" should be set to: `https://<project-ref>.supabase.co/auth/v1/callback`.
@@ -57,7 +58,7 @@ After you've created the client successfully, ensure that you set the following
### Obtain the Client Secret
This will serve as the `client_secret` when you make API calls to authenticate the user.
Under the "Credentials" tab, the `Secret` value will be used as the `client secret`.
Under the "Credentials" tab, the `Secret` value will be used as the `client secret`.
![Obtain the client secret](/img/guides/auth-keycloak/keycloak-client-secret.png)
@@ -89,7 +90,7 @@ async function signout() {
}
```
## Resources
## Resources
- You can find the keycloak openid endpoint configuration under the realm settings.
![Keycloak OpenID Endpoint Configuration](/img/guides/auth-keycloak/keycloak-openid-endpoint-config.png)
![Keycloak OpenID Endpoint Configuration](/img/guides/auth-keycloak/keycloak-openid-endpoint-config.png)
@@ -14,7 +14,7 @@ To enable LinkedIn Auth for your project, you need to set up a LinkedIn OAuth ap
Setting up LinkedIn logins for your application consists of 3 parts:
- Create and configure a LinkedIn Project and App on the [LinkedIn Developer Dashboard](https://www.linkedin.com/developers/apps).
- Add your LinkedIn `API Key` and `API Secret Key` to your [Supabase Project](https://app.supabase.com).
- Add your LinkedIn `client_id` and `client_secret` to your [Supabase Project](https://app.supabase.com).
- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js).
## Steps
@@ -39,7 +39,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create a LinkedIn OAuth app
@@ -60,7 +65,7 @@ The next step requires a callback URL, which looks like this:
- Click `Settings` from the list to go to the `Authentication Settings` page.
- Enter the final (hosted) URL of your app under `Site URL` (this is important).
- Under `External OAuth Providers` turn `LinkedIn Enabled` to ON.
- Enter your `API Key` (`client_id`) and `API Secret Key` (`client_secret`) saved in the previous step.
- Enter your `client_id` and `client_secret` saved in the previous step.
- Click `Save`.
### Add login code to your client app
@@ -40,7 +40,7 @@ This is the number that will be receiving the SMS OTPs.
![Get your API Keys](/img/guides/auth-messagebird/2.png)
Navigate to the [dashboard settings](https://dashboard.messagebird.com/en/settings/sms) to set the default originator. The messagebird originator is the name or number from which the message is sent.
Navigate to the [dashboard settings](https://dashboard.messagebird.com/en/settings/sms) to set the default originator. The messagebird originator is the name or number from which the message is sent.
For more information, you can refer to the messagebird article on choosing an originator [here](https://support.messagebird.com/hc/en-us/articles/115002628665-Choosing-an-originator)
![Set the default originator](/img/guides/auth-messagebird/3.png)
@@ -59,9 +59,10 @@ You should see an option to enable Phone Signup.
Toggle it on, and copy the 2 values over from the messagebird dashboard. Click save.
Note: If you use the Test API Key, the OTP will not be delivered to the mobile number specified but messagebird will log the response in the dashboard.
If the Live API Key is used instead, the OTP will be delivered and there will be a deduction in your free credits.
If the Live API Key is used instead, the OTP will be delivered and there will be a deduction in your free credits.
<!-- TODO: Add screenshot of UI -->
Plugin MessageBird credentials
Now the backend should be setup, we can proceed to add our client-side code!
@@ -34,6 +34,7 @@ Setting up Notion logins for your application consists of 3 parts:
![notion.so](/img/guides/auth-notion/notion-developer.png)
### Add the redirect uri
- After selecting "Public integration", you should see an option to add "Redirect URIs".
![notion.so](/img/guides/auth-notion/notion-redirect-uri.png)
@@ -49,7 +50,12 @@ You can retrieve the redirect uri with the following steps:
Your redirect uri should look like the following: `https://<project-ref>.supabase.co/auth/v1/callback`
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Add your Notion credentials into your Supabase Project
@@ -39,7 +39,12 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source
src="/docs/videos/api/api-url-and-key.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
### Create a Slack OAuth app
@@ -73,7 +78,7 @@ Under `Redirect URLs`:
- Click `Settings` from the list to go to the `Authentication Settings` page.
- Enter the final (hosted) URL of your app under `Site URL` (this is important).
- Under `External OAuth Providers` turn `Slack Enabled` to ON.
- Enter your `API Key` (`client_id`) and `API Secret Key` (`client_secret`) saved in the previous step.
- Enter your `Client ID` (`client_id`) and `Client Secret` (`client_secret`) saved in the previous step.
- Click `Save`.
### Add login code to your client app
Loaded 100 of 2095 files, more files were not shown because too many files have changed in this diff. Show more