chore: activate spelling and admonitions lints for docs (#33292)

This commit is contained in:
Charis authored and GitHub committed 2025-02-04 13:18:31 -05:00
1 parent 8112d6d1bb
commit 2d55512553
188 files changed
+951 -824

No files matched your search

+3 -3
View File
@@ -38,10 +38,10 @@ jobs:
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: 6435a4cd1eeea7c2bbd343731de7e8a5127cb2d1
key: 0be447eba738c3fd56698eff8ad01fa56c2391d7
- name: install linter
if: steps.cache-cargo.outputs.cache-hit != 'true'
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 6435a4cd1eeea7c2bbd343731de7e8a5127cb2d1
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev 0be447eba738c3fd56698eff8ad01fa56c2391d7
- name: install reviewdog
uses: reviewdog/action-setup@3f401fe1d58fe77e10d665ab713057375e39b887 # v1.3.0
with:
@@ -54,7 +54,7 @@ jobs:
run: |
set -o pipefail
git diff --name-only origin/$BASE_REF HEAD \
| { grep -E "^apps/docs/content/guides/" || test $? = 1; } \
| { grep -E "^apps/docs/content/" || test $? = 1; } \
| xargs -r supa-mdx-lint --format rdf \
| reviewdog -f=rdjsonl -reporter=github-pr-review
- name: run linter on push or workflow dispatch
+1 -1
View File
@@ -74,7 +74,7 @@ const HomePageCover = (props) => {
href: '/guides/getting-started/quickstarts/vue',
},
{
tooltip: 'NuxtJS',
tooltip: 'Nuxt',
icon: '/docs/img/icons/nuxt-icon',
href: '/guides/getting-started/quickstarts/nuxtjs',
},
@@ -258,7 +258,7 @@ export const gettingstarted: NavMenuConstant = {
items: [
{ name: 'Next.js', url: '/guides/getting-started/quickstarts/nextjs' },
{ name: 'React', url: '/guides/getting-started/quickstarts/reactjs' },
{ name: 'NuxtJS', url: '/guides/getting-started/quickstarts/nuxtjs' },
{ name: 'Nuxt', url: '/guides/getting-started/quickstarts/nuxtjs' },
{ name: 'Vue', url: '/guides/getting-started/quickstarts/vue' },
{ name: 'Hono', url: '/guides/getting-started/quickstarts/hono' },
{ name: 'Flutter', url: '/guides/getting-started/quickstarts/flutter' },
@@ -277,7 +277,7 @@ There are various ways to improve your pgvector performance. Here are some tips:
It's useful to execute a few thousand “warm-up” queries before going into production. This helps help with RAM utilization. This can also help to determine that you've selected the right compute size for your workload.
### Finetune index parameters
### Fine-tune index parameters
You can increase the Requests per Second by increasing `m` and `ef_construction` or `lists`. This also has an important caveat: building the index takes longer with higher values for these parameters.
@@ -301,7 +301,7 @@ You can increase the Requests per Second by increasing `m` and `ef_construction`
</TabPanel>
<TabPanel id="ivfflat" label="IVFFlat">
<Image
alt="multi database"
src={{
@@ -80,9 +80,9 @@ To start quicker you may use Supabase CLI to spin everything up locally as it al
supabase start
```
This will pull all docker images and run supabase stack in docker on your local machine. It will also apply all the necessary migrations to set the whole thing up. You can then use your local setup the same way, just export the environment variables and follow to the next steps.
This will pull all docker images and run Supabase stack in docker on your local machine. It will also apply all the necessary migrations to set the whole thing up. You can then use your local setup the same way, just export the environment variables and follow to the next steps.
Using `supabase-cli` is not required and you can use any other docker image or hosted version of PostgresDB that includes `pgvector`. Just make sure you run migrations from `examples/providers/supabase/migrations/20230414142107_init_pg_vector.sql`.
Using `supabase-cli` is not required and you can use any other docker image or hosted version of Postgres that includes `pgvector`. Just make sure you run migrations from `examples/providers/supabase/migrations/20230414142107_init_pg_vector.sql`.
### Step 5: Obtain OpenAI API key
@@ -6,7 +6,7 @@ breadcrumb: 'AI Examples'
Supabase provides a [Headless Search Toolkit](https://github.com/supabase/headless-vector-search) for adding "Generative Q&A" to your documentation. The toolkit is "headless", so that you can integrate it into your existing website and style it to match your website theme.
You can see how this works with the Supabase docs. Just hit `cmd+k` and "ask" for something like "what are the features of supabase?". You will see that the response is streamed back, using the information provided in the docs:
You can see how this works with the Supabase docs. Just hit `cmd+k` and "ask" for something like "what are the features of Supabase?". You will see that the response is streamed back, using the information provided in the docs:
![headless search](/docs/img/ai/headless-search/headless.png)
@@ -8,9 +8,9 @@ subtitle: 'Implement image search with the OpenAI CLIP Model and Supabase Vector
The [OpenAI CLIP Model](https://github.com/openai/CLIP) was trained on a variety of (image, text)-pairs. You can use the CLIP model for:
- Text-to-Image / Image-To-Text / Image-to-Image / Text-to-Text Search
- You can fine-tune it on your own image and text data with the regular SentenceTransformers training code.
- You can fine-tune it on your own image and text data with the regular `SentenceTransformers` training code.
[SentenceTransformers](https://www.sbert.net/examples/applications/image-search/README.html) provides models that allow you to embed images and text into the same vector space. You can use this to find similar images as well as to implement image search.
[`SentenceTransformers`](https://www.sbert.net/examples/applications/image-search/README.html) provides models that allow you to embed images and text into the same vector space. You can use this to find similar images as well as to implement image search.
You can find the full application code as a Python Poetry project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/image_search#image-search-with-supabase-vector).
@@ -72,7 +72,7 @@ DB_CONNECTION = "postgresql://postgres:postgres@localhost:54322/postgres"
## Create embeddings for your images
In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/image_search/images) or you can find license free images on [unsplash](https://unsplash.com).
In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/image_search/images) or you can find license free images on [Unsplash](https://unsplash.com).
Next, create a `seed` method, which will create a new Supabase Vector Collection, generate embeddings for your images, and upsert the embeddings into your database:
@@ -130,7 +130,7 @@ seed = "image_search.main:seed"
search = "image_search.main:search"
```
After activating the virtual environtment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your local database by visiting the local Supabase dashboard at [localhost:54323](http://localhost:54323/project/default/editor), selecting the `vecs` schema, and the `image_vectors` database.
After activating the virtual environment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your local database by visiting the local Supabase dashboard at [localhost:54323](http://localhost:54323/project/default/editor), selecting the `vecs` schema, and the `image_vectors` database.
## Perform an image search from a text query
@@ -297,7 +297,7 @@ With our database set up, we need to process and store all `.mdx` files in the `
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Run script at build time">
Include the script in your `package.json` script commands to enable Vercel to automaticall run it at build time.
Include the script in your `package.json` script commands to enable Vercel to automatically run it at build time.
</StepHikeCompact.Details>
@@ -91,7 +91,7 @@ You should see a GPT response come back from OpenAI!
## Deploy
Deploy your function to the cloud by runnning:
Deploy your function to the cloud by running:
```bash
supabase functions deploy --no-verify-jwt openai
@@ -84,7 +84,7 @@ bedrock_client = boto3.client(
## Create embeddings for your images
In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search/images) or you can find license free images on [unsplash](https://unsplash.com).
In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search/images) or you can find license free images on [Unsplash](https://unsplash.com).
To send images to the Amazon Bedrock API we need to need to encode them as `base64` strings. Create the following helper methods:
@@ -188,7 +188,7 @@ seed = "image_search.main:seed"
search = "image_search.main:search"
```
After activating the virtual environtment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](https://supabase.com/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table.
After activating the virtual environment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](https://supabase.com/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table.
## Perform an image search from a text query
@@ -29,7 +29,7 @@ On the other hand, if you need to scale your application, you will need to [crea
`pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
<Image
alt="dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute addon"
alt="dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute add-on"
src={{
light: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--light.png',
dark: '/docs/img/ai/going-prod/dbpedia-ivfflat-vs-hnsw-4xl--dark.png',
@@ -83,12 +83,12 @@ You can find more examples of how `lists` and `probes` constants affect accuracy
First, a few generic tips which you can pick and choose from:
1. The Supabase managed platform will automatically optimize Postgres configs for you based on your compute addon. But if you self-host, consider **adjusting your Postgres config** based on RAM & CPU cores. See [example optimizations](https://gist.github.com/egor-romanov/323e2847851bbd758081511785573c08) for more details.
1. The Supabase managed platform will automatically optimize Postgres configs for you based on your compute add-on. But if you self-host, consider **adjusting your Postgres config** based on RAM & CPU cores. See [example optimizations](https://gist.github.com/egor-romanov/323e2847851bbd758081511785573c08) for more details.
2. Prefer `inner-product` to `L2` or `Cosine` distances if your vectors are normalized (like `text-embedding-ada-002`). If embeddings are not normalized, `Cosine` distance should give the best results with an index.
3. **Pre-warm your database.** Implement the warm-up technique before transitioning to production or running benchmarks.
- Use [pg_prewarm](https://www.postgresql.org/docs/current/pgprewarm.html) to load the index into RAM `select pg_prewarm('vecs.docs_vec_idx');`. This will help to avoid cold cache issues.
- Execute 10,000 to 50,000 "warm-up" queries before each benchmark/prod. This will help to utilize cache and buffers more efficiently.
4. **Establish your workload.** Finetune `m` and `ef_construction` or `lists` constants for the pgvector index to accelerate your queries (at the expense of a slower build times). For instance, for benchmarks with 1,000,000 OpenAI embeddings, we set `m` and `ef_construction` to 32 and 80, and it resulted in 35% higher QPS than 24 and 56 values respectively.
4. **Establish your workload.** Fine-tune `m` and `ef_construction` or `lists` constants for the pgvector index to accelerate your queries (at the expense of a slower build times). For instance, for benchmarks with 1,000,000 OpenAI embeddings, we set `m` and `ef_construction` to 32 and 80, and it resulted in 35% higher QPS than 24 and 56 values respectively.
5. **Benchmark your own specific workloads.** Doing this during cache warm-up helps gauge the best value for the index build parameters, balancing accuracy with queries per second (QPS).
## Going into production
@@ -5,7 +5,7 @@ subtitle: 'Learn how to integrate Supabase with LlamaIndex, a data framework for
breadcrumb: 'AI Integrations'
---
This guide will walk you through a basic example using the LlamaIndex [SupabaseVectorStore](https://github.com/supabase/supabase/blob/master/examples/ai/llamaindex/llamaindex.ipynb).
This guide will walk you through a basic example using the LlamaIndex [`SupabaseVectorStore`](https://github.com/supabase/supabase/blob/master/examples/ai/llamaindex/llamaindex.ipynb).
<DatabaseSetup />
@@ -66,5 +66,5 @@ You can view the inserted items in the [Table Editor](https://supabase.com/dashb
## Resources
- Visit the LlamaIndex + SupabaseVectorStore [docs](https://gpt-index.readthedocs.io/en/latest/examples/vector_stores/SupabaseVectorIndexDemo.html)
- Visit the LlamaIndex + `SupabaseVectorStore` [docs](https://gpt-index.readthedocs.io/en/latest/examples/vector_stores/SupabaseVectorIndexDemo.html)
- Visit the official LlamaIndex [repo](https://github.com/jerryjliu/llama_index/)
+1 -1
View File
@@ -147,7 +147,7 @@ export const run = async () => {
### Advanced metadata filtering
You can also use query builder-style filtering ([similar to how the Supabase JavaScript library works](https://supabase.com/docs/reference/javascript/using-filters)) instead of passing an object. Note that since the filter properties will be in the metadata column, you need to use arrow operators (`->` for integer or `->>` for text) as defined in [Postgrest API documentation](https://postgrest.org/en/stable/references/api/tables_views.html?highlight=operators#json-columns) and specify the data type of the property (e.g. the column should look something like `metadata->some_int_value::int`).
You can also use query builder-style filtering ([similar to how the Supabase JavaScript library works](https://supabase.com/docs/reference/javascript/using-filters)) instead of passing an object. Note that since the filter properties will be in the metadata column, you need to use arrow operators (`->` for integer or `->>` for text) as defined in [PostgREST API documentation](https://postgrest.org/en/stable/references/api/tables_views.html?highlight=operators#json-columns) and specify the data type of the property (e.g. the column should look something like `metadata->some_int_value::int`).
```js
import { SupabaseFilterRPCCall, SupabaseVectorStore } from 'langchain/vectorstores/supabase'
@@ -109,7 +109,7 @@ Let's build an Edge Function that will accept an input string and generate an em
Note the two options we pass to `session.run()`:
- `mean_pool`: The first option sets `pooling` to `mean`. Pooling referes to how token-level embedding representations are compressed into a single sentence embedding that reflects the meaning of the entire sentence. Average pooling is the most common type of pooling for sentence embeddings.
- `mean_pool`: The first option sets `pooling` to `mean`. Pooling refers to how token-level embedding representations are compressed into a single sentence embedding that reflects the meaning of the entire sentence. Average pooling is the most common type of pooling for sentence embeddings.
- `normalize`: The second option tells to normalize the embedding vector so that it can be used with distance measures like dot product. A normalized vector means its length (magnitude) is 1 - also referred to as a unit vector. A vector is normalized by dividing each element by the vector's length (magnitude), which maintains its direction but changes its length to 1.
</StepHikeCompact.Details>
@@ -50,7 +50,7 @@ on document_sections for select to authenticated using (
);
```
<Admonition>
<Admonition type="tip">
In this example, the current user is determined using the built-in `auth.uid()` function when the query is executed through your project's auto-generated [REST API](/docs/guides/api). If you are connecting to your Supabase database through a direct Postgres connection, see [Direct Postgres Connection](#direct-postgres-connection) below for directions on how to achieve the same access control.
@@ -117,7 +117,7 @@ RLS is latency-sensitive, so extra caution should be taken before implementing t
</Admonition>
<Admonition>
<Admonition type="tip">
For data sources other than Postgres, see [Foreign Data Wrappers](/docs/guides/database/extensions/wrappers/overview) for a list of external sources supported today. If your data lives in a source not provided in the list, please contact [support](https://supabase.com/dashboard/support/new) and we'll be happy to discuss your use case.
@@ -161,7 +161,7 @@ import foreign schema public limit to (users, documents)
from server foreign_server into external;
```
<Admonition>
<Admonition type="tip">
This example maps the `authenticated` role in Supabase to the `postgres` user in the external DB. In production, it's best to create a custom user on the external DB that has the minimum permissions necessary to access the information you need.
@@ -224,7 +224,7 @@ where document_sections.embedding <#> embedding < -match_threshold
order by document_sections.embedding <#> embedding;
```
<Admonition>
<Admonition type="caution">
You might be tempted to discard RLS completely and simply filter by user within the `where` clause. Though this will work, we recommend RLS as a general best practice since RLS is always applied even as new queries and application logic is introduced in the future.
@@ -61,7 +61,7 @@ create table documents (
In the above SQL snippet, we create a `documents` table with a column called `embedding` (note this is just a regular Postgres column - you can name it whatever you like). We give the `embedding` column a `vector` data type with 384 dimensions. Change this to the number of dimensions produced by your embedding model. For example, if you are [generating embeddings](/docs/guides/ai/quickstarts/generate-text-embeddings) using the open source [`gte-small`](https://huggingface.co/Supabase/gte-small) model, you would set this number to 384 since that model produces 384 dimensions.
<Admonition>
<Admonition type="tip">
In general, embeddings with fewer dimensions perform best. See our [analysis on fewer dimensions in pgvector](https://supabase.com/blog/fewer-dimensions-are-better-pgvector).
@@ -155,7 +155,7 @@ const { data: documents } = await supabaseClient.rpc('match_documents', {
In this example `embedding` would be another embedding you wish to compare against your table of pre-generated embedding documents. For example if you were building a search engine, every time the user submits their query you would first generate an embedding on the search query itself, then pass it into the above `rpc()` function to match.
<Admonition>
<Admonition type="tip">
Be sure to use embeddings produced from the same embedding model when calculating distance. Comparing embeddings from two different models will produce no meaningful result.
@@ -105,9 +105,9 @@ curl '<SUPABASE_URL>/rest/v1/todos' \
</TabPanel>
</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()`](/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).
@@ -258,7 +258,7 @@ jobs:
branch: ${{ github.ref }}
```
Alternatively, you can use a community-supported GitHub action: [generate-supabase-db-types-github-action](https://github.com/lyqht/generate-supabase-db-types-github-action).
Alternatively, you can use a community-supported GitHub action: [`generate-supabase-db-types-github-action`](https://github.com/lyqht/generate-supabase-db-types-github-action).
## Resources
+1 -1
View File
@@ -66,7 +66,7 @@ const { data, error } = await supabase
## Resources
- [Supabase - Get started for free](https://supabase.com)
- [Postgrest Operators](https://postgrest.org/en/stable/api.html#operators)
- [PostgREST Operators](https://postgrest.org/en/stable/api.html#operators)
- [Supabase API: JavaScript select](/docs/reference/javascript/select)
- [Supabase API: JavaScript modifiers](/docs/reference/javascript/using-modifiers)
- [Supabase API: JavaScript filters](/docs/reference/javascript/using-filters)
+1 -1
View File
@@ -7,7 +7,7 @@ description: 'Translate SQL queries to HTTP requests and Supabase client code'
Sometimes it's challenging to translate SQL queries to the equivalent [PostgREST](https://postgrest.org/) request or Supabase client code. Use this tool to help with this translation.
<Admonition type="info">
<Admonition type="note">
PostgREST supports a subset of SQL, so not all SQL queries will translate.
@@ -189,7 +189,7 @@ response = supabase.auth.update_user({
>
<TabPanel id="js" label="JavaScript">
You can use the [`linkIdentity()`](/docs/reference/javascript/auth-linkidentity) method to link an oauth identity to the anonymous user.
You can use the [`linkIdentity()`](/docs/reference/javascript/auth-linkidentity) method to link an OAuth identity to the anonymous user.
```js
const { data, error } = await supabase.auth.linkIdentity({ provider: 'google' })
@@ -216,7 +216,7 @@ try await supabase.auth.linkIdentity(provider: .google)
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
You can use the [`linkIdentity()`](/docs/reference/kotlin/auth-linkidentity) method to link an oauth identity to the anonymous user.
You can use the [`linkIdentity()`](/docs/reference/kotlin/auth-linkidentity) method to link an OAuth identity to the anonymous user.
```kotlin
supabase.auth.linkIdentity(Google)
@@ -225,7 +225,7 @@ supabase.auth.linkIdentity(Google)
</TabPanel>
<TabPanel id="python" label="Python">
You can use the [`link_identity()`](/docs/reference/python/auth-linkidentity) method to link an oauth identity to the anonymous user.
You can use the [`link_identity()`](/docs/reference/python/auth-linkidentity) method to link an OAuth identity to the anonymous user.
```python
response = supabase.auth.link_identity({'provider': 'google'})
@@ -250,7 +250,7 @@ to authenticated
using ( true );
```
<Admonition variant="note" label="Use restrictive policies">
<Admonition type="note" label="Use restrictive policies">
RLS policies are permissive by default, which means that they are combined using an "OR" operator when multiple policies are applied. It is important to construct restrictive policies to ensure that the checks for an anonymous user are always enforced when combined with other policies.
@@ -313,7 +313,7 @@ async function resolveDataConflicts(anonymousUserId, existingUserId) {
## Abuse prevention and rate limits
Since anonymous users are stored in your database, bad actors can abuse the endpoint to increase your database size drastically. It is strongly recommended to [enable invisible Captcha or Cloudflare Turnstile](/docs/guides/auth/auth-captcha) to prevent abuse for anonymous sign-ins. An IP-based rate limit is enforced at 30 requests per hour which can be modified in your [dashboard](/dashboard/project/_/auth/rate-limits). You can refer to the full list of rate limits [here](/docs/guides/platform/going-into-prod#rate-limiting-resource-allocation--abuse-prevention).
Since anonymous users are stored in your database, bad actors can abuse the endpoint to increase your database size drastically. It is strongly recommended to [enable invisible CAPTCHA or Cloudflare Turnstile](/docs/guides/auth/auth-captcha) to prevent abuse for anonymous sign-ins. An IP-based rate limit is enforced at 30 requests per hour which can be modified in your [dashboard](/dashboard/project/_/auth/rate-limits). You can refer to the full list of rate limits [here](/docs/guides/platform/going-into-prod#rate-limiting-resource-allocation--abuse-prevention).
## Automatic cleanup
+11 -11
View File
@@ -41,13 +41,13 @@ In the Settings page, look for the **Sitekey** section and copy the key.
## Enable CAPTCHA protection for your Supabase project
Navigate to the **[Auth](https://supabase.com/dashboard/project/_/settings/auth)** section of your Project Settings in the Supabase Dashboard and find the **Enable Captcha protection** toggle under Settings > Authentication > Bot and Abuse Protection > Enable Captcha protection.
Navigate to the **[Auth](https://supabase.com/dashboard/project/_/settings/auth)** section of your Project Settings in the Supabase Dashboard and find the **Enable CAPTCHA protection** toggle under Settings > Authentication > Bot and Abuse Protection > Enable CAPTCHA protection.
Select your CAPTCHA provider from the dropdown, enter your Captcha **Secret key**, and click **Save**.
Select your CAPTCHA provider from the dropdown, enter your CAPTCHA **Secret key**, and click **Save**.
## Add the CAPTCHA frontend component
The frontend requires some changes to provide the captcha on-screen for the user. This example uses React and the corresponding Captcha React component, but both Captcha providers can be used with any JavaScript framework.
The frontend requires some changes to provide the CAPTCHA on-screen for the user. This example uses React and the corresponding CAPTCHA React component, but both CAPTCHA providers can be used with any JavaScript framework.
<Tabs
scrollable
@@ -77,13 +77,13 @@ Let's create a empty state to store our `captchaToken`
const [captchaToken, setCaptchaToken] = useState()
```
Now lets add the HCaptcha component to the JSX section of our code
Now lets add the `HCaptcha` component to the JSX section of our code
```jsx
<HCaptcha />
```
We will pass it the sitekey we copied from the hCaptcha website as a property along with a onVerify property which takes a callback function. This callback function will have a token as one of its properties. Let's set the token in the state using `setCaptchaToken`
We will pass it the sitekey we copied from the hCaptcha website as a property along with a `onVerify` property which takes a callback function. This callback function will have a token as one of its properties. Let's set the token in the state using `setCaptchaToken`
```jsx
<HCaptcha
@@ -94,7 +94,7 @@ We will pass it the sitekey we copied from the hCaptcha website as a property al
/>
```
Now lets use the captcha token we receive in our Supabase signUp function.
Now lets use the CAPTCHA token we receive in our Supabase signUp function.
```jsx
await supabase.auth.signUp({
@@ -104,9 +104,9 @@ await supabase.auth.signUp({
})
```
We will also need to reset the captcha challenge after we have made a call to the function above.
We will also need to reset the CAPTCHA challenge after we have made a call to the function above.
Create a ref to use on our HCaptcha component.
Create a ref to use on our `HCaptcha` component.
```jsx
const captcha = useRef()
@@ -136,7 +136,7 @@ In order to test that this works locally we will need to use something like [ngr
<TabPanel id="turnstile-2" label="Turnstile">
The frontend requires some changes to provide the captcha on-screen for the user. Turnstile can be used with any JavaScript framework but we'll use React and the Turnstile React component for this example.
The frontend requires some changes to provide the CAPTCHA on-screen for the user. Turnstile can be used with any JavaScript framework but we'll use React and the Turnstile React component for this example.
Install @marsidev/react-turnstile in your project as a dependency.
@@ -183,9 +183,9 @@ await supabase.auth.signUp({
})
```
To test locally, you will need to add localhost to the domain whitelist as per the [Cloudflare docs](https://developers.cloudflare.com/turnstile/reference/testing/)
To test locally, you will need to add localhost to the domain allowlist as per the [Cloudflare docs](https://developers.cloudflare.com/turnstile/reference/testing/)
</TabPanel>
</Tabs>
Run the application and you should now be provided with a captcha challenge.
Run the application and you should now be provided with a CAPTCHA challenge.
@@ -5,7 +5,7 @@ description: 'A prebuilt, customizable React component for authenticating users.
sitemapPriority: 0.5
---
<Admonition type="warning">
<Admonition type="caution">
As of 7th Feb 2024, [this repository](https://github.com/supabase-community/auth-ui) is no longer maintained by the Supabase Team. At the moment, the team does not have capacity to give the expected level of care to this repository. We may revisit Auth UI in the future but regrettably have to leave it on hold for now as we focus on other priorities such as improving the Server-Side Rendering (SSR) package and advanced Auth primitives.
@@ -444,7 +444,7 @@ A full list of the available variables is below:
| `phone_input_label` | Phone number |
| `phone_input_placeholder` | Your phone number |
| `token_input_label` | Token |
| `token_input_placeholder` | Your Otp token |
| `token_input_placeholder` | Your OTP token |
| `button_label` | Verify token |
| `loading_button_label` | Signing in ... |
@@ -36,9 +36,9 @@ void main() async {
### Email Auth
Use a SupaEmailAuth widget to create an email and password signin and signup form. It also contains a button to toggle to display a forgot password form.
Use a `SupaEmailAuth` widget to create an email and password signin and signup form. It also contains a button to toggle to display a forgot password form.
You can pass metadataFields to add additional fields to the form to pass as metadata to Supabase.
You can pass `metadataFields` to add additional fields to the form to pass as metadata to Supabase.
```dart
SupaEmailAuth(
@@ -63,7 +63,7 @@ SupaEmailAuth(
### Magic link Auth
Use SupaMagicAuth widget to create a magic link signIn form.
Use `SupaMagicAuth` widget to create a magic link signIn form.
```dart
SupaMagicAuth(
@@ -75,7 +75,7 @@ SupaMagicAuth(
### Reset password
Use SupaResetPassword to create a password reset form.
Use `SupaResetPassword` to create a password reset form.
```dart
SupaResetPassword(
@@ -87,7 +87,7 @@ SupaResetPassword(
### Phone Auth
Use SupaPhoneAuth to create a phone authentication form.
Use `SupaPhoneAuth` to create a phone authentication form.
```dart
SupaPhoneAuth(
@@ -100,7 +100,7 @@ SupaPhoneAuth(
The package supports login with [official social providers](../../auth#providers).
Use SupaSocialsAuth to create list of social login buttons.
Use `SupaSocialsAuth` to create list of social login buttons.
```dart
SupaSocialsAuth(
@@ -20,7 +20,7 @@ The `auth-helpers` package has been replaced with the `@supabase/ssr` package. W
size="medium"
className="text-foreground-light border-b mt-8 pb-2"
>
<AccordionItem
header="See legacy docs"
id="legacy-docs"
@@ -196,7 +196,7 @@ You can pass types that were [generated with the Supabase CLI](/docs/reference/j
### Browser client
Creating a new supabase client object:
Creating a new `supabase` client object:
```tsx
import { createPagesBrowserClient } from '@supabase/auth-helpers-nextjs'
@@ -205,7 +205,7 @@ import { Database } from '../database.types'
const supabaseClient = createPagesBrowserClient<Database>()
```
Retrieving a supabase client object from the SessionContext:
Retrieving a `supabase` client object from the `SessionContext`:
```tsx
import { useSupabaseClient } from '@supabase/auth-helpers-react'
@@ -286,7 +286,7 @@ export default LoginPage
## Server-side rendering (SSR)
Create a server supabase client to retrieve the logged in user's session:
Create a server Supabase client to retrieve the logged in user's session:
```jsx pages/profile.js
import { createPagesServerClient } from '@supabase/auth-helpers-nextjs'
@@ -321,7 +321,7 @@ export const getServerSideProps = async (ctx) => {
## Server-side data fetching with RLS
You can use the server supabase client to run [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) authenticated queries server-side:
You can use the server Supabase client to run [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) authenticated queries server-side:
<Tabs
scrollable
@@ -543,7 +543,7 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
## Protecting API routes
Create a server supabase client to retrieve the logged in user's session:
Create a server Supabase client to retrieve the logged in user's session:
<Tabs
scrollable
@@ -674,7 +674,7 @@ supabase.auth.signUp({
#### Deprecated functions
With v0.7.x of the Next.js Auth Helpers a new naming convention has been implemented for createClient functions. The `createBrowserSupabaseClient` and `createServerSupabaseClient` functions have been marked as deprecated, and will be removed in a future version of the Auth Helpers.
With v0.7.x of the Next.js Auth Helpers a new naming convention has been implemented for `createClient` functions. The `createBrowserSupabaseClient` and `createServerSupabaseClient` functions have been marked as deprecated, and will be removed in a future version of the Auth Helpers.
- `createBrowserSupabaseClient` has been replaced with `createPagesBrowserClient`
- `createServerSupabaseClient` has been replaced with `createPagesServerClient`
@@ -917,7 +917,7 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
- The `useUser` hook now returns the `user` object or `null`.
- Usage with TypeScript: You can pass types that were [generated with the Supabase CLI](/docs/reference/javascript/typescript-support#generating-types) to the Supabase Client to get enhanced type safety and auto completion:
Creating a new supabase client object:
Creating a new `supabase` client object:
```tsx
import { Database } from '../database.types'
@@ -925,7 +925,7 @@ import { Database } from '../database.types'
const [supabaseClient] = useState(() => createPagesBrowserClient<Database>())
```
Retrieving a supabase client object from the SessionContext:
Retrieving a `supabase` client object from the `SessionContext`:
```tsx
import { useSupabaseClient } from '@supabase/auth-helpers-react'
@@ -1304,7 +1304,7 @@ supabase.auth.signUp({
#### Deprecated functions
With v0.7.x of the Next.js Auth Helpers a new naming convention has been implemented for createClient functions. The `createMiddlewareSupabaseClient`, `createBrowserSupabaseClient`, `createServerComponentSupabaseClient` and `createRouteHandlerSupabaseClient` functions have been marked as deprecated, and will be removed in a future version of the Auth Helpers.
With v0.7.x of the Next.js Auth Helpers a new naming convention has been implemented for `createClient` functions. The `createMiddlewareSupabaseClient`, `createBrowserSupabaseClient`, `createServerComponentSupabaseClient` and `createRouteHandlerSupabaseClient` functions have been marked as deprecated, and will be removed in a future version of the Auth Helpers.
- `createMiddlewareSupabaseClient` has been replaced with `createMiddlewareClient`
- `createBrowserSupabaseClient` has been replaced with `createClientComponentClient`
@@ -20,7 +20,7 @@ We generally recommend using the new `@supabase/ssr` package instead of `auth-he
size="medium"
className="text-foreground-light border-b mt-8 pb-2"
>
<AccordionItem
header="See legacy docs"
id="legacy-docs"
@@ -155,7 +155,7 @@ export const handle: Handle = async ({ event, resolve }) => {
<Admonition type="note">
Note that we are specifying filterSerializedResponseHeaders here. We need to tell SvelteKit that supabase needs the `content-range` and `x-supabase-api-version` headers.
Note that we are specifying `filterSerializedResponseHeaders` here. We need to tell SvelteKit that Supabase needs the `content-range` and `x-supabase-api-version` headers.
</Admonition>
@@ -213,7 +213,7 @@ export const GET = async ({ url, locals: { supabase } }) => {
### Generate types from your database
In order to get the most out of TypeScript and it's intellisense, you should import the generated Database types into the `app.d.ts` type definition file that comes with your SvelteKit project, where `import('./DatabaseDefinitions')` points to the generated types file outlined in [v2 docs here](https://supabase.com/docs/reference/javascript/release-notes#typescript-support) after you have logged in, linked, and generated types through the Supabase CLI.
In order to get the most out of TypeScript and its IntelliSense, you should import the generated Database types into the `app.d.ts` type definition file that comes with your SvelteKit project, where `import('./DatabaseDefinitions')` points to the generated types file outlined in [v2 docs here](https://supabase.com/docs/reference/javascript/release-notes#typescript-support) after you have logged in, linked, and generated types through the Supabase CLI.
```ts src/app.d.ts
// src/app.d.ts
@@ -377,13 +377,13 @@ TypeScript types can be [generated with the Supabase CLI](https://supabase.com/d
Access the client inside pages by `$page.data.supabase` or `data.supabase` when using `export let data`.
The usage of `depends` tells sveltekit that this load function should be executed whenever `invalidate` is called to keep the page store in sync.
The usage of `depends` tells SvelteKit that this load function should be executed whenever `invalidate` is called to keep the page store in sync.
`createSupabaseLoadClient` caches the client when running in a browser environment and therefore does not create a new client for every time the load function runs.
#### Setting up the event listener on the client side
We need to create an event listener in the root `+layout.svelte` file in order to catch supabase events being triggered.
We need to create an event listener in the root `+layout.svelte` file in order to catch Supabase events being triggered.
```svelte src/routes/+layout.svelte
<!-- src/routes/+layout.svelte -->
@@ -416,7 +416,7 @@ The usage of `invalidate` tells SvelteKit that the root `+layout.ts` load functi
#### Sign in / sign up / sign out
We can access the supabase instance in our `+page.svelte` file through the data object.
We can access the Supabase instance in our `+page.svelte` file through the data object.
```svelte src/routes/auth/+page.svelte
<!-- // src/routes/auth/+page.svelte -->
@@ -634,7 +634,7 @@ If you try to submit a form with the action `?/createPost` without a valid sessi
To avoid writing the same auth logic in every single route you can also use the handle hook to
protect multiple routes at once. For this to work with your Supabase session, you need to use
Sveltekit's [sequence helper](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks) function.
SvelteKit's [sequence helper](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks) function.
Edit your `/src/hooks.server.js` with the below:
<Tabs
@@ -1081,7 +1081,7 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
Since version 0.9 relies on `hooks.server.ts` to setup our client, we no longer need the `hooks.client.ts` in our project for Supabase related code.
#### Typings [#migration-typings]
#### Types [#migration-typings]
<Tabs
scrollable
@@ -1431,7 +1431,7 @@ import '$lib/db'
</TabPanel>
</Tabs>
#### Typings [#migration-typings-0-8]
#### Types [#migration-typings-0-8]
<Tabs
scrollable
@@ -1784,7 +1784,7 @@ export const handle = sequence(auth(), yourHandler)
</TabPanel>
</Tabs>
#### Typings [#migration-typings-0-7]
#### Types [#migration-typings-0-7]
<Tabs
scrollable
+5 -5
View File
@@ -36,7 +36,7 @@ Supabase supports 2 ways to [configure a hook](/dashboard/project/_/auth/hooks)
>
<TabPanel id="postgres-function" label="Postgres Function">
A [postgres function](/docs/guides/database/functions) can be configured as a hook. The function should take in a single argument -- the event of type JSONB -- and return a JSONB object. Since the postgres function runs on your database, the request does not leave your project's instance.
A [Postgres function](/docs/guides/database/functions) can be configured as a hook. The function should take in a single argument -- the event of type JSONB -- and return a JSONB object. Since the Postgres function runs on your database, the request does not leave your project's instance.
</TabPanel>
<TabPanel id="http" label="HTTP Endpoint">
@@ -59,9 +59,9 @@ Sign the payload and grant permissions selectively in order to guard the integri
>
<TabPanel id="sql" label="SQL">
When you configure a postgres function as a hook, Supabase will automatically apply the following grants to the function for these reasons:
When you configure a Postgres function as a hook, Supabase will automatically apply the following grants to the function for these reasons:
- Allow the `supabase_auth_admin` role to execute the function. The `supabase_auth_admin` role is the postgres role that is used by Supabase Auth to make requests to your database.
- Allow the `supabase_auth_admin` role to execute the function. The `supabase_auth_admin` role is the Postgres role that is used by Supabase Auth to make requests to your database.
- Revoke permissions from other roles (e.g. `anon`, `authenticated`, `public`) to ensure the function is not accessible by Supabase Data APIs.
```sql
@@ -81,7 +81,7 @@ revoke execute
You will need to alter your row-level security (RLS) policies to allow the `supabase_auth_admin` role to access tables that you have RLS policies on. You can read more about RLS policies [here](/docs/guides/database/postgres/row-level-security).
Alternatively, you can create your postgres function via the dashboard with the `security definer` tag. The `security definer` tag specifies that the function is to be executed with the privileges of the user that owns it.
Alternatively, you can create your Postgres function via the dashboard with the `security definer` tag. The `security definer` tag specifies that the function is to be executed with the privileges of the user that owns it.
Currently, functions created via the dashboard take on the `postgres` role. Read more about the `security definer` tag [in our database guide](/docs/guides/database/functions#security-definer-vs-invoker)
@@ -344,7 +344,7 @@ Outside of runtime errors, both HTTP Hooks and Postgres Hooks return timeout err
## Available Hooks
Each Hook description contains an example JSONSchema which you can use in conjunction with [JSONSchema Faker](https://json-schema-faker.js.org/) in order to generate a mock payload. For HTTP Hooks, you can also use [the Standard Webhooks Testing Tool](https://www.standardwebhooks.com/simulate) to simulate a request.
Each Hook description contains an example JSON Schema which you can use in conjunction with [JSON Schema Faker](https://json-schema-faker.js.org/) in order to generate a mock payload. For HTTP Hooks, you can also use [the Standard Webhooks Testing Tool](https://www.standardwebhooks.com/simulate) to simulate a request.
<div className="grid md:grid-cols-12 gap-4 not-prose">
{[
@@ -477,7 +477,7 @@ RESEND_API_KEY=your_resend_api_key
SEND_EMAIL_HOOK_SECRET=<base64_secret>
```
<Admonition type="info">
<Admonition type="note">
You can generate the secret in the [Auth Hooks](/dashboard/project/_/auth/hooks) section of the Supabase dashboard. Make sure to remove the `v1,whsec_` prefix!
@@ -8,7 +8,7 @@ Runs before a message is sent. Use the hook to:
- Use a regional SMS Provider
- Use alternate messaging channels such as WhatsApp
- Adjust the message body to include platform specific fields such as the [AppHash](https://developers.google.com/identity/sms-retriever/overview)
- Adjust the message body to include platform specific fields such as the [`AppHash`](https://developers.google.com/identity/sms-retriever/overview)
**Inputs**
+1 -1
View File
@@ -111,7 +111,7 @@ Below is an example that creates a new `UnenrollMFA` component that illustrates
- When the component appears on screen, the `supabase.auth.mfa.listFactors()` endpoint
fetches all existing factors together with their details.
- The existing factors for a user are displayed in a table.
- Once the user has selected a factor to unenroll, they can type in the factorId and click **Unenroll**
- Once the user has selected a factor to unenroll, they can type in the `factorId` and click **Unenroll**
which creates a confirmation modal.
<Admonition type="note">
+1 -1
View File
@@ -63,7 +63,7 @@ They use lists of known email addresses to sign up users to your project with pr
Usually the goal for this behavior is:
- To negatively affect your email sending reputation, after which they might ask for a ransom promising to stop the behavior.
- To cause a short-term or even long-term Denial of Service attack on your service, by preventing new account creation, sign ins with magic links or one-time passwords, or to severely impact important security flows in your application (such as reset password or forgot password).
- To cause a short-term or even long-term Denial of Service attack on your service, by preventing new account creation, signins with magic links or one-time passwords, or to severely impact important security flows in your application (such as reset password or forgot password).
- To force you to reduce the security posture of your project, such as by disabling email confirmations. At that point, they may target specific or a broad number of users by creating an account in their name. Then they can use social engineering techniques to trick them to use your application in such a way that both attacker and victim have access to the same account.
Mitigation strategies:
@@ -5,7 +5,7 @@ description: 'Use Single Sign-On (SSO) authentication on your project with SAML
video: 'https://www.youtube.com/v/em1cpOAXknM'
---
<Admonition>
<Admonition type="tip">
Looking for guides on how to use Single Sign-On with the Supabase dashboard? Head on over to [Enable SSO for Your Organization](/docs/guides/platform/sso).
@@ -13,7 +13,7 @@ Looking for guides on how to use Single Sign-On with the Supabase dashboard? Hea
Supabase Auth supports enterprise-level Single Sign-On (SSO) for any identity providers compatible with the SAML 2.0 protocol. This is a non-exclusive list of supported identity providers:
- Google Workspaces (formerly known as GSuite)
- Google Workspaces (formerly known as G Suite)
- Okta, Auth0
- Microsoft Active Directory, Azure Active Directory, Microsoft Entra
- PingIdentity
@@ -36,14 +36,14 @@ Please note that SAML 2.0 support is offered on plans Pro and above. Check the [
The number of SAML and SSO acronyms can often be overwhelming. Here's a glossary which you can refer back to at any time:
- **Identity Provider**, **IdP**, or **IDP**
An identity provider is a service that manages user accounts at a company or organization. It can verify the identity of a user and exchange that information with your Supabase project and other applications. It acts as a single source of truth for user identities and access rights. Commonly used identity providers are: Microsoft Active Directory (Azure AD, Microsoft Entra), Okta, Google Workspaces (GSuite), PingIdentity, OneLogin, and many others. There are also self-hosted and on-prem versions of identity providers, and sometimes they are accessible only by having access to a company VPN or being in a specific building.
An identity provider is a service that manages user accounts at a company or organization. It can verify the identity of a user and exchange that information with your Supabase project and other applications. It acts as a single source of truth for user identities and access rights. Commonly used identity providers are: Microsoft Active Directory (Azure AD, Microsoft Entra), Okta, Google Workspaces (G Suite), PingIdentity, OneLogin, and many others. There are also self-hosted and on-prem versions of identity providers, and sometimes they are accessible only by having access to a company VPN or being in a specific building.
- **Service Provider**, **SP**
This is the software that is asking for user information from an identity provider. In Supabase, this is your project's Auth server.
- **Assertion**
An assertion is a statement issued by an identity provider that contains information about a user.
- **EntityID**
- **`EntityID`**
A globally unique ID (usually a URL) that identifies an Identity Provider or Service Provider across the world.
- **NameID**
- **`NameID`**
A unique ID (usually an email address) that identifies a user at an Identity Provider.
- **Metadata**
An XML document that describes the features and configuration of an Identity Provider or Service Provider. It can be as a standalone document or as a URL. Usually (but not always) the `EntityID` is the URL at which you can access the Metadata.
@@ -53,7 +53,7 @@ The number of SAML and SSO acronyms can often be overwhelming. Here's a glossary
This is one of the most important SAML URLs. It is the URL where Supabase Auth will accept assertions from an identity provider. Basically, once the identity provider verifies the user's identity it will redirect to this URL and the redirect request will contain the assertion.
- **Binding (Redirect, POST, or Artifact)**
This is a description of the way an identity provider communicates with Supabase Auth. When using the Redirect binding, the communication occurs using HTTP 301 redirects. When it's `POST`, it's using `POST` requests sent with `<form>` elements on a page. When using Artifact, it's using a more secure exchange over a Redirect or `POST`.
- **RelayState**
- **`RelayState`**
State used by Supabase Auth to hold information about a request to verify the identity of a user.
## Important SAML 2.0 information
@@ -62,12 +62,12 @@ Below is information about your project's SAML 2.0 configuration which you can s
| Name | Value |
| --------------------------- | ----------------------------------------------------------------------- |
| EntityID | `https://<project>.supabase.co/auth/v1/sso/saml/metadata` |
| `EntityID` | `https://<project>.supabase.co/auth/v1/sso/saml/metadata` |
| Metadata URL | `https://<project>.supabase.co/auth/v1/sso/saml/metadata` |
| Metadata URL<br/>(download) | `https://<project>.supabase.co/auth/v1/sso/saml/metadata?download=true` |
| ACS URL | `https://<project>.supabase.co/auth/v1/sso/saml/acs` |
| SLO URL | `https://<project>.supabase.co/auth/v1/sso/slo` |
| NameID | Required `emailAddress` or `persistent` |
| `NameID` | Required `emailAddress` or `persistent` |
Note that SLO (Single Logout) is not supported at this time with Supabase Auth as it is a rarely supported feature by identity providers. However, the URL is registered and advertised for when this does become available.
@@ -155,7 +155,7 @@ Commonly used SAML 2.0 Identity Providers that support Metadata URLs:
Commonly used SAML 2.0 Identity Providers that only support Metadata XML files:
- Google Workspaces (GSuite)
- Google Workspaces (G Suite)
- Any self-hosted or on-prem identity provider behind a VPN
Once you've obtained the SAML 2.0 Metadata XML file or URL you can [establish a connection](/docs/reference/cli/supabase-sso-add) with your project's Supabase Auth server by running:
@@ -323,7 +323,7 @@ Most SAML 2.0 identity providers use Lightweight Directory Access Protocol (LDAP
**Accessing the stored attributes**
The stored attributes, once mapped, show up in the access token (a JWT) of the user. If you need to look these values up in the database, you can find them in the `auth.identities` table under the `identity_data` JSON column. Identities created for SSO providers have `sso:<uuid-of-provider>` in the `provider` column, while `id` contains the unique NameID of the user account.
The stored attributes, once mapped, show up in the access token (a JWT) of the user. If you need to look these values up in the database, you can find them in the `auth.identities` table under the `identity_data` JSON column. Identities created for SSO providers have `sso:<uuid-of-provider>` in the `provider` column, while `id` contains the unique `NameID` of the user account.
Furthermore, you can find the same identity data under `raw_app_meta_data` inside `auth.users`.
+1 -1
View File
@@ -41,7 +41,7 @@ The JSON object starts out looking something like this:
Just note that the more data you store in your token, the longer the encoded string will be.
When we want to send the JWT to the user, we first encode the data using an algorithm such as `HS256`. There are many libraries (and several different algorithms) that can be used to do this encoding/decoding, such as [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken). The signing is as simple as:
When we want to send the JWT to the user, we first encode the data using an algorithm such as `HS256`. There are many libraries (and several different algorithms) that can be used to do this encoding/decoding, such as [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken). The signing is as simple as:
```js
// from https://replit.com/@awalias/jsonwebtokens#index.js
@@ -113,14 +113,14 @@ With Deep Linking, you can configure this redirect to open a specific page. This
</TabPanel>
<TabPanel id="flutter" label="Flutter">
// Currently supabase_flutter supports deep links on Android, iOS, Web, MacOS and Windows.
// Currently supabase_flutter supports deep links on Android, iOS, Web, macOS and Windows.
### Deep link config
- Go to your [auth settings](https://supabase.com/dashboard/project/_/auth/url-configuration) page.
- You need to enter your app redirect callback on `Additional Redirect URLs` field.
The redirect callback url should have this format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.flutterquickstart://login-callback` is just an example, you can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
The redirect callback URL should have this format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.flutterquickstart://login-callback` is just an example, you can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
![Supabase console deep link setting](/docs/img/deeplink-setting.png)
@@ -269,11 +269,10 @@ With Deep Linking, you can configure this redirect to open a specific page. This
You can achieve it with [url_protocol](https://pub.dev/packages/url_protocol) inside you app.
The most relevant solution is to include those registry modifications into your installer to allow
for deregistration.
The most relevant solution is to include those registry modifications into your installer to allow for deregistration.
</TabPanel>
<TabPanel id="macos" label="MacOS">
<TabPanel id="macos" label="macOS">
Add this XML chapter in your `macos/Runner/Info.plist` inside `<plist version="1.0"><dict>` chapter:
@@ -311,7 +310,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This
1. Go to your [auth settings](https://supabase.com/dashboard/project/_/auth/url-configuration) page.
2. Enter your app redirect URL in the `Additional Redirect URLs` field. This is the URL that the user gets redirected to after clicking a magic link.
The redirect callback url should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
The redirect callback URL should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
![Supabase console deep link setting](/docs/img/deeplink-setting.png)
@@ -349,7 +348,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This
1. Go to your [auth settings](https://supabase.com/dashboard/project/_/auth/url-configuration) page.
2. Enter your app redirect URL in the `Additional Redirect URLs` field. This is the URL that the user gets redirected to after clicking a magic link.
The redirect callback url should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
The redirect callback URL should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used.
Now, edit the Android manifest to make sure the app opens when the user clicks on the magic link.
@@ -394,7 +393,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This
}
```
The user will now be authenticated when your app receives a valid deeplink!
The user will now be authenticated when your app receives a valid deep link!
</TabPanel>
</Tabs>
+2 -2
View File
@@ -465,7 +465,7 @@ data = supabase.auth.sign_up({
>
<TabPanel id="js" label="JavaScript">
When your user signs in, call [signInWithPassword()](/docs/reference/javascript/auth-signinwithpassword) with their email address and password:
When your user signs in, call [`signInWithPassword()`](/docs/reference/javascript/auth-signinwithpassword) with their email address and password:
```js
async function signInWithEmail() {
@@ -479,7 +479,7 @@ async function signInWithEmail() {
</TabPanel>
<TabPanel id="dart" label="Dart">
When your user signs in, call [signInWithPassword()](/docs/reference/dart/auth-signinwithpassword) with their email address and password:
When your user signs in, call [`signInWithPassword()`](/docs/reference/dart/auth-signinwithpassword) with their email address and password:
```dart
Future<void> signInWithEmail() async {
@@ -5,7 +5,7 @@ description: 'Learn about logging in to your platform using SMS one-time passwor
Phone Login is a method of authentication that allows users to log in to a website or application without using a password. The user authenticates through a one-time password (OTP) sent via a channel (SMS or WhatsApp).
<Admonition type="info">
<Admonition type="note">
At this time, `WhatsApp` is only supported as a channel for the Twilio and Twilio Verify Providers.
@@ -376,7 +376,7 @@ export const handle: Handle = async ({ event, resolve }) => {
<TabPanel id="layout" label="Root Layout Load">
Page components can get access to the supabase client from the `data` object due to this load function.
Page components can get access to the Supabase client from the `data` object due to this load function.
```ts +layout.ts
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public'
@@ -63,7 +63,7 @@ When developing with Expo, you can test Sign in with Apple via the Expo Go app,
6. Create a signing **Key** in the [Keys](https://developer.apple.com/account/resources/authkeys/list) section of the Apple Developer Console. You can use this key to generate a secret key using the tool below, which is added to your Supabase project's Auth configuration. Make sure you safely store the `AuthKey_XXXXXXXXXX.p8` file. If you ever lose access to it, or make it public accidentally please revoke it from the Apple Developer Console and create a new one immediately. You will have to generate a new secret key using this file every 6 months, so make sure you schedule a recurring meeting in your calendar!
7. Finally, add the information you configured above to the [Apple provider configuration in the Supabase dashboard](https://supabase.com/dashboard/project/_/auth/providers).
<Admonition>
<Admonition type="tip">
Use this tool to generate a new Apple client secret. No keys leave your browser! Be aware that this tool does not currently work in Safari, so please use Firefox or a Chrome-based browser instead.
@@ -280,7 +280,7 @@ When developing with Expo, you can test Sign in with Apple via the Expo Go app,
6. Create a signing **Key** in the [Keys](https://developer.apple.com/account/resources/authkeys/list) section of the Apple Developer Console. You can use this key to generate a secret key using the tool below, which is added to your Supabase project's Auth configuration. Make sure you safely store the `AuthKey_XXXXXXXXXX.p8` file. If you ever lose access to it, or make it public accidentally please revoke it from the Apple Developer Console and create a new one immediately. You will have to generate a new secret key using this file every 6 months, so make sure you schedule a recurring reminder in your calendar!
7. Finally, add the information you configured above to the [Apple provider configuration in the Supabase dashboard](https://supabase.com/dashboard/project/_/auth/providers).
<Admonition>
<Admonition type="tip">
Use this tool to generate a new Apple client secret. No keys leave your browser! Be aware that this tool does not currently work in Safari, so please use Firefox or a Chrome-based browser instead.
@@ -348,12 +348,12 @@ When developing with Expo, you can test Sign in with Apple via the Expo Go app,
</Admonition>
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
## Using native sign in with Apple in Kotlin
When using [Compose Multiplatform](https://github.com/JetBrains/compose-multiplatform/), you can use the [compose-auth](https://supabase.com/docs/reference/kotlin/installing) plugin. On iOS it uses Native Apple Login automatically and on other platforms it uses `gotrue.signInWith(Apple)`.
When using [Compose Multiplatform](https://github.com/JetBrains/compose-multiplatform/), you can use the [compose-auth](https://supabase.com/docs/reference/kotlin/installing) plugin. On iOS it uses Native Apple Login automatically and on other platforms it uses `gotrue.signInWith(Apple)`.
**Initialize the Supabase Client**
@@ -126,7 +126,7 @@ Supabase Auth requires that Azure returns a valid email address. Therefore you m
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `azure` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `azure` as the `provider`:
```js
async function signInWithAzure() {
@@ -142,7 +142,7 @@ async function signInWithAzure() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `azure` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `azure` as the `provider`:
```dart
Future<void> signInWithAzure() async {
@@ -4,7 +4,7 @@ title: 'Login with Bitbucket'
description: 'Add Bitbucket OAuth to your Supabase project'
---
To enable Bitbucket Auth for your project, you need to set up a BitBucket OAuth application and add the application credentials to your Supabase Dashboard.
To enable Bitbucket Auth for your project, you need to set up a Bitbucket OAuth application and add the application credentials to your Supabase Dashboard.
## Overview
@@ -57,7 +57,7 @@ Setting up Bitbucket logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `bitbucket` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `bitbucket` as the `provider`:
```js
async function signInWithBitbucket() {
@@ -70,7 +70,7 @@ async function signInWithBitbucket() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `bitbucket` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `bitbucket` as the `provider`:
```dart
Future<void> signInWithBitbucket() async {
@@ -56,7 +56,7 @@ Setting up Discord logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `discord` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `discord` as the `provider`:
```js
async function signInWithDiscord() {
@@ -69,7 +69,7 @@ async function signInWithDiscord() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `discord` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `discord` as the `provider`:
```dart
Future<void> signInWithDiscord() async {
@@ -73,7 +73,7 @@ Under `Build Your App`, click on `Use Cases` screen. From there, do the followin
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `facebook` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `facebook` as the `provider`:
```js
async function signInWithFacebook() {
@@ -86,7 +86,7 @@ async function signInWithFacebook() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `facebook` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `facebook` as the `provider`:
```dart
Future<void> signInWithFacebook() async {
@@ -102,7 +102,7 @@ Future<void> signInWithFacebook() async {
</TabPanel>
<TabPanel id="swift" label="Swift">
When your user signs in, call [signInWithOAuth()](/docs/reference/swift/auth-signinwithoauth) with `facebook` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/swift/auth-signinwithoauth) with `facebook` as the `provider`:
```swift
func signInWithFacebook() async throws {
@@ -57,7 +57,7 @@ Setting up Figma logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `figma` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `figma` as the `provider`:
```js
async function signInWithFigma() {
@@ -70,7 +70,7 @@ async function signInWithFigma() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/flutter/auth-signinwithoauth) with `figma` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/flutter/auth-signinwithoauth) with `figma` as the `provider`:
```dart
Future<void> signInWithFigma() async {
@@ -51,7 +51,7 @@ Copy your new OAuth credentials
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `github` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `github` as the `provider`:
```js
async function signInWithGithub() {
@@ -64,7 +64,7 @@ async function signInWithGithub() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `github` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `github` as the `provider`:
```dart
Future<void> signInWithGithub() async {
@@ -80,7 +80,7 @@ Future<void> signInWithGithub() async {
</TabPanel>
<TabPanel id="swift" label="Swift">
When your user signs in, call [signInWithOAuth](/docs/reference/swift/auth-signinwithoauth) with `.github` as the `Provider`:
When your user signs in, call [`signInWithOAuth`](/docs/reference/swift/auth-signinwithoauth) with `.github` as the `Provider`:
```swift
func signInWithGithub() async throws {
@@ -54,7 +54,7 @@ Setting up GitLab logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `gitlab` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `gitlab` as the `provider`:
```js
async function signInWithGitLab() {
@@ -67,7 +67,7 @@ async function signInWithGitLab() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `gitlab` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `gitlab` as the `provider`:
```dart
Future<void> signInWithGitLab() async {
@@ -27,7 +27,7 @@ To support Sign In with Google, you need to configure the Google provider for yo
For web applications, you can set up your signin button two different ways:
- Use your own [application code](#application-code) for the button.
- Use [Google's pre-built sign-in or OneTap flows](#google-pre-built).
- Use [Google's pre-built sign-in or One Tap flows](#google-pre-built).
### Application code configuration
@@ -78,7 +78,7 @@ To use Google's pre-built signin buttons:
1. Configure OAuth credentials for your Google Cloud project in the [Credentials](https://console.cloud.google.com/apis/credentials) page of the console. When creating a new OAuth client ID, choose _Android_ or _iOS_ depending on the mobile operating system your app is built for.
- For Android, use the instructions on screen to provide the SHA-1 certificate fingerprint used to sign your Android app.
- You will have a different set of SHA-1 certificate fingerprint for testing locally and going to production. Make sure to add both to the Google Cloud Console. and add all of the Client IDs to Supabase dashboard.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple AppStore.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple App Store.
2. Configure the [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent). This information is shown to the user when giving consent to your app. In particular, make sure you have set up links to your app's privacy policy and terms of service.
3. Finally, add the client ID from step 1 in the [Google provider on the Supabase Dashboard](https://supabase.com/dashboard/project/_/auth/providers), under _Client IDs_.
@@ -94,7 +94,7 @@ To use Google's pre-built signin buttons:
- For both Android and iOS, you will need to create a Web client ID in the [Google Cloud Console](https://console.cloud.google.com/apis/credentials).
- For Android, use the instructions on screen to provide the SHA-1 certificate fingerprint used to sign your Android app.
- You will have a different set of SHA-1 certificate fingerprint for testing locally and going to production. Make sure to add both to the Google Cloud Console. and add all of the Client IDs to Supabase dashboard.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple AppStore.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple App Store.
2. Configure the [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent). This information is shown to the user when giving consent to your app. In particular, make sure you have set up links to your app's privacy policy and terms of service.
3. Add only the web client ID from step 1 in the [Google provider on the Supabase Dashboard](https://supabase.com/dashboard/project/_/auth/providers), under _Client IDs_. If you need iOS support, enable the `Skip nonce check` option.
4. For iOS, add the `CFBundleURLTypes` attributes below into the `/ios/Runner/Info.plist` file.
@@ -129,7 +129,7 @@ To use Google's pre-built signin buttons:
<TabPanel id="swift" label="Swift">
Google sign-in with Supabase is done through the [GoogleSignIn-iOS](https://github.com/google/GoogleSignIn-iOS) package.
Google sign-in with Supabase is done through the [`GoogleSignIn-iOS`](https://github.com/google/GoogleSignIn-iOS) package.
When the user provides consent, Google issues an identity token (commonly abbreviated as ID token) that is then sent to your project's Supabase Auth server. When valid, a new user session is started by issuing an access and refresh token from Supabase Auth.
@@ -187,7 +187,7 @@ To use Google's pre-built signin buttons:
1. Configure OAuth credentials for your Google Cloud project in the [Credentials](https://console.cloud.google.com/apis/credentials) page of the console. When creating a new OAuth client ID, choose _Android_ or _iOS_ depending on the mobile operating system your app is built for.
- For Android, use the instructions on screen to provide the SHA-1 certificate fingerprint used to sign your Android app.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple AppStore.
- For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple App Store.
2. Configure the [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent). This information is shown to the user when giving consent to your app. In particular, make sure you have set up links to your app's privacy policy and terms of service.
3. Finally, add the client ID from step 1 in the [Google provider on the Supabase Dashboard](https://supabase.com/dashboard/project/_/auth/providers), under _Client IDs_.
@@ -548,7 +548,7 @@ Future<void> _nativeGoogleSignIn() async {
### Web, macOS, Windows, and Linux
Google sign-in with Supabase on Web, macOS, Windows, and Linux is done through the [signInWithOAuth](docs/reference/dart/auth-signinwithoauth) method.
Google sign-in with Supabase on Web, macOS, Windows, and Linux is done through the [`signInWithOAuth`](docs/reference/dart/auth-signinwithoauth) method.
This method of signing in is web based, and will open a browser window to perform the sign in. For non-web platforms, the user is brought back to the app via [deep linking](/docs/guides/auth/native-mobile-deep-linking?platform=flutter).
@@ -595,7 +595,7 @@ implementation ("com.google.android.libraries.identity.googleid:googleid:<latest
implementation("androidx.credentials:credentials-play-services-auth:<latest version>")
```
Add the following proguard rules to your `proguard-rules.pro` file:
Add the following ProGuard rules to your `proguard-rules.pro` file:
```proguard
-if class androidx.credentials.CredentialManager
@@ -52,7 +52,7 @@ This will serve as the `client_id` when you make API calls to authenticate the u
- Go to `Product settings` > `Kakao Login` > `Security`.
- Click on the `Kakao Login` switch to enable Kakao Login.
- Click on `generate code` at the bottom to generate the `Client secret code` -- this will serve as a `client_secret` for your supabase project.
- Click on `generate code` at the bottom to generate the `Client secret code` -- this will serve as a `client_secret` for your Supabase project.
- Make sure you enabled `Client secret code` by selecting `enable` from the `Activation state` section.
## Additional configurations on Kakao Developers portal
@@ -79,7 +79,7 @@ This will serve as the `client_id` when you make API calls to authenticate the u
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `kakao` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `kakao` as the `provider`:
```js
async function signInWithKakao() {
@@ -92,7 +92,7 @@ async function signInWithKakao() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `kakao` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `kakao` as the `provider`:
```dart
Future<void> signInWithKakao() async {
@@ -10,16 +10,16 @@ To enable Keycloak Auth for your project, you need to set up an Keycloak OAuth a
To get started with Keycloak, you can run it in a docker container with: `docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:latest start-dev`
This guide will be assuming that you are running keycloak in a docker container as described in the command above.
This guide will be assuming that you are running Keycloak in a docker container as described in the command above.
Keycloak OAuth consists of five broad steps:
- Create a new client in your specified keycloak realm.
- Create a new client in your specified Keycloak realm.
- Obtain the `issuer` from the "OpenID Endpoint Configuration". This will be used as the `Keycloak URL`.
- Ensure that the new client has the "Client Protocol" set to "openid-connect" and the "Access Type" is set to "confidential".
- Ensure that the new client has the "Client Protocol" set to `openid-connect` and the "Access Type" is set to "confidential".
- The `Client ID` of the client created will be used as the `client id`.
- Obtain the `Secret` from the credentials tab which will be used as the `client secret`.
- Add the callback url of your application to your allowlist.
- Add the callback URL of your application to your allowlist.
## Access your Keycloak admin console
@@ -43,7 +43,7 @@ The "Client ID" of the created client will serve as the `client_id` when you mak
After you've created the client successfully, ensure that you set the following settings:
1. The "Client Protocol" should be set to "openid-connect".
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`.
@@ -72,7 +72,7 @@ Since Keycloak version 22, the `openid` scope must be passed. Add this to the [`
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `keycloak` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `keycloak` as the `provider`:
```js
async function signInWithKeycloak() {
@@ -88,7 +88,7 @@ async function signInWithKeycloak() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `keycloak` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `keycloak` as the `provider`:
```dart
Future<void> signInWithKeycloak() async {
@@ -163,5 +163,5 @@ suspend fun signOut() {
## Resources
- You can find the keycloak openid endpoint configuration under the realm settings.
- You can find the Keycloak OpenID endpoint configuration under the realm settings.
![Keycloak OpenID Endpoint Configuration](/docs/img/guides/auth-keycloak/keycloak-openid-endpoint-config.png)
@@ -59,7 +59,7 @@ Ensure that the appropriate scopes have been added under OAuth 2.0 Scopes at the
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `linkedin_oidc` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `linkedin_oidc` as the `provider`:
```js
async function signInWithLinkedIn() {
@@ -72,7 +72,7 @@ async function signInWithLinkedIn() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `linkedin_oidc` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `linkedin_oidc` as the `provider`:
```dart
Future<void> signInWithLinkedIn() async {
@@ -23,7 +23,7 @@ Setting up Notion logins for your application consists of 3 parts:
- Once logged in, go to [notion.so/my-integrations](https://notion.so/my-integrations) and create a new integration.
- When creating your integration, ensure that you select "Public integration" under "Integration type" and "Read user information including email addresses" under "Capabilities".
- You will need to add a redirect uri, see [Add the redirect uri](#add-the-redirect-uri)
- You will need to add a redirect URI, see [Add the redirect URI](#add-the-redirect-uri)
- Once you've filled in the necessary fields, click "Submit" to finish creating the integration.
![notion.so](/docs/img/guides/auth-notion/notion-developer.png)
@@ -57,7 +57,7 @@ Setting up Notion logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `notion` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `notion` as the `provider`:
```js
async function signInWithNotion() {
@@ -70,7 +70,7 @@ async function signInWithNotion() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `notion` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `notion` as the `provider`:
```dart
Future<void> signInWithNotion() async {
@@ -75,7 +75,7 @@ Under `Scopes`:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `slack_oidc` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `slack_oidc` as the `provider`:
```js
async function signInWithSlack() {
@@ -88,7 +88,7 @@ async function signInWithSlack() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `slack` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `slack` as the `provider`:
```dart
Future<void> signInWithSlack() async {
@@ -69,7 +69,7 @@ The following outlines the steps to sign in using Spotify with Supabase Auth.
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `spotify` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `spotify` as the `provider`:
```js
async function signInWithSpotify() {
@@ -82,7 +82,7 @@ async function signInWithSpotify() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `spotify` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `spotify` as the `provider`:
```dart
Future<void> signInWithSpotify() async {
@@ -41,7 +41,7 @@ Setting up Twitch logins for your application consists of 3 parts:
- Enter the name of your application.
- Type or paste your `OAuth Redirect URL` (the callback URL from the previous step.)
- Select a category for your app.
- Check the Captcha box and click `Create`.
- Check the CAPTCHA box and click `Create`.
## Retrieve your Twitch OAuth client ID and client secret
@@ -72,7 +72,7 @@ Setting up Twitch logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `twitch` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `twitch` as the `provider`:
```js
async function signInWithTwitch() {
@@ -85,7 +85,7 @@ async function signInWithTwitch() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `twitch` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `twitch` as the `provider`:
```dart
Future<void> signInWithTwitch() async {
@@ -63,7 +63,7 @@ Setting up Twitter logins for your application consists of 3 parts:
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `twitter` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `twitter` as the `provider`:
```js
async function signInWithTwitter() {
@@ -76,7 +76,7 @@ async function signInWithTwitter() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `twitter` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `twitter` as the `provider`:
```dart
Future<void> signInWithTwitter() async {
@@ -50,7 +50,7 @@ On the redirects page, enter your Supabase project's `Callback URL (for OAuth)`
## Step 5. Add login code to your client app
When a user signs in, call signInWithOAuth with `workos` as the provider.
When a user signs in, call `signInWithOAuth` with `workos` as the provider.
```javascript
async function signInWithWorkOS() {
@@ -70,7 +70,7 @@ Under `Scopes`
<CreateClientSnippet />
When your user signs in, call [signInWithOAuth()](/docs/reference/javascript/auth-signinwithoauth) with `zoom` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/javascript/auth-signinwithoauth) with `zoom` as the `provider`:
```js
async function signInWithZoom() {
@@ -83,7 +83,7 @@ async function signInWithZoom() {
</TabPanel>
<TabPanel id="flutter" label="Flutter">
When your user signs in, call [signInWithOAuth()](/docs/reference/dart/auth-signinwithoauth) with `zoom` as the `provider`:
When your user signs in, call [`signInWithOAuth()`](/docs/reference/dart/auth-signinwithoauth) with `zoom` as the `provider`:
```dart
Future<void> signInWithZoom() async {
+1 -1
View File
@@ -12,7 +12,7 @@ Supabase has first-class support for these third-party authentication providers:
You can use these providers alongside Supabase Auth, or on their own, to access the [Data API (REST and GraphQL)](/docs/guides/database), [Storage](/docs/guides/storage), [Realtime](/docs/guides/storage) and [Functions](/docs/guides/functions) from your existing apps.
If you already have production apps using one of these authentication providers, and would like to use a Supabase feature, you no longer need to migrate your users to Supabase Auth or use work-arounds like translating JWTs into the Supabase Auth format and using your project's signing secret.
If you already have production apps using one of these authentication providers, and would like to use a Supabase feature, you no longer need to migrate your users to Supabase Auth or use workarounds like translating JWTs into the Supabase Auth format and using your project's signing secret.
## How does it work?
+1 -1
View File
@@ -50,7 +50,7 @@ An identity describes the authentication method that a user can use to sign in.
<Admonition type="note">
A user with an email or phone identity will be able to sign in with either a password or passwordless method (e.g. use a one-time password (OTP) or magiclink). By default, a user with an unverified email or phone number will not be able to sign in.
A user with an email or phone identity will be able to sign in with either a password or passwordless method (e.g. use a one-time password (OTP) or magic link). By default, a user with an unverified email or phone number will not be able to sign in.
</Admonition>
+1 -1
View File
@@ -37,7 +37,7 @@ Uninstall Supabase Cron by disabling the `pg_cron` extension:
drop extension if exists pg_cron;
```
<Admonition type="warning">
<Admonition type="danger">
Disabling the `pg_cron` extension will permanently delete all Jobs.
+2 -2
View File
@@ -204,7 +204,7 @@ select cron.alter_job(
select cron.unschedule('permanent-cron-job-name');
```
<Admonition type="warning">
<Admonition type="caution">
Unscheduling a Job will permanently delete the Job from `cron.job` table but its run history remain in `cron.job_run_details` table.
@@ -246,7 +246,7 @@ order by start_time desc
limit 10;
```
<Admonition type="warning">
<Admonition type="caution">
The records in the `cron.job_run_details` table are not cleaned up automatically. They are also not removed when jobs are unscheduled, which will take up disk space in your database.
@@ -132,9 +132,11 @@ supabase.from_('arraytest').insert(
You should see:
```
| id | textarray |
| --- | ----------------------- |
| 1 | ["Harry","Larry","Moe"] |
```
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -145,9 +147,11 @@ select * from arraytest;
You should see:
```
| id | textarray |
| --- | ----------------------- |
| 1 | ["Harry","Larry","Moe"] |
```
</TabPanel>
</Tabs>
@@ -173,9 +177,11 @@ SELECT textarray[1], array_length(textarray, 1) FROM arraytest;
returns:
```
| textarray | array_length |
| --------- | ------------ |
| Harry | 3 |
```
</TabPanel>
<TabPanel id="js" label="JavaScript">
@@ -66,7 +66,7 @@ The direct connection string connects directly to your Postgres instance. It is
<Admonition type="caution">
Direct connections use IPv6 by default. If your environment doesn't support IPv6, use [Supavisor session mode](#supavisor-session-mode) or get the [IPv4 addon](/docs/guides/platform/ipv4-address).
Direct connections use IPv6 by default. If your environment doesn't support IPv6, use [Supavisor session mode](#supavisor-session-mode) or get the [IPv4 add-on](/docs/guides/platform/ipv4-address).
</Admonition>
@@ -53,27 +53,27 @@ ON pg_stat_ssl.pid = pg_stat_activity.pid;
Interpreting the query:
| Column | Description |
| ---------------- | ------------------------------------------------- |
| connection_id | connection id |
| ssl | Indicates if SSL is in use |
| database | Name of the connected database (usually postgres) |
| usename | Role of the connected user |
| application_name | Name of the connecting application |
| client_addr | IP address of the connecting server |
| query | Last query executed by the connection |
| query_start | Time when the last query was executed |
| state | Querying state: active or idle |
| backend_start | Timestamp of the connection's establishment |
| Column | Description |
| ------------------ | --------------------------------------------------- |
| `connection_id` | connection id |
| `ssl` | Indicates if SSL is in use |
| `database` | Name of the connected database (usually `postgres`) |
| `usename` | Role of the connected user |
| `application_name` | Name of the connecting application |
| `client_addr` | IP address of the connecting server |
| `query` | Last query executed by the connection |
| `query_start` | Time when the last query was executed |
| `state` | Querying state: active or idle |
| `backend_start` | Timestamp of the connection's establishment |
The usename can be used to identify the source:
The username can be used to identify the source:
| Role | API/Tool |
| ---------------------------- | ------------------------------------------------------------------------- |
| supabase_admin | Used by Supabase for monitoring and by Realtime |
| authenticator | Data API (PostgREST) |
| supabase_auth_admin | Auth |
| supabase_storage_admin | Storage |
| supabase_replication_admin | Synchronizes Read Replicas |
| postgres | Supabase Dashboard and External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
| `supabase_admin` | Used by Supabase for monitoring and by Realtime |
| `authenticator` | Data API (PostgREST) |
| `supabase_auth_admin` | Auth |
| `supabase_storage_admin` | Storage |
| `supabase_replication_admin` | Synchronizes Read Replicas |
| `postgres` | Supabase Dashboard and External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
| Custom roles defined by user | External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
@@ -61,7 +61,7 @@ Some settings can only be modified by a superuser. Supabase pre-enables the [`su
| `session_replication_role` | Sets the session's behavior for triggers and rewrite rules. |
| `track_io_timing` | Collects timing statistics for database I/O activity. |
For example, to enable `log_nested_statements` for the postgres role, execute:
For example, to enable `log_nested_statements` for the `postgres` role, execute:
```sql
alter role "postgres" set "auto_explain.log_nested_statements" to 'on';
@@ -46,7 +46,7 @@ You can use the `http` extension to make these network requests from Postgres.
1. Go to the [Database](https://supabase.com/dashboard/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "http" and enable the extension.
3. Search for `http` and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -4,7 +4,7 @@ title: 'pg_hashids: Short UIDs'
description: 'Generate Short UIDs from Numbers'
---
[pg_hashids](https://github.com/iCyberon/pg_hashids) provides a secure way to generate short, unique, non-sequential ids from numbers. The hashes are intended to be small, easy-to-remember identifiers that can be used to obfuscate data (optionally) with a password, alphabet, and salt. For example, you may wish to hide data like user IDs, order numbers, or tracking codes in favor of `pg_hashid`'s unique identifers.
[pg_hashids](https://github.com/iCyberon/pg_hashids) provides a secure way to generate short, unique, non-sequential ids from numbers. The hashes are intended to be small, easy-to-remember identifiers that can be used to obfuscate data (optionally) with a password, alphabet, and salt. For example, you may wish to hide data like user IDs, order numbers, or tracking codes in favor of `pg_hashid`'s unique identifiers.
## Enable the extension
@@ -43,7 +43,7 @@ It's good practice to create the extension within a separate schema (like `exten
## Usage
Suppose we have a table that stores order information, and we want to give customers a unique identifer without exposing the sequential `id` column. To do this, we can use `pg_hashid`'s `id_encode` function.
Suppose we have a table that stores order information, and we want to give customers a unique identifier without exposing the sequential `id` column. To do this, we can use `pg_hashid`'s `id_encode` function.
```sql
create table orders (
@@ -435,7 +435,7 @@ More examples can be seen on the [Extension's GitHub page](https://github.com/su
- Can only make POST requests with JSON data. No other data formats are supported
- Intended to handle at most 200 requests per second. Increasing the rate can introduce instability
- Does not have support for PATCH/PUT requests
- Can only work with one database at a time. It defaults to the postgres database.
- Can only work with one database at a time. It defaults to the `postgres` database.
## Resources
@@ -56,21 +56,21 @@ select * from extensions.pg_stat_monitor;
The following table shows a subset of available columns:
| Column Type | Description |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| bucket bigint | Data collection unit. The number shows what bucket in a chain a record belongs to |
| bucket_start_time timestampz | The start time of the bucket |
| userid oid (references pg_authid.oid) | OID of user who executed the statement |
| dbid oid (references pg_database.oid) | OID of database in which the statement was executed |
| toplevel bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) |
| client_ip inet | The IP address of a client that ran the query |
| queryid bigint | Hash code to identify identical normalized queries. |
| planid text | An internally generated ID of a query plan |
| query_plan text | The sequence of steps used to execute a query. This parameter is only available when pgsm_enable_query_plan is enabled |
| query text | Text of a representative statement |
| plans bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| total_plan_time double precision | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| min_plan_time double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| Column Type | Description |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `bucket` `bigint` | Data collection unit. The number shows what bucket in a chain a record belongs to |
| `bucket_start_time` `timestampz` | The start time of the bucket |
| `userid` `oid` (references `pg_authid.oid`) | OID of user who executed the statement |
| `dbid` `oid` (references `pg_database.oid`) | OID of database in which the statement was executed |
| `toplevel` `bool` | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) |
| `client_ip` `inet` | The IP address of a client that ran the query |
| `queryid` `bigint` | Hash code to identify identical normalized queries. |
| `planid` `text` | An internally generated ID of a query plan |
| `query_plan` `text` | The sequence of steps used to execute a query. This parameter is only available when pgsm_enable_query_plan is enabled |
| `query` `text` | Text of a representative statement |
| `plans` `bigint` | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| `total_plan_time` `double precision` | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| `min_plan_time` `double precision` | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
A full list of statistics is available in the [pg_stat_monitor docs](https://docs.percona.com/pg-stat-monitor/reference.html#postgresql-15).
@@ -6,16 +6,16 @@ description: 'Track planning and execution statistics of all SQL statements exec
`pg_stat_statements` is a database extension that exposes a view, of the same name, to track statistics about SQL statements executed on the database. The following table shows some of the available statistics and metadata:
| Column Name | Column Type | Description |
| --------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| userid | oid (references pg_authid.oid) | OID of user who executed the statement |
| dbid | oid (references pg_database.oid) | OID of database in which the statement was executed |
| toplevel | bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) |
| queryid | bigint | Hash code to identify identical normalized queries. |
| query | text | Text of a representative statement |
| plans | bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| total_plan_time | double precision | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| min_plan_time | double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| Column Name | Column Type | Description |
| ----------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `userid` | `oid` (references `pg_authid.oid`) | OID of user who executed the statement |
| `dbid` | `oid` (references `pg_database.oid`) | OID of database in which the statement was executed |
| `toplevel` | `bool` | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) |
| `queryid` | `bigint` | Hash code to identify identical normalized queries. |
| `query` | `text` | Text of a representative statement |
| `plans` | `bigint` | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| `total_plan_time` | `double precision` | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| `min_plan_time` | `double precision` | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
A full list of statistics is available in the [pg_stat_statements docs](https://www.postgresql.org/docs/current/pgstatstatements.html).
@@ -48,7 +48,7 @@ PGAudit can be configured with different levels of precision.
**PGAudit logging precision:**
- **[Session](#session-logging):** Logs activity within a connection, such as a [psql](https://supabase.com/docs/guides/database/connecting-to-postgres#connecting-with-psql) connection.
- **[User](#user-logging):** Logs activity by a particular database user (for example, anon or postgres).
- **[User](#user-logging):** Logs activity by a particular database user (for example, `anon` or `postgres`).
- **[Global](#global-logging):** Logs activity across the entire database.
- **[Object](#object-logging):** Logs events related to specific database objects (for example, the auth.users table).
@@ -58,15 +58,15 @@ Although Session, User, and Global modes differ in their precision, they're all
These modes can monitor predefined categories of database operations:
| Category | What it Logs | Description |
| -------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| read | Data retrieval (SELECT, COPY) | Tracks what data is being accessed. |
| write | Data modification (INSERT, DELETE, UPDATE, TRUNCATE, COPY) | Tracks changes made to your database. |
| function | FUNCTION, PROCEDURE, and DO/END block executions | Tracks routine/function executions |
| role | User management actions (CREATE, DROP, ALTER on users and privileges) | Tracks changes to user permissions and access. |
| ddl | Schema changes (CREATE, DROP, ALTER statements) | Monitors modifications to your database structure (tables, indexes, etc.). |
| misc | Less common commands (FETCH, CHECKPOINT) | Captures obscure actions for deeper analysis if needed. |
| all | Everything above | Comprehensive logging for complete audit trails. |
| Category | What it Logs | Description |
| ---------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `read` | Data retrieval (SELECT, COPY) | Tracks what data is being accessed. |
| `write` | Data modification (INSERT, DELETE, UPDATE, TRUNCATE, COPY) | Tracks changes made to your database. |
| `function` | FUNCTION, PROCEDURE, and DO/END block executions | Tracks routine/function executions |
| `role` | User management actions (CREATE, DROP, ALTER on users and privileges) | Tracks changes to user permissions and access. |
| `ddl` | Schema changes (CREATE, DROP, ALTER statements) | Monitors modifications to your database structure (tables, indexes, etc.). |
| `misc` | Less common commands (FETCH, CHECKPOINT) | Captures obscure actions for deeper analysis if needed. |
| `all` | Everything above | Comprehensive logging for complete audit trails. |
Below is a limited example of how to assign PGAudit to monitor specific categories.
@@ -148,13 +148,13 @@ Use global logging cautiously. It can generate many logs and make it difficult t
</Admonition>
The below SQL configures PGAudit to record all events associated with the "postgres" role. Since it has extensive privileges, this effectively monitors all database activity.
The below SQL configures PGAudit to record all events associated with the `postgres` role. Since it has extensive privileges, this effectively monitors all database activity.
```sql
alter role "postgres" set pgaudit.log to 'all';
```
To check if the postgres role is auditing, execute the following command:
To check if the `postgres` role is auditing, execute the following command:
```sql
select
@@ -279,7 +279,7 @@ API requests are already recorded in the [API Edge Network](https://supabase.com
</Admonition>
To monitor all writes initiated by the Postgrest API roles:
To monitor all writes initiated by the PostgREST API roles:
```sql
alter role "authenticator" set pgaudit.log to 'write';
@@ -383,7 +383,7 @@ PGAudit allows settings to be applied to 3 different database scopes:
| Database | Specific database | ALTER DATABASE commands |
| Role | Specific user/role | ALTER ROLE commands |
Supabase limits full privileges for file system and database variables, meaning PGAudit modifications can only occur at the role level. Assigning PGAudit to the 'postgres' role grants it nearly complete visibility into the database, making role-level adjustments a practical alternative to configuring at the database or system level.
Supabase limits full privileges for file system and database variables, meaning PGAudit modifications can only occur at the role level. Assigning PGAudit to the `postgres` role grants it nearly complete visibility into the database, making role-level adjustments a practical alternative to configuring at the database or system level.
PGAudit's [official documentation](https://www.pgaudit.org) focuses on system and database level configs, but its docs officially supports role level configs, too.
@@ -11,7 +11,7 @@ tocVideo: 'agFsGDJxjwA'
While you may be able to store simple lat/long geographic coordinates as a set of decimals, it does not scale very well when you try to query through a large data set. PostGIS comes with special data types that are efficient, and indexable for high scalability.
The additional data types that PostGIS provides include [Point](https://postgis.net/docs/using_postgis_dbmanagement.html#Point), [Polygon](https://postgis.net/docs/using_postgis_dbmanagement.html#Polygon), [Linestring](https://postgis.net/docs/using_postgis_dbmanagement.html#LineString), and many more to represent different types of geographical data. In this guide, we will mainly focus on how to interact with `Point` type, which represents a single set of latitude and longitude. If you are interested in digging deeper, you can learn more about different data types on the [data management section of PostGIS docs](https://postgis.net/docs/using_postgis_dbmanagement.html).
The additional data types that PostGIS provides include [Point](https://postgis.net/docs/using_postgis_dbmanagement.html#Point), [Polygon](https://postgis.net/docs/using_postgis_dbmanagement.html#Polygon), [LineString](https://postgis.net/docs/using_postgis_dbmanagement.html#LineString), and many more to represent different types of geographical data. In this guide, we will mainly focus on how to interact with `Point` type, which represents a single set of latitude and longitude. If you are interested in digging deeper, you can learn more about different data types on the [data management section of PostGIS docs](https://postgis.net/docs/using_postgis_dbmanagement.html).
## Enable the extension
@@ -28,7 +28,7 @@ You can get started with PostGIS by enabling the PostGIS extension in your Supab
1. Go to the [Database](https://supabase.com/dashboard/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "postgis" and enable the extension.
3. Search for `postgis` and enable the extension.
4. In the confirmation prompt select "Create a new schema" and name it `gis` for example.
</TabPanel>
@@ -85,12 +85,16 @@ You can insert geographical data through SQL or through our API.
<h4>Restaurants</h4>
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | name | location |
| --- | ----------- | -------------------------------- |
| 1 | Supa Burger | lat: 40.807416, long: -73.946823 |
| 2 | Supa Pizza | lat: 40.807475, long: -73.94581 |
| 3 | Supa Taco | lat: 40.80629, long: -73.945826 |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -438,7 +442,7 @@ The [official PostGIS documentation](https://postgis.net/documentation/tips/tip-
</Admonition>
As of PostGIS 2.3 or newer, the PostGIS extension is no longer relocatable from one schema to another. If you need to move it from one schema to another for any reason (Eg. from the public schema to the extensions schema for security reasons), you would normally run a ALTER EXTENSION to relocate the schema. However, you will now to do the following steps:
As of PostGIS 2.3 or newer, the PostGIS extension is no longer relocatable from one schema to another. If you need to move it from one schema to another for any reason (e.g. from the public schema to the extensions schema for security reasons), you would normally run a ALTER EXTENSION to relocate the schema. However, you will now to do the following steps:
1. Backup your Database to prevent data loss - You can do this through the [CLI](https://supabase.com/docs/reference/cli/supabase-db-dump) or Postgres backup tools such as [pg_dumpall](https://www.postgresql.org/docs/current/backup-dump.html#BACKUP-DUMP-ALL)
@@ -4,7 +4,7 @@ title: 'RUM: improved inverted index for full-text search based on GIN index'
description: 'A GIN-like index with additional tree-organized data for each index entry'
---
[RUM](https://github.com/postgrespro/rum) is an extension which adds a RUM index to Postgresql.
[RUM](https://github.com/postgrespro/rum) is an extension which adds a RUM index to Postgres.
RUM index is based on GIN that stores additional per-entry information in a posting tree. For example, positional information of lexemes or timestamps. In comparison to GIN it can use this information to make faster index-only scans for:
@@ -18,10 +18,10 @@ combinations or phrases.
Main operators for ordering are:
tsvector `<=>` tsquery | float4 | Distance between tsvector and tsquery.
value `<=>` value | float8 | Distance between two values.
`tsvector` `<=>` `tsquery` | `float4` | Distance between `tsvector` and `tsquery`.
value `<=>` value | `float8` | Distance between two values.
Where value is timestamp, timestamptz, int2, int4, int8, float4, float8, money and oid
Where value is `timestamp`, `timestamptz`, `int2`, `int4`, `int8`, `float4`, `float8`, `money` and `oid`
## Usage
@@ -120,7 +120,7 @@ SELECT id, d, d `<=>` '2016-05-16 14:21:25' FROM tsts WHERE t @@ 'wr&qh' ORDER B
`rum_anyarray_ops`
This operator class stores anyarray elements with length of the array. It supports operators `&&`, `@>`, `<@`, `=`, `%` operators. It also supports ordering by `<=>` operator.
This operator class stores `anyarray` elements with length of the array. It supports operators `&&`, `@>`, `<@`, `=`, `%` operators. It also supports ordering by `<=>` operator.
```sql
CREATE TABLE test_array (i int2[]);
@@ -143,7 +143,7 @@ SELECT * FROM test_array WHERE i && '{1}' ORDER BY i `<=>` '{1}' ASC;
`rum_anyarray_addon_ops`
The does the same with anyarray index as `rum_tsvector_addon_ops` i.e. allows to order select results using distance
The does the same with `anyarray` index as `rum_tsvector_addon_ops` i.e. allows to order select results using distance
operator by attached column.
## Limitations
@@ -4,7 +4,7 @@ title: 'timescaledb: Time-Series data'
description: 'Scalable time-series data storage and analysis'
---
[timescaledb](https://docs.timescale.com/timescaledb/latest/) is a PostgreSQL extension designed for improved handling of time-series data. It provides a scalable, high-performance solution for storing and querying time-series data on top of a standard PostgreSQL database.
[`timescaledb`](https://docs.timescale.com/timescaledb/latest/) is a PostgreSQL extension designed for improved handling of time-series data. It provides a scalable, high-performance solution for storing and querying time-series data on top of a standard PostgreSQL database.
`timescaledb` uses a time-series-aware storage model and indexing techniques to improve performance of PostgreSQL in working with time-series data. The extension divides data into chunks based on time intervals, allowing it to scale efficiently, especially for large data sets. The data is then compressed, optimized for write-heavy workloads, and partitioned for parallel processing. `timescaledb` also includes a set of functions, operators, and indexes that work with time-series data to reduce query times, and make data easier to work with.
@@ -27,7 +27,7 @@ Supabase projects come with [TimescaleDB Apache 2 Edition](https://docs.timescal
1. Go to the [Database](https://supabase.com/dashboard/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "timescaledb" and enable the extension.
3. Search for `timescaledb` and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -27,7 +27,7 @@ Currently `uuid-ossp` extension is enabled by default and cannot be disabled.
1. Go to the [Database](https://supabase.com/dashboard/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "uuid-ossp" and enable the extension.
3. Search for `uuid-ossp` and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -30,7 +30,7 @@ For this guide we'll use the following example data:
>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------ |
@@ -40,7 +40,7 @@ For this guide we'll use the following example data:
| 4 | Green Eggs and Ham | Dr. Seuss | Sam has changing food preferences and eats unusually colored food. |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -301,14 +301,14 @@ data = supabase.from_('books').select().text_search('description', "'big'").exec
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ----------------------------------- | ----------------- | ----------------------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -420,14 +420,14 @@ data = supabase.from_('books').select().text_search('title_description', "little
</TabPanel>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | --------------------- | ---------------------- | ------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -507,13 +507,13 @@ data = supabase.from_('books').select().text_search('description', "'little' & '
</TabPanel>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ------ | ----------------- | -------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -593,14 +593,14 @@ response = client.from_('books').select().text_search('description', "'little' |
</TabPanel>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | --------------------- | ---------------------- | ------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -699,7 +699,7 @@ select * from search_books_by_title_prefix('Little+Puppy');
## Creating indexes
Now that we have Full Text Search working, let's create an `index`. This will allow Postgres to "build" the documents pre-emptively so that they
Now that we have Full Text Search working, let's create an `index`. This will allow Postgres to "build" the documents preemptively so that they
don't need to be created at the time we execute the query. This will make our queries much faster.
### Searchable columns
@@ -734,8 +734,7 @@ from books;
</TabPanel>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
```
| id | fts |
| --- | --------------------------------------------------------------------------------------------------------------- |
| 1 | 'anim':7 'bigger':6 'littl':10 'poki':9 'puppi':1,11 'slower':3 |
@@ -743,8 +742,7 @@ from books;
| 3 | 'big':5 'dream':6 'littl':1 'tootl':7 'toy':2 'train':3 |
| 4 | 'chang':3 'color':9 'eat':7 'egg':12 'food':4,10 'green':11 'ham':14 'prefer':5 'sam':1 'unus':8 |
| 5 | 'big':6 'drama':7 'ensu':8 'fire':15 'fourth':1 'goblet':13 'harri':9 'potter':10 'school':4 'start':5 'year':2 |
{/* <!-- vale on --> */}
```
</TabPanel>
</Tabs>
@@ -820,13 +818,13 @@ data = client.from_('books').select().text_search('fts', "'little' & 'big'").exe
</TabPanel>
<TabPanel id="data" label="Data">
{/* <!-- vale off --> */}
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description | fts |
| --- | ------ | ----------------- | -------------------------------- | ------------------------------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | 'big':5 'dream':6 'littl':1 'tootl':7 'toy':2 'train':3 |
{/* <!-- vale on --> */}
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -82,7 +82,7 @@ select hello_world();
const { data, error } = await supabase.rpc('hello_world')
```
Reference: [rpc()](../../reference/javascript/rpc)
Reference: [`rpc()`](../../reference/javascript/rpc)
</TabPanel>
<TabPanel id="dart" label="Dart">
@@ -92,7 +92,7 @@ final data = await supabase
.rpc('hello_world');
```
Reference: [rpc()](../../reference/dart/rpc)
Reference: [`rpc()`](../../reference/dart/rpc)
</TabPanel>
<TabPanel id="swift" label="Swift">
@@ -101,7 +101,7 @@ Reference: [rpc()](../../reference/dart/rpc)
try await supabase.rpc("hello_world").execute()
```
Reference: [rpc()](../../reference/swift/rpc)
Reference: [`rpc()`](../../reference/swift/rpc)
</TabPanel>
<TabPanel id="kotlin" label="Kotlin">
@@ -110,7 +110,7 @@ Reference: [rpc()](../../reference/swift/rpc)
val data = supabase.postgrest.rpc("hello_world")
```
Reference: [rpc()](../../reference/kotlin/rpc)
Reference: [`rpc()`](../../reference/kotlin/rpc)
</TabPanel>
<TabPanel id="python" label="Python">
@@ -119,7 +119,7 @@ Reference: [rpc()](../../reference/kotlin/rpc)
data = supabase.rpc('hello_world').execute()
```
Reference: [rpc()](../../reference/python/rpc)
Reference: [`rpc()`](../../reference/python/rpc)
</TabPanel>
</Tabs>
@@ -141,20 +141,24 @@ For example, if we had a database with some Star Wars data inside:
<h4>Planets</h4>
```
| id | name |
| --- | -------- |
| 1 | Tatooine |
| 2 | Alderaan |
| 3 | Kashyyyk |
```
<h4>People</h4>
```
| id | name | planet_id |
| --- | ---------------- | --------- |
| 1 | Anakin Skywalker | 1 |
| 2 | Luke Skywalker | 1 |
| 3 | Princess Leia | 2 |
| 4 | Chewbacca | 3 |
```
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -49,7 +49,7 @@ Then the CLI will automatically connect to your Supabase project whenever you ar
## Inspection commands
Below are the db inspection commands provided, grouped by different use cases.
Below are the `db` inspection commands provided, grouped by different use cases.
<Admonition type="note">
@@ -99,4 +99,4 @@ Learn more about pg_stats [here](https://supabase.com/docs/guides/database/exten
## Acknowledgements
Supabase CLI's inspect commands are heavily inspired by the <a href="https://github.com/heroku/heroku-pg-extras" target="_blank">pg-extras</a> tools.
Supabase CLI's inspect commands are heavily inspired by the <a href="https://github.com/heroku/heroku-pg-extras" target="_blank">`pg-extras`</a> tools.
@@ -117,6 +117,8 @@ values
2. Select the `books` table in the sidebar.
3. Click **+ Insert row** and add 5 rows with the following properties:
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | metadata |
| --- | ----------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | `json {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."}` |
@@ -125,6 +127,8 @@ values
| 4 | Green Eggs and Ham | Dr. Seuss | `json {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."}` |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | `json {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."}` |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="js" label="JavaScript">
@@ -15,7 +15,7 @@ OrioleDB addresses PostgreSQL's scalability limitations by removing bottlenecks
zoomable
/>
<Admonition type="info">
<Admonition type="note">
OrioleDB is in active development and currently has [certain limitations](https://www.orioledb.com/docs/usage/getting-started#current-limitations). Currently, only B-tree indexes are supported, so features like pg_vector's HNSW indexes are not yet available. An Index Access Method bridge to unlock support for all index types used with heap storage is under active development. In the Supabase OrioleDB image the default storage method has been updated to use OrioleDB, granting better performance out of the box.
@@ -78,7 +78,7 @@ create table blog_post (
OrioleDB tables always have a primary key. If it wasn't defined explicitly, a hidden primary key is created using the `ctid` column.
Additionally you can create secondary indexes.
<Admonition type="info">
<Admonition type="note">
Currently, only B-tree indexes are supported, so features like pg_vector's HNSW indexes are not yet available.
@@ -70,7 +70,7 @@ hideToc: true
Download your SSL certificate from Dashboard's [`Database Settings`](https://supabase.com/dashboard/project/_/settings/database).
In pgAdmin, navigate to the Parameters tab and select connection parameter as Root Certificate. Next navigate to the Root certificate input, it will open up a file-picker modal. Select the certificate you downloaded earlier and save the server details. PgAdmin should now be able to connect to your Postgres via SSL.
In pgAdmin, navigate to the Parameters tab and select connection parameter as Root Certificate. Next navigate to the Root certificate input, it will open up a file-picker modal. Select the certificate you downloaded earlier and save the server details. pgAdmin should now be able to connect to your Postgres via SSL.
</StepHikeCompact.Details>
@@ -267,7 +267,7 @@ const { subscription: authListener } = supabase.auth.onAuthStateChange(async (ev
})
```
For server-side logic you can use packages like [express-jwt](https://github.com/auth0/express-jwt), [koa-jwt](https://github.com/stiang/koa-jwt), [PyJWT](https://github.com/jpadilla/pyjwt), [dart_jsonwebtoken](https://pub.dev/packages/dart_jsonwebtoken), [Microsoft.AspNetCore.Authentication.JwtBearer](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer), etc.
For server-side logic you can use packages like [`express-jwt`](https://github.com/auth0/express-jwt), [`koa-jwt`](https://github.com/stiang/koa-jwt), [`PyJWT`](https://github.com/jpadilla/pyjwt), [dart_jsonwebtoken](https://pub.dev/packages/dart_jsonwebtoken), [Microsoft.AspNetCore.Authentication.JwtBearer](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer), etc.
## Conclusion
@@ -26,7 +26,7 @@ create table persons (
);
```
<Admonition>
<Admonition type="tip">
All the queries in this guide can be run using the [SQL Editor](https://supabase.com/dashboard/project/_/sql) in the Supabase Dashboard, or via `psql` if you're [connecting directly to the database](/docs/guides/database/connecting-to-postgres#direct-connections).
@@ -38,13 +38,13 @@ Your Postgres database is the core of your Supabase project, so it's important t
### Special symbols in passwords
If you use special symbols in your postgres password, you must remember to [percent-encode](https://en.wikipedia.org/wiki/Percent-encoding) your password later if using the postgres connection string, for example, `postgresql://postgres.projectref:p%3Dword@aws-0-us-east-1.pooler.supabase.com:6543/postgres`
If you use special symbols in your Postgres password, you must remember to [percent-encode](https://en.wikipedia.org/wiki/Percent-encoding) your password later if using the Postgres connection string, for example, `postgresql://postgres.projectref:p%3Dword@aws-0-us-east-1.pooler.supabase.com:6543/postgres`
### Changing your project password
When you created your project you were also asked to enter a password. This is actually the password for the `postgres` role in your database. You can update this from the Dashboard under the [database settings](https://supabase.com/dashboard/project/_/settings/database) page. You should _never_ give this to third-party service unless you absolutely trust them. Instead, we recommend that you create a new user for every service that you want to give access too. This will also help you with debugging - you can see every query that each role is executing in your database within `pg_stat_statements`.
Changing the password does not result in any downtime. All connected services, such as postgrest, pgbouncer, and other Supabase managed services, are automatically updated to use the latest password to ensure availability. However, if you have any external services connecting to the Supabase database using hardcoded username/password credentials, a manual update will be required.
Changing the password does not result in any downtime. All connected services, such as PostgREST, PgBouncer, and other Supabase managed services, are automatically updated to use the latest password to ensure availability. However, if you have any external services connecting to the Supabase database using hardcoded username/password credentials, a manual update will be required.
## Granting permissions
@@ -72,7 +72,7 @@ create role "child_role_name" inherit "parent_role_name";
### Preventing inheritance
In some cases, you might want to prevent a role from having a child relationship (typically superuser roles). You can prevent inheritance relations using NOINHERIT:
In some cases, you might want to prevent a role from having a child relationship (typically superuser roles). You can prevent inheritance relations using `NOINHERIT`:
```sql
alter role "child_role_name" noinherit;
@@ -13,7 +13,7 @@ RLS is incredibly powerful and flexible, allowing you to write complex SQL rules
RLS is a Postgres primitive and can provide "[defense in depth](<https://en.wikipedia.org/wiki/Defense_in_depth_(computing)>)" to protect your data from malicious actors even when accessed through third-party tooling.
<Admonition type="info">
<Admonition type="note">
You should _always_ enable RLS on tables created in a public schema. This is done for you when you create a table with the Table Editor. If you create one in raw SQL or with the SQL Editor, remember to enable RLS yourself.
@@ -25,7 +25,7 @@ select pg_create_logical_replication_slot('example_slot', 'pgoutput');
3. Now we will connect to our **external database** and subscribe to our `publication` Note: ):
<Admonition type="info">
<Admonition type="note">
This will need a direct connection to your database and you can find the connection info in the [Dashboard](https://supabase.com/dashboard/project/_/settings/database).
@@ -42,7 +42,7 @@ PUBLICATION example_pub
WITH (copy_data = true, create_slot=false, slot_name=example_slot);
```
<Admonition type="info">
<Admonition type="note">
`create_slot` is set to `false` because `slot_name` is provided and the slot was already created in Step 2.
To copy data from before the slot was created, set `copy_data` to `true`.
@@ -71,8 +71,7 @@ alter role example_role set statement_timeout = '10min'; -- could also use secon
```
<Admonition type="tip">
If you are changing the timeout for the Supabase Client API calls, you will need to reload
postgREST to reflect the timeout changes by running the following script:
If you are changing the timeout for the Supabase Client API calls, you will need to reload PostgREST to reflect the timeout changes by running the following script:
```sql
NOTIFY pgrst, 'reload config';
@@ -161,16 +160,16 @@ Go to the [Query Performance page](/dashboard/project/_/advisors/query-performan
Each API server uses a designated user for connecting to the database:
| Role | API/Tool |
| -------------------------- | ------------------------------------------------------------------------- |
| supabase_admin | Used by Supabase to configure projects and for monitoring |
| authenticator | PostgREST |
| supabase_auth_admin | Auth |
| supabase_storage_admin | Storage |
| supabase_realtime_admin | Realtime |
| supabase_replication_admin | Synchronizes Read Replicas |
| postgres | Supabase Dashboard and External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
| Custom roles | External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
| Role | API/Tool |
| ---------------------------- | ------------------------------------------------------------------------- |
| `supabase_admin` | Used by Supabase to configure projects and for monitoring |
| `authenticator` | PostgREST |
| `supabase_auth_admin` | Auth |
| `supabase_storage_admin` | Storage |
| `supabase_realtime_admin` | Realtime |
| `supabase_replication_admin` | Synchronizes Read Replicas |
| `postgres` | Supabase Dashboard and External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
| Custom roles | External Tools (e.g., Prisma, SQLAlchemy, PSQL...) |
Filter by the `parsed.user_name` field to only retrieve logs made by specific users:
+8 -8
View File
@@ -17,7 +17,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Create a custom user for Prisma">
- In the [SQL Editor](https://supabase.com/dashboard/project/_/sql/new), create a Prisma db-user with full privileges on the public schema.
- In the [SQL Editor](https://supabase.com/dashboard/project/_/sql/new), create a Prisma DB user with full privileges on the public schema.
- This gives you better control over Prisma's access and makes it easier to monitor using Supabase tools like the [Query Performance Dashboard](https://supabase.com/dashboard/project/_/advisors/query-performance) and [Log Explorer](https://supabase.com/dashboard/project/_/logs/explorer).
<Admonition type="note" label="password manager">
@@ -56,7 +56,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Create a Prisma Project">
Create a new prisma Project on your computer
Create a new Prisma Project on your computer
</StepHikeCompact.Details>
<StepHikeCompact.Code>
@@ -166,7 +166,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
postgres://prisma.[PROJECT-REF]...
```
In your schema.prisma file, edit your datasource db configs to reference your DIRECT_URL
In your schema.prisma file, edit your `datasource db` configs to reference your DIRECT_URL
```text schema.prisma
datasource db {
provider = "postgresql"
@@ -269,7 +269,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
npx prisma db pull
```
Create a migraton file
Create a migration file
```bash
mkdir -p prisma/migrations/0_init_supabase
```
@@ -295,7 +295,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
pnpx prisma db pull
```
Create a migraton file
Create a migration file
```bash
mkdir -p prisma/migrations/0_init_supabase
```
@@ -321,7 +321,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
yarn dlx prisma db pull
```
Create a migraton file
Create a migration file
```bash
mkdir -p prisma/migrations/0_init_supabase
```
@@ -347,7 +347,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
bunx prisma db pull
```
Create a migraton file
Create a migration file
```bash
mkdir -p prisma/migrations/0_init_supabase
```
@@ -378,7 +378,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
</StepHikeCompact.Step>
<StepHikeCompact.Step step={5}>
<StepHikeCompact.Details title="Install the prisma client">
Install the prisma client and generate its model
Install the Prisma client and generate its model
</StepHikeCompact.Details>
<StepHikeCompact.Code>
+10 -10
View File
@@ -5,13 +5,13 @@ subtitle: Troubleshooting Supavisor errors
Supavisor logs are available under [Pooler Logs](/dashboard/project/_/logs/pooler-logs) in the Dashboard. The following are common errors and their solutions:
| Error Type | Description | Resolution Link |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Max client connections reached | This error happens when the number of connections to Supavisor is more than [the allowed limit of your compute add-on](https://supabase.com/docs/guides/platform/compute-add-ons). | Follow this [guide](https://github.com/orgs/supabase/discussions/22305) to resolve. |
| Connection failed \{:error, :eaddrnotavail} to 'db.xxx.supabase.co':5432 | Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond. | N/A |
| Connection failed \{:error, :nxdomain} to 'db.xxx.supabase.co':5432 | Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond. | N/A |
| Connection closed when state was authentication | This error happens when either the database doesn’t exist or if the user doesn't have the right credentials. | N/A |
| Subscribe error: \{:error, :worker_not_found} | This log event is emitted when the client tries to connect to the database, but Supavisor does not have the necessary information to route the connection. Try reconnecting to the database as it can take some time for the project information to propagate to Supavisor. | N/A |
| Subscribe error: \{:error, \{:badrpc, \{:error, \{:erpc, :timeout}}}} | This is a timeout error when the communication between different Supavisor nodes takes longer than expected. Try reconnecting to the database. | N/A |
| Terminating with reason :client_termination when state was :busy | This error happens when the client terminates the connection before the connection with the database is completed. | N/A |
| Error: received invalid response to GSSAPI negotiation: S | This error happens due to "gssencmode" parameter not set to disabled. | Follow this [guide](https://github.com/orgs/supabase/discussions/30173) to resolve. |
| Error Type | Description | Resolution Link |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Max client connections reached | This error happens when the number of connections to Supavisor is more than [the allowed limit of your compute add-on](https://supabase.com/docs/guides/platform/compute-add-ons). | Follow this [guide](https://github.com/orgs/supabase/discussions/22305) to resolve. |
| Connection failed `{:error, :eaddrnotavail}` to 'db.xxx.supabase.co':5432 | Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond. | N/A |
| Connection failed `{:error, :nxdomain}` to 'db.xxx.supabase.co':5432 | Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond. | N/A |
| Connection closed when state was authentication | This error happens when either the database doesn’t exist or if the user doesn't have the right credentials. | N/A |
| Subscribe error: `{:error, :worker_not_found}` | This log event is emitted when the client tries to connect to the database, but Supavisor does not have the necessary information to route the connection. Try reconnecting to the database as it can take some time for the project information to propagate to Supavisor. | N/A |
| Subscribe error: `{:error, {:badrpc, {:error, {:erpc, :timeout}}}}` | This is a timeout error when the communication between different Supavisor nodes takes longer than expected. Try reconnecting to the database. | N/A |
| Terminating with reason :client_termination when state was :busy | This error happens when the client terminates the connection before the connection with the database is completed. | N/A |
| Error: received invalid response to GSSAPI negotiation: S | This error happens due to `gssencmode` parameter not set to disabled. | Follow this [guide](https://github.com/orgs/supabase/discussions/30173) to resolve. |
+54 -46
View File
@@ -10,6 +10,8 @@ Tables are where you store your data.
Tables are similar to excel spreadsheets. They contain columns and rows.
For example, this table has 3 "columns" (`id`, `name`, `description`) and 4 "rows" of data:
{/* supa-mdx-lint-disable Rule003Spelling */}
| `id` | `name` | `description` |
| ---- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | The Phantom Menace | Two Jedi escape a hostile blockade to find allies and come across a young boy who may bring balance to the Force. |
@@ -17,6 +19,8 @@ For example, this table has 3 "columns" (`id`, `name`, `description`) and 4 "row
| 3 | Revenge of the Sith | As Obi-Wan pursues a new threat, Anakin acts as a double agent between the Jedi Council and Palpatine and is lured into a sinister plan to rule the galaxy. |
| 4 | Star Wars | Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee and two droids to save the galaxy from the Empire's world-destroying battle station. |
{/* supa-mdx-lint-enable Rule003Spelling */}
There are a few important differences from a spreadsheet, but it's a good starting point if you're new to Relational databases.
## Creating tables
@@ -91,51 +95,51 @@ Every column is a predefined type. PostgreSQL provides many [default types](http
<details>
<summary>Show/Hide default data types</summary>
| `Name` | `Aliases` | `Description` |
| --------------------------------- | ----------- | ---------------------------------------------------------------- |
| bigint | int8 | signed eight-byte integer |
| bigserial | serial8 | autoincrementing eight-byte integer |
| bit | | fixed-length bit string |
| bit varying | varbit | variable-length bit string |
| boolean | bool | logical Boolean (true/false) |
| box | | rectangular box on a plane |
| bytea | | binary data (“byte array”) |
| character | char | fixed-length character string |
| character varying | varchar | variable-length character string |
| cidr | | IPv4 or IPv6 network address |
| circle | | circle on a plane |
| date | | calendar date (year, month, day) |
| double precision | float8 | double precision floating-point number (8 bytes) |
| inet | | IPv4 or IPv6 host address |
| integer | int, int4 | signed four-byte integer |
| interval \[ fields \] | | time span |
| json | | textual JSON data |
| jsonb | | binary JSON data, decomposed |
| line | | infinite line on a plane |
| lseg | | line segment on a plane |
| macaddr | | MAC (Media Access Control) address |
| macaddr8 | | MAC (Media Access Control) address (EUI-64 format) |
| money | | currency amount |
| numeric | decimal | exact numeric of selectable precision |
| path | | geometric path on a plane |
| pg_lsn | | PostgreSQL Log Sequence Number |
| pg_snapshot | | user-level transaction ID snapshot |
| point | | geometric point on a plane |
| polygon | | closed geometric path on a plane |
| real | float4 | single precision floating-point number (4 bytes) |
| smallint | int2 | signed two-byte integer |
| smallserial | serial2 | autoincrementing two-byte integer |
| serial | serial4 | autoincrementing four-byte integer |
| text | | variable-length character string |
| time \[ without time zone \] | | time of day (no time zone) |
| time with time zone | timetz | time of day, including time zone |
| timestamp \[ without time zone \] | | date and time (no time zone) |
| timestamp with time zone | timestamptz | date and time, including time zone |
| tsquery | | text search query |
| tsvector | | text search document |
| txid_snapshot | | user-level transaction ID snapshot (deprecated; see pg_snapshot) |
| uuid | | universally unique identifier |
| xml | | XML data |
| `Name` | `Aliases` | `Description` |
| --------------------------------- | ------------- | ---------------------------------------------------------------- |
| `bigint` | `int8` | signed eight-byte integer |
| `bigserial` | `serial8` | autoincrementing eight-byte integer |
| `bit` | | fixed-length bit string |
| `bit varying` | `varbit` | variable-length bit string |
| `boolean` | `bool` | logical Boolean (true/false) |
| `box` | | rectangular box on a plane |
| `bytea` | | binary data (“byte array”) |
| `character` | `char` | fixed-length character string |
| `character varying` | `varchar` | variable-length character string |
| `cidr` | | IPv4 or IPv6 network address |
| `circle` | | circle on a plane |
| `date` | | calendar date (year, month, day) |
| `double precision` | `float8` | double precision floating-point number (8 bytes) |
| `inet` | | IPv4 or IPv6 host address |
| `integer` | `int`, `int4` | signed four-byte integer |
| `interval [ fields ]` | | time span |
| `json` | | textual JSON data |
| `jsonb` | | binary JSON data, decomposed |
| `line` | | infinite line on a plane |
| `lseg` | | line segment on a plane |
| `macaddr` | | MAC (Media Access Control) address |
| `macaddr8` | | MAC (Media Access Control) address (EUI-64 format) |
| `money` | | currency amount |
| `numeric` | `decimal` | exact numeric of selectable precision |
| `path` | | geometric path on a plane |
| `pg_lsn` | | PostgreSQL Log Sequence Number |
| `pg_snapshot` | | user-level transaction ID snapshot |
| `point` | | geometric point on a plane |
| `polygon` | | closed geometric path on a plane |
| `real` | `float4` | single precision floating-point number (4 bytes) |
| `smallint` | `int2` | signed two-byte integer |
| `smallserial` | `serial2` | autoincrementing two-byte integer |
| `serial` | `serial4` | autoincrementing four-byte integer |
| `text` | | variable-length character string |
| `time [ without time zone ]` | | time of day (no time zone) |
| `time with time zone` | `timetz` | time of day, including time zone |
| `timestamp [ without time zone ]` | | date and time (no time zone) |
| `timestamp with time zone` | `timestamptz` | date and time, including time zone |
| `tsquery` | | text search query |
| `tsvector` | | text search document |
| `txid_snapshot` | | user-level transaction ID snapshot (deprecated; see pg_snapshot) |
| `uuid` | | universally unique identifier |
| `xml` | | XML data |
</details>
@@ -300,7 +304,7 @@ supabase
### Bulk data loading
When inserting large data sets it's best to use PostgreSQL's [COPY](https://www.postgresql.org/docs/current/sql-copy.html) command.
This loads data directly from a file into a table. There are several file formats available for copying data: text, csv, binary, JSON, etc.
This loads data directly from a file into a table. There are several file formats available for copying data: text, CSV, binary, JSON, etc.
For example, if you wanted to load a CSV file into your movies table:
@@ -442,12 +446,16 @@ Say we have the following tables from a database of a university:
**`students`**
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | name | type |
| --- | ---------------- | ------------- |
| 1 | Princess Leia | undergraduate |
| 2 | Yoda | graduate |
| 3 | Anakin Skywalker | graduate |
{/* supa-mdx-lint-enable Rule003Spelling */}
**`courses`**
| id | title | code |
@@ -18,7 +18,7 @@ You can use the Supabase CLI to test your database. The minimum required version
## Creating a test
Create a tests folder inside the supabase folder:
Create a tests folder inside the `supabase` folder:
```bash
mkdir -p ./supabase/tests/database
@@ -50,7 +50,7 @@ Preview Branch instances contain no data by default. You must include a seed fil
## Git providers
To manage code changes, your Supabase project must be connected to a Git repository. At this stage, we only support [GitHub](#branching-with-github). If you are interested in other Git providers, join the [discussion](https://github.com/orgs/supabase/discussions/18936) for GitLab, BitBucket, and non-Git based Branching.
To manage code changes, your Supabase project must be connected to a Git repository. At this stage, we only support [GitHub](#branching-with-github). If you are interested in other Git providers, join the [discussion](https://github.com/orgs/supabase/discussions/18936) for GitLab, Bitbucket, and non-Git based Branching.
### Branching with GitHub
@@ -337,7 +337,7 @@ The Supabase CLI provides two options: [manual migrations](https://supabase.com/
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Make schema changes locally" fullWidth>
Start supabase locally:
Start Supabase locally:
<CH.Code lineNumbers={false}>
@@ -135,7 +135,7 @@ supabase migration up
Finally, you should see the `department` column added to your `employees` table in the local Dashboard.
<Admonition type="info">
<Admonition type="note">
View the [complete code](https://github.com/supabase/supabase/tree/master/examples/database/employees) for this example on GitHub.
@@ -42,7 +42,7 @@ After developing your project and deciding it's Production Ready, you should run
- Tools like [k6](https://k6.io/) can simulate traffic from many different users.
- Upgrade your database if you require more resources. If you need anything beyond what is listed, contact enterprise@supabase.io.
- If you are expecting a surge in traffic (for a big launch) and are on a Team or Enterprise Plan, [contact support](https://supabase.com/dashboard/support/new) with more details about your launch and we'll help keep an eye on your project.
- If you expect your database size to be > 4 GB, [enable](https://supabase.com/dashboard/project/_/settings/addons?panel=pitr) the Point in Time Recovery (PITR) addon. Daily backups can take up resources from your database when the backup is in progress. PITR is more resource efficient, since only the changes to the database are backed up.
- If you expect your database size to be > 4 GB, [enable](https://supabase.com/dashboard/project/_/settings/addons?panel=pitr) the Point in Time Recovery (PITR) add-on. Daily backups can take up resources from your database when the backup is in progress. PITR is more resource efficient, since only the changes to the database are backed up.
- Check and review issues in your database using [Performance Advisor](https://supabase.com/dashboard/project/_/database/performance-advisor).
## Availability
@@ -75,7 +75,7 @@ After developing your project and deciding it's Production Ready, you should run
| ------------------------------------------------ | -------------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| All endpoints that send emails | `/auth/v1/signup` `/auth/v1/recover` `/auth/v1/user`[^1] | Sum of combined requests | As of 3 Sep 2024, this has been updated to <SharedData data="config">auth.rate_limits.email.inbuilt_smtp_per_hour.value</SharedData> emails per hour. You can only change this with your own [custom SMTP setup](/docs/guides/auth/auth-smtp). |
| All endpoints that send One-Time-Passwords (OTP) | `/auth/v1/otp` | Sum of combined requests | Defaults to 360 OTPs per hour. Is customizable. |
| Send OTPs or magiclinks | `/auth/v1/otp` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. |
| Send OTPs or magic links | `/auth/v1/otp` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. |
| Signup confirmation request | `/auth/v1/signup` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. |
| Password Reset Request | `/auth/v1/recover` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. |
| Verification requests | `/auth/v1/verify` | IP Address | 360 requests per hour (with bursts up to 30 requests) |
@@ -97,7 +97,7 @@ After developing your project and deciding it's Production Ready, you should run
- When working with enterprise systems, email scanners may scan and make a `GET` request to the reset password link or sign up link in your email. Since links in Supabase Auth are single use, a user who opens an email post-scan to click on a link will receive an error. To get around this problem,
consider altering the email template to replace the original magic link with a link to a domain you control. The domain can present the user with a "Sign-in" button which redirect the user to the original magic link URL when clicked.
- When using a custom SMTP service, some services might have link tracking enabled which may overwrite or malform the email confirmation links sent by Supabase Auth. To prevent this from happening, we recommend that you disable link tracking when using a custom SMTP service.
- When using a custom SMTP service, some services might have link tracking enabled which may overwrite or disform the email confirmation links sent by Supabase Auth. To prevent this from happening, we recommend that you disable link tracking when using a custom SMTP service.
## Next steps
@@ -146,7 +146,7 @@ Commit the new migration script to git and you are ready to deploy.
<Admonition type="tip">
Alternatively, you may pass in the `--use-migra` experimental flag to generate a more concise migration using [migra](https://github.com/djrobstep/migra).
Alternatively, you may pass in the `--use-migra` experimental flag to generate a more concise migration using [`migra`](https://github.com/djrobstep/migra).
Without the `-f` file flag, the output is written to stdout by default.
@@ -360,7 +360,7 @@ Once pushed, check that the migration version is up to date for both local and r
supabase migration list
```
### Permission denied on db pull
### Permission denied on `db pull`
If you have been using Supabase hosted projects for a long time, you might encounter the following permission error when executing `db pull`.
@@ -378,7 +378,7 @@ grant all on all functions in schema graphql to postgres, anon, authenticated, s
grant all on all sequences in schema graphql to postgres, anon, authenticated, service_role;
```
### Permission denied on db push
### Permission denied on `db push`
If you created a table through Supabase dashboard, and your new migration script contains `ALTER TABLE` statements, you might run into permission error when applying them on staging or production databases.
@@ -61,7 +61,7 @@ Supabase offers a lot of opportunities for flexibly integrating with third-party
- Calls to external APIs within Postgres functions or triggers
- Calls to external APIs within Edge Functions
You are free to use and integrate with any service, but you're also responsible for ensuring that the performance, availability, and security of the services you use match up with your application's requirements. We do not monitor for outages or performance issues within integrations with third-party services. Depending on the implementation, an issue with such an integration could also result in performance degradataion or an outage for your Supabase project.
You are free to use and integrate with any service, but you're also responsible for ensuring that the performance, availability, and security of the services you use match up with your application's requirements. We do not monitor for outages or performance issues within integrations with third-party services. Depending on the implementation, an issue with such an integration could also result in performance degradation or an outage for your Supabase project.
If your application architecture relies on such integrations, you should monitor the relevant logs and metrics to ensure optimal performance.
@@ -165,7 +165,7 @@ curl --get "http://localhost:54321/functions/v1/ollama-test" \
</TabPanel>
<TabPanel id="llamafile" label="Mozilla Llamafile">
Follow the [Llamafile Quickstart](https://github.com/Mozilla-Ocho/llamafile?tab=readme-ov-file#quickstart) to download an run a llamafile locally on your machine.
Follow the [Llamafile Quickstart](https://github.com/Mozilla-Ocho/llamafile?tab=readme-ov-file#quickstart) to download an run a Llamafile locally on your machine.
Since Llamafile provides an OpenAI API compatible server, you can either use it with `@supabase/functions-js` or with the official OpenAI Deno SDK.
@@ -190,7 +190,7 @@ Create a new function with the following code
supabase functions new llamafile-test
```
<Admonition type="info">
<Admonition type="note">
Note that the model parameter doesn't have any effect here! The model depends on which Llamafile is currently running!
@@ -246,7 +246,7 @@ Create a new function with the following code
supabase functions new llamafile-test
```
<Admonition type="info">
<Admonition type="note">
Note that the model parameter doesn't have any effect here! The model depends on which Llamafile is currently running!
@@ -43,7 +43,7 @@ Deno.serve(async (req) => {
})
```
<Admonition type="warning">
<Admonition type="caution">
Edge functions have a runtime memory limit of 150MB. Overly large compressed payloads may result in an out-of-memory error.
@@ -34,7 +34,7 @@ Learn more about npm specifiers and Node built-in APIs in [Deno's documentation]
### JSR
You can import JS modules published to [JSR](https://jsr.io/) (eg: Deno's standard library), using the `jsr:` specifier:
You can import JS modules published to [JSR](https://jsr.io/) (e.g.: Deno's standard library), using the `jsr:` specifier:
```ts
import path from 'jsr:@std/path@1.0.8'
@@ -57,7 +57,7 @@ There are two ways to manage your dependencies in Supabase Edge Functions:
### Using deno.json (recommended)
<Admonition type="info">
<Admonition type="note">
This feature requires Supabase CLI version 1.215.0 or higher.
@@ -14,7 +14,7 @@ Ephemeral storage will reset on each function invocation. This means the files y
Here are some use cases where ephemeral storage can be useful:
- Unzip an archive of CSVs and then add them as records to the DB
- Custom image manipulation workflows (using [MagickWasm](https://supabase.com/docs/guides/functions/examples/image-manipulation))
- Custom image manipulation workflows (using [`magick-wasm`](https://supabase.com/docs/guides/functions/examples/image-manipulation))
You can use [Background Tasks](https://supabase.com/docs/guides/functions/background-tasks) to handle slow file processing outside of a request.
@@ -45,9 +45,9 @@ Deno.serve(async (req) => {
### Unavailable APIs
Currently, the synchronous APIs (eg: `Deno.writeFileSync` or `Deno.mkdirSync`) for creating or writing files are not supported.
Currently, the synchronous APIs (e.g. `Deno.writeFileSync` or `Deno.mkdirSync`) for creating or writing files are not supported.
You can use sync variations of read APIs (eg: `Deno.readFileSync`).
You can use sync variations of read APIs (e.g. `Deno.readFileSync`).
### Limits
Loaded 100 of 188 files, more files were not shown because too many files have changed in this diff. Show more