diff --git a/README.md b/README.md index 5cd68c3014de8..da83a9e1e4e1a 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ You can also [self-host](https://supabase.com/docs/guides/hosting/overview) and - [pg_graphql](http://github.com/supabase/pg_graphql/) a PostgreSQL extension that exposes a GraphQL API - [Storage](https://github.com/supabase/storage-api) provides a RESTful interface for managing Files stored in S3, using Postgres to manage permissions. - [postgres-meta](https://github.com/supabase/postgres-meta) is a RESTful API for managing your Postgres, allowing you to fetch tables, add roles, and run queries, etc. -- [GoTrue](https://github.com/netlify/gotrue) is an SWT based API for managing users and issuing SWT tokens. +- [GoTrue](https://github.com/supabase/gotrue) is an JWT based API for managing users and issuing JWT tokens. - [Kong](https://github.com/Kong/kong) is a cloud-native API gateway. #### Client libraries diff --git a/apps/docs/components/Extensions.tsx b/apps/docs/components/Extensions.tsx index b7b7260cd6408..b49c5ad83d34d 100644 --- a/apps/docs/components/Extensions.tsx +++ b/apps/docs/components/Extensions.tsx @@ -3,14 +3,25 @@ import React, { useState } from 'react' import { GlassPanel, IconLink, IconX, Input } from 'ui' import extensions from '../data/extensions.json' -type extension = { +type Extension = { name: string comment: string tags: string[] - link?: string + link: string } -function getUniqueTags(json: extension[]) { +type LinkTarget = React.ComponentProps<'a'>['target'] + +function getLinkTarget(link: string): LinkTarget { + // Link is relative, open in the same tab + if (link.startsWith('/')) { + return '_self' + } + // Link is external, open in a new tab + return '_blank' +} + +function getUniqueTags(json: Extension[]): string[] { const tags = [] for (const item of json) { if (item.tags) { @@ -21,12 +32,12 @@ function getUniqueTags(json: extension[]) { } export default function Extensions() { - const [searchTerm, setSearchTerm] = useState('') - const [filters, setFilters] = useState([]) + const [searchTerm, setSearchTerm] = useState('') + const [filters, setFilters] = useState([]) const tags = getUniqueTags(extensions) - function handleChecked(tag) { + function handleChecked(tag: string) { if (filters.includes(tag)) { setFilters(filters.filter((x) => x !== tag)) } else { @@ -94,15 +105,8 @@ export default function Extensions() { filters.length === 0 ? x : x.tags.some((item) => filters.includes(item)) ) .map((extension) => ( - - + +

{extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)} diff --git a/apps/docs/components/HomePageCover.tsx b/apps/docs/components/HomePageCover.tsx index 597e64e817447..e760c411dc38a 100644 --- a/apps/docs/components/HomePageCover.tsx +++ b/apps/docs/components/HomePageCover.tsx @@ -77,7 +77,7 @@ const HomePageCover = (props) => { Discover how to set up a database to an app making queries in just a few minutes.

-
+
{frameworks.map((framework, i) => ( @@ -98,7 +98,7 @@ const HomePageCover = (props) => { return (
-
+

{props.meta?.title}

@@ -108,7 +108,7 @@ const HomePageCover = (props) => {

-
+
diff --git a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx b/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx index 6925319d68d2a..4d2e53f6ea257 100644 --- a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx @@ -1,3 +1,5 @@ +import { products } from 'shared-data' + type HomeMenuIcon = { width?: number height?: number @@ -50,7 +52,7 @@ export function IconMenuAuth({ width = 16, height = 16 }: HomeMenuIcon) { xmlns="http://www.w3.org/2000/svg" > +### Storage Location + +Currently, all BigQuery datasets stored and managed by Analytics, whether via CLI or self-hosted, will default to the US region. + ## Production Recommendations To self-host in a production setting, we recommend performing the following for a better experience. diff --git a/apps/docs/layouts/SiteLayout.tsx b/apps/docs/layouts/SiteLayout.tsx index adc866288b075..b24019de13994 100644 --- a/apps/docs/layouts/SiteLayout.tsx +++ b/apps/docs/layouts/SiteLayout.tsx @@ -96,7 +96,7 @@ const levelsData = { }, reference_swift_v0: { icon: '/docs/img/icons/menu/reference-swift', - name: 'Swift Reference v1.0', + name: 'Swift Reference v0.0', }, reference_kotlin_v0: { icon: '/docs/img/icons/menu/reference-kotlin', diff --git a/apps/docs/pages/guides/ai/choosing-compute-addon.mdx b/apps/docs/pages/guides/ai/choosing-compute-addon.mdx new file mode 100644 index 0000000000000..1a27b1e52cd54 --- /dev/null +++ b/apps/docs/pages/guides/ai/choosing-compute-addon.mdx @@ -0,0 +1,167 @@ +import Layout from '~/layouts/DefaultGuideLayout' +import { Tabs } from 'ui' +export const TabPanel = Tabs.Panel + +export const meta = { + id: 'ai-choosing-compute-addon', + title: 'Choosing Compute Add-on', + description: 'Choosing the right Compute Add-on for your workload.', + subtitle: 'Choosing the right Compute Add-on for your workload.', + sidebar_label: 'Choosing Compute Add-on', +} + +This guide will help you choose the right Compute Add-on for your workload. We'll provide general guidance, as it is impossible to provide specific instructions for every possible use case. The goal is to give you a starting point from which you can make your own benchmarks and optimizations. + +Note that it is only useful for index searches, not for sequential scans. Sequential scans will result to significantly higher latencies and lower throughput, but will guarantee 100% precision and will not be RAM bound. Therefore it is possible to use a smaller plan for sequential scans. + +For more information about engineering at scale, see our [Engineering for Scale](/docs/guides/ai/engineering-for-scale) guide. + +## Simple workloads + +We've run a set of benchmarks using + +- The [dbpedia-entities-openai-1M](https://huggingface.co/datasets/KShivendu/dbpedia-entities-openai-1M) dataset. This dataset contains 1,000,000 embeddings for text, with each embedding being 1536 dimensions made using OpenAI API. +- The [gist-960-angular](http://corpus-texmex.irisa.fr/) dataset. This dataset contains 1,000,000 embeddings for images, with each embedding being 960 dimensions. +- The [GloVe Reddit comments](https://nlp.stanford.edu/projects/glove/) dataset, which contains 1,623,397 embeddings for words, with each embedding being 512 dimensions. + +We used [Vecs](https://github.com/supabase/vecs) to create a collection, upload the embeddings to a single table, and create an `inner-product` index for the embedding column. We then ran a series of queries to measure the performance of different compute add-ons: + +### Results + + + + +Emdeddings of 1536 dimensions by OpenAI for dbpedia dataset with 1,000,000 vectors. + +| Plan | Vectors | Lists | RPS | Latency Mean | Latency p95 | RAM Usage | RAM | +| ------ | --------- | ----- | ---- | ------------ | ----------- | ------------------ | ------ | +| Free | 20,000 | 40 | 135 | 0.372 sec | 0.412 sec | 1 GB + 200 Mb Swap | 1 GB | +| Small | 50,000 | 100 | 140 | 0.357 sec | 0.398 sec | 1.8 GB | 2 GB | +| Medium | 100,000 | 200 | 130 | 0.383 sec | 0.446 sec | 3.7 GB | 4 GB | +| Large | 250,000 | 500 | 130 | 0.378 sec | 0.434 sec | 7 GB | 8 GB | +| XL | 500,000 | 1000 | 235 | 0.213 sec | 0.271 sec | 13.5 GB | 16 GB | +| 2XL | 1,000,000 | 2000 | 380 | 0.133 sec | 0.236 sec | 30 GB | 32 GB | +| 4XL | 1,000,000 | 2000 | 720 | 0.068 sec | 0.120 sec | 35 GB | 64 GB | +| 8XL | 1,000,000 | 2000 | 1250 | 0.039 sec | 0.066 sec | 38 GB | 128 GB | +| 12XL | 1,000,000 | 2000 | 1600 | 0.030 sec | 0.052 sec | 41 GB | 192 GB | +| 16XL | 1,000,000 | 2000 | 1790 | 0.029 sec | 0.051 sec | 45 GB | 256 GB | + +For 1,000,000 vectors 10 probes results to precision of 0.91. And for 500,000 vectors and below 10 probes results to precision in the range of 0.95 - 0.99. To increase precision, you need to increase the number of probes. + + + + +Emdeddings of 1536 dimensions by OpenAI for dbpedia dataset with 1,000,000 vectors. + +| Plan | Vectors | Lists | RPS | Latency Mean | Latency p95 | RAM Usage | RAM | +| ------ | --------- | ----- | --- | ------------ | ----------- | --------- | ------ | +| Free | 20,000 | 40 | - | - | - | - | 1 GB | +| Small | 50,000 | 100 | - | - | - | - | 2 GB | +| Medium | 100,000 | 200 | - | - | - | - | 4 GB | +| Large | 250,000 | 500 | - | - | - | - | 8 GB | +| XL | 500,000 | 1000 | - | - | - | - | 16 GB | +| 2XL | 1,000,000 | 2000 | 140 | 0.358 sec | 0.575 sec | 30 GB | 32 GB | +| 4XL | 1,000,000 | 2000 | 270 | 0.186 sec | 0.304 sec | 35 GB | 64 GB | +| 8XL | 1,000,000 | 2000 | 470 | 0.104 sec | 0.166 sec | 38 GB | 128 GB | +| 12XL | 1,000,000 | 2000 | 600 | 0.085 sec | 0.132 sec | 41 GB | 192 GB | +| 16XL | 1,000,000 | 2000 | 670 | 0.081 sec | 0.129 sec | 45 GB | 256 GB | + +For 1,000,000 vectors 40 probes results to precision of 0.98. Note that exact values may vary depending on the dataset and queries, we recommend to run benchmarks with your own data to get precise results. Use this table as a reference. + + + + +Emdeddings of 960 dimensions from gist-960 dataset with 1,000,000 vectors. + +| Plan | Vectors | Lists | RPS | Latency Mean | Latency p95 | RAM Usage | RAM | +| ------ | --------- | ----- | ---- | ------------ | ----------- | ------------------ | ------ | +| Free | 30,000 | 30 | 75 | 0.065 sec | 0.088 sec | 1 GB + 100 Mb Swap | 1 GB | +| Small | 100,000 | 100 | 78 | 0.064 sec | 0.092 sec | 1.8 GB | 2 GB | +| Medium | 250,000 | 250 | 58 | 0.085 sec | 0.129 sec | 3.2 GB | 4 GB | +| Large | 500,000 | 500 | 55 | 0.088 sec | 0.140 sec | 5 GB | 8 GB | +| XL | 1,000,000 | 1000 | 110 | 0.046 sec | 0.070 sec | 14 GB | 16 GB | +| 2XL | 1,000,000 | 1000 | 235 | 0.083 sec | 0.136 sec | 10 GB | 32 GB | +| 4XL | 1,000,000 | 1000 | 420 | 0.071 sec | 0.106 sec | 11 GB | 64 GB | +| 8XL | 1,000,000 | 1000 | 815 | 0.072 sec | 0.106 sec | 13 GB | 128 GB | +| 12XL | 1,000,000 | 1000 | 1150 | 0.052 sec | 0.078 sec | 15.5 GB | 192 GB | +| 16XL | 1,000,000 | 1000 | 1345 | 0.072 sec | 0.106 sec | 17.5 GB | 256 GB | + + + + +Emdeddings of 512 dimensions from GloVe Reddit comments dataset with 1,623,397 vectors. + +| Plan | Vectors | Lists | RPS | Latency Mean | Latency p95 | RAM Usage | RAM | +| ------ | --------- | ----- | ---- | ------------ | ----------- | ------------------ | ------ | +| Free | 100,000 | 100 | 250 | 0.395 sec | 0.432 sec | 1 GB + 300 Mb Swap | 1 GB | +| Small | 250,000 | 250 | 440 | 0.223 sec | 0.250 sec | 2 GB + 200 Mb Swap | 2 GB | +| Medium | 500,000 | 500 | 425 | 0.116 sec | 0.143 sec | 3.7 GB | 4 GB | +| Large | 1,000,000 | 1000 | 515 | 0.096 sec | 0.116 sec | 7.5 GB | 8 GB | +| XL | 1,623,397 | 1275 | 465 | 0.212 sec | 0.272 sec | 14 GB | 16 GB | +| 2XL | 1,623,397 | 1275 | 1400 | 0.061 sec | 0.075 sec | 22 GB | 32 GB | +| 4XL | 1,623,397 | 1275 | 1800 | 0.027 sec | 0.043 sec | 20 GB | 64 GB | +| 8XL | 1,623,397 | 1275 | 2850 | 0.032 sec | 0.049 sec | 21 GB | 128 GB | +| 12XL | 1,623,397 | 1275 | 3700 | 0.020 sec | 0.036 sec | 26 GB | 192 GB | +| 16XL | 1,623,397 | 1275 | 3700 | 0.025 sec | 0.042 sec | 29 GB | 256 GB | + +Random vectors were generated for queries. + + + + +Emdeddings of 512 dimensions from GloVe Reddit comments dataset with 1,623,397 vectors. + +| Plan | Vectors | Lists | RPS | Latency Mean | Latency p95 | RAM Usage | RAM | +| ------ | --------- | ----- | --- | ------------ | ----------- | --------- | ------ | +| Free | 100,000 | 100 | - | - | - | - | 1 GB | +| Small | 250,000 | 250 | - | - | - | - | 2 GB | +| Medium | 500,000 | 500 | 75 | 0.656 sec | 0.750 sec | 3.7 GB | 4 GB | +| Large | 1,000,000 | 1000 | 102 | 0.488 sec | 0.580 sec | 7.5 GB | 8 GB | +| XL | 1,000,000 | 1000 | 188 | 0.525 sec | 0.596 sec | 14 GB | 16 GB | +| XL | 1,623,397 | 1275 | 75 | 0.679 sec | 0.798 sec | 14 GB | 16 GB | +| 2XL | 1,623,397 | 1275 | 160 | 0.314 sec | 0.384 sec | 22 GB | 32 GB | +| 4XL | 1,623,397 | 1275 | 300 | 0.083 sec | 0.113 sec | 20 GB | 64 GB | +| 8XL | 1,623,397 | 1275 | 565 | 0.105 sec | 0.141 sec | 21 GB | 128 GB | +| 12XL | 1,623,397 | 1275 | 840 | 0.093 sec | 0.124 sec | 26 GB | 192 GB | +| 16XL | 1,623,397 | 1275 | 940 | 0.084 sec | 0.108 sec | 29 GB | 256 GB | + +Random vectors were generated for queries. + + + + + + +It is possible to upload more vectors to a single table if Memory allows it (for example, 4XL plan and higher for OpenAI embeddings). But it will affect the performance of the queries: RPS will be lower, and latency will be higher. Scaling should be almost linear, but it is recommended to benchmark your workload to find the optimal number of vectors per table and per database instance. + + + +## Methodology + +We follow techniques outlined in the [ANN Benchmarks](https://github.com/erikbern/ann-benchmarks) methodology. A Python test runner is responsible for uploading the data, creating the index, and running the queries. The pgvector engine is implemented using [vecs](https://github.com/supabase/vecs), a Python client for pgvector. + +
+ multi database + multi database +
+ +Each test is run for a minimum of 30-40 minutes. They include a series of experiments executed at different concurrency levels to measure the engine's performance under different load types. The results are then averaged. + +As a general recommendation, we suggest using a concurrency level of 5 or more for most workloads and 30 or more for high-load workloads. + +export const Page = ({ children }) => + +export default Page diff --git a/apps/docs/pages/guides/ai/choosing-instance-type.mdx b/apps/docs/pages/guides/ai/choosing-instance-type.mdx deleted file mode 100644 index c6bb503c4aa65..0000000000000 --- a/apps/docs/pages/guides/ai/choosing-instance-type.mdx +++ /dev/null @@ -1,79 +0,0 @@ -import Layout from '~/layouts/DefaultGuideLayout' - -export const meta = { - id: 'ai-choosing-instance-type', - title: 'Choosing Instance Type', - description: 'Choosing the right instance type for your workload.', - subtitle: 'Choosing the right instance type for your workload.', - sidebar_label: 'Choosing Instance Type', -} - -This guide will help you choose the right instance type for your workload. We'll provide general guidance, as it is impossible to provide specific instructions for every possible use case. The goal is to give you a starting point from which you can make your own benchmarks and optimizations. - -For more information about engineering at scale, see our [Engineering for Scale](/docs/guides/ai/engineering-for-scale) guide. - -## Simple workloads - -We've run a set of benchmarks using the [gist-960-angular](http://corpus-texmex.irisa.fr/) dataset. This dataset contains 1,000,000 embeddings for images, with each embedding being 960 dimensions. - -We used [Vecs](https://github.com/supabase/vecs) to create a collection, upload the embeddings to a single table, and create an `inner-product` index for the embedding column. We then ran a series of queries to measure the performance of different instance types: - -### Results - -The number of vectors in `gist-960-angular` was cut to fit the instance size. - -| Plan | CPU | Memory | Vectors | RPS | Latency Mean | Latency p95 | CPU Usage - Max % | Memory Usage - Max | -| ------ | ------ | ------ | ------- | --- | ------------ | ----------- | ----------------- | ------------------ | -| Free | 2-core | 1 GB | 30,000 | 75 | 0.065 sec | 0.088 sec | 90% | 1 GB + 100 Mb Swap | -| Small | 2-core | 2 GB | 100,000 | 78 | 0.064 sec | 0.092 sec | 80% | 1.8 GB | -| Medium | 2-core | 4 GB | 250,000 | 58 | 0.085 sec | 0.129 sec | 90% | 3.2 GB | -| Large | 2-core | 8 GB | 500,000 | 55 | 0.088 sec | 0.140 sec | 90% | 5 GB | - -The full number of vectors in `gist-960-angular` dataset - 1,000,000. - -| Plan | CPU | Memory | Vectors | RPS | Latency Mean | Latency p95 | CPU Usage - Max % | Memory Usage - Max | -| ---- | ------- | ------ | --------- | ---- | ------------ | ----------- | ----------------- | ------------------ | -| XL | 4-core | 16 GB | 1,000,000 | 110 | 0.046 sec | 0.070 sec | 45% | 14 GB | -| 2XL | 8-core | 32 GB | 1,000,000 | 235 | 0.083 sec | 0.136 sec | 33% | 10 GB | -| 4XL | 16-core | 64 GB | 1,000,000 | 420 | 0.071 sec | 0.106 sec | 45% | 11 GB | -| 8XL | 32-core | 128 GB | 1,000,000 | 815 | 0.072 sec | 0.106 sec | 75% | 13 GB | -| 12XL | 48-core | 192 GB | 1,000,000 | 1150 | 0.052 sec | 0.078 sec | 70% | 15.5 GB | -| 16XL | 64-core | 256 GB | 1,000,000 | 1345 | 0.072 sec | 0.106 sec | 60% | 17.5 GB | - -- Lists set to `Number of vectors / 1000` -- Probes set to `10` - - - -It is possible to upload more than 1,000,000 vectors to a single table if Memory allows it (for example, 2XL instance and higher). But it will affect the performance of the queries: RPS will be lower, and latency will be higher. Scaling should be almost linear, but it is recommended to benchmark your workload to find the optimal number of vectors per table and per instance. - - - -## Methodology - -We follow techniques outlined in the [ANN Benchmarks](https://github.com/erikbern/ann-benchmarks) methodology. A Python test runner is responsible for uploading the data, creating the index, and running the queries. The pgvector engine is implemented using [vecs](https://github.com/supabase/vecs), a Python client for pgvector. - -
- multi database - multi database -
- -Each test is run for a minimum of 30-40 minutes. They include a series of experiments executed at different concurrency levels to measure the engine's performance under different load types. The results are then averaged. - -As a general recommendation, we suggest using a concurrency level of 5 or more for most workloads and 30 or more for high-load workloads. - -## Future benchmarks - -We'll continue to add more benchmarks on datasets consisting of different vector dimensions, number of `lists` in the index, and number of `probes` in the index. Stay tuned for more information about how it may affect the performance and precision of your queries. - -export const Page = ({ children }) => - -export default Page diff --git a/apps/docs/pages/guides/ai/managing-collections.mdx b/apps/docs/pages/guides/ai/managing-collections.mdx index 58e700e2927e9..5ed4d45ce42d7 100644 --- a/apps/docs/pages/guides/ai/managing-collections.mdx +++ b/apps/docs/pages/guides/ai/managing-collections.mdx @@ -9,7 +9,7 @@ export const meta = { A collection is a group of vector records managed by the `vecs` Python library. Records can be added to or updated in a collection. Collections can be queried at any time, but should be indexed for scalable query performance. -Supabase provides a [Python client](/docs/guides/ai/vecs-python-client) called `vecs` for managing unstructured vector stores in Postgres. If you come from a data science background, this unstructured data approach will feel familiar. If you are more interested in a structured data approach, see [Vector columns](/docs/guides/ai/vector-columns) or read our guide on [Structured & Unstructured Embeddings](/docs/guides/ai/structured-unstructured-embeddings). +Supabase provides a [Python client](/docs/guides/ai/vecs-python-client) called `vecs` for managing unstructured vector stores in Postgres. If you come from a data science background, this unstructured data approach will feel familiar. If you are more interested in a structured data approach, see [Vector columns](/docs/guides/ai/vector-columns) or read our guide on [Structured & Unstructured Embeddings](/docs/guides/ai/structured-unstructured). Under the hood `vecs` will manage the necessary Postgres tables and columns to store and query your collections. diff --git a/apps/docs/pages/guides/ai/structured-unstructured.mdx b/apps/docs/pages/guides/ai/structured-unstructured.mdx index 0c392c20e09c9..04b35b5b4cbcb 100644 --- a/apps/docs/pages/guides/ai/structured-unstructured.mdx +++ b/apps/docs/pages/guides/ai/structured-unstructured.mdx @@ -23,7 +23,7 @@ create table docs ( ); insert into docs - (id, content, url, embedding) + (id, embedding, content, url) values ('79409372-7556-4ccc-ab8f-5786a6cfa4f7', array[0.1, 0.2, 0.3], 'Hello world', '/hello-world'); ``` @@ -89,7 +89,7 @@ create table docs ( ); insert into docs - (id, embedding, meta) + (id, embedding, content, url, meta) values ( '79409372-7556-4ccc-ab8f-5786a6cfa4f7', diff --git a/apps/docs/pages/guides/auth.mdx b/apps/docs/pages/guides/auth.mdx index ebc76e00d84ac..a7e261423f6f8 100644 --- a/apps/docs/pages/guides/auth.mdx +++ b/apps/docs/pages/guides/auth.mdx @@ -84,7 +84,7 @@ For deployments with Vercel, set the `SITE_URL` to your official site URL. Add t - `http://localhost:3000/**` - `https://*-username.vercel.app/**` -Vercel provides an environment variable for the URL of the deployment called `NEXT_PUBLIC_VERCEL_URL`. See the [Vercel docs](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) for more details. You can use this variable to dynamically redirect depending on the environment: +Vercel provides an environment variable for the URL of the deployment called `NEXT_PUBLIC_VERCEL_URL`. See the [Vercel docs](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) for more details. You can use this variable to dynamically redirect depending on the environment. You should also set the value of the environment variable called NEXT_PUBLIC_SITE_URL, this should be set to your site URL in production environment to ensure that redirects function correctly. ```js const getURL = () => { diff --git a/apps/docs/pages/guides/auth/auth-captcha.mdx b/apps/docs/pages/guides/auth/auth-captcha.mdx index fac1bdf87d17f..0834167875d2c 100644 --- a/apps/docs/pages/guides/auth/auth-captcha.mdx +++ b/apps/docs/pages/guides/auth/auth-captcha.mdx @@ -165,18 +165,18 @@ Let's create an empty state to store our `captchaToken` const [captchaToken, setCaptchaToken] = useState() ``` -Now lets add the Cloudflare Turnstile component to the JSX section of our code +Now lets add the Cloudflare Turnstile component to the JSX section of our code: ```html ``` -We will pass it the sitekey we copied from the Cloudflare 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 Cloudflare website as a property along with a `onSuccess` 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 { setCaptchaToken(token) } + onSuccess={(token) => { setCaptchaToken(token) } /> ``` diff --git a/apps/docs/pages/guides/auth/auth-helpers/nextjs.mdx b/apps/docs/pages/guides/auth/auth-helpers/nextjs.mdx index 0e38a19150aab..1ed17f6830368 100644 --- a/apps/docs/pages/guides/auth/auth-helpers/nextjs.mdx +++ b/apps/docs/pages/guides/auth/auth-helpers/nextjs.mdx @@ -528,7 +528,7 @@ This allows for the Supabase client to be easily instantiated in the correct con