diff --git a/apps/docs/components/index.tsx b/apps/docs/components/index.tsx
index 8178b4d51f5..831b1fa4027 100644
--- a/apps/docs/components/index.tsx
+++ b/apps/docs/components/index.tsx
@@ -1,7 +1,6 @@
import Link from 'next/link'
import { Alert, Button, CodeBlock, GlassPanel, markdownComponents, Tabs } from 'ui'
import StepHikeCompact from '~/components/StepHikeCompact'
-
// Common components
import Admonition from './Admonition'
import ButtonCard from './ButtonCard'
@@ -31,6 +30,29 @@ import CliGlobalFlagsHandler from '~/components/reference/enrichments/cli/CliGlo
import Options from '~/components/Options'
import Param from '~/components/Params'
+import {
+ IconMenuJavascript,
+ IconMenuHome,
+ IconMenuGettingStarted,
+ IconMenuDatabase,
+ IconMenuServerlessApis,
+ IconMenuAuth,
+ IconMenuEdgeFunctions,
+ IconMenuRealtime,
+ IconMenuStorage,
+ IconMenuPlatform,
+ IconMenuResources,
+ IconMenuSelfHosting,
+ IconMenuIntegrations,
+ IconMenuFlutter,
+ IconMenuPython,
+ IconMenuCsharp,
+ IconMenuSwift,
+ IconMenuKotlin,
+ IconMenuApi,
+ IconMenuCli,
+} from './Navigation/NavigationMenu/HomeMenuIcons'
+
const components = {
...markdownComponents,
Admonition,
@@ -73,6 +95,26 @@ const components = {
CliGlobalFlagsHandler: () =>
,
Options,
Param,
+ IconMenuJavascript,
+ IconMenuHome,
+ IconMenuGettingStarted,
+ IconMenuDatabase,
+ IconMenuServerlessApis,
+ IconMenuAuth,
+ IconMenuEdgeFunctions,
+ IconMenuRealtime,
+ IconMenuStorage,
+ IconMenuPlatform,
+ IconMenuResources,
+ IconMenuSelfHosting,
+ IconMenuIntegrations,
+ IconMenuFlutter,
+ IconMenuPython,
+ IconMenuCsharp,
+ IconMenuKotlin,
+ IconMenuSwift,
+ IconMenuApi,
+ IconMenuCli,
}
export default components
diff --git a/apps/docs/components/reference/CLICommandSection.tsx b/apps/docs/components/reference/CLICommandSection.tsx
index f25d32e74cf..400b3fa7287 100644
--- a/apps/docs/components/reference/CLICommandSection.tsx
+++ b/apps/docs/components/reference/CLICommandSection.tsx
@@ -1,6 +1,5 @@
import ReactMarkdown from 'react-markdown'
import { CodeBlock, IconChevronRight, Tabs } from 'ui'
-// @ts-expect-error
import spec from '~/../../spec/cli_v1_commands.yaml' assert { type: 'yml' }
import Options from '~/components/Options'
import Param from '~/components/Params'
diff --git a/apps/docs/components/reference/OldVersionAlert.tsx b/apps/docs/components/reference/OldVersionAlert.tsx
new file mode 100644
index 00000000000..55b94576d75
--- /dev/null
+++ b/apps/docs/components/reference/OldVersionAlert.tsx
@@ -0,0 +1,40 @@
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+import { useMenuActiveRefId } from '~/hooks/useMenuState'
+import Admonition from '../Admonition'
+import { ICommonSection } from './Reference.types'
+
+export interface OldVersionAlertProps {
+ sections: ICommonSection[]
+}
+
+const OldVersionAlert = ({ sections }: OldVersionAlertProps) => {
+ const router = useRouter()
+ const activeRefId = useMenuActiveRefId()
+
+ const activeSection = sections.find(({ id }) => id === activeRefId)
+
+ // Remove the version number from URL to get the latest
+ const latestVersionUrl = router.asPath
+ .split('/')
+ .slice(0, -2)
+ .concat(activeSection ? [activeSection.slug] : [])
+ .join('/')
+
+ return (
+
+ )
+}
+
+export default OldVersionAlert
diff --git a/apps/docs/components/reference/RefFunctionSection.tsx b/apps/docs/components/reference/RefFunctionSection.tsx
index ddb35ba930b..739ad2c139e 100644
--- a/apps/docs/components/reference/RefFunctionSection.tsx
+++ b/apps/docs/components/reference/RefFunctionSection.tsx
@@ -123,6 +123,8 @@ const RefFunctionSection: React.FC
= (props) => {
? 'dart'
: example?.code?.startsWith('```c#')
? 'csharp'
+ : example?.code?.startsWith('```kotlin')
+ ? 'kotlin'
: 'js'
// `
// import { createClient } from '@supabase/supabase-js'
@@ -156,7 +158,8 @@ const RefFunctionSection: React.FC = (props) => {
.replace('js', '')
.replace('ts', '')
.replace('dart', '')
- .replace('c#', ''))}
+ .replace('c#', '')
+ .replace('kotlin', ''))}
{((tables && tables.length > 0) || sql) && (
diff --git a/apps/docs/components/reference/RefSectionHandler.tsx b/apps/docs/components/reference/RefSectionHandler.tsx
index b1b5bebf134..df5ed1c5700 100644
--- a/apps/docs/components/reference/RefSectionHandler.tsx
+++ b/apps/docs/components/reference/RefSectionHandler.tsx
@@ -8,28 +8,41 @@ import RefFunctionSection from '~/components/reference/RefFunctionSection'
import RefSubLayout from '~/layouts/ref/RefSubLayout'
import ApiOperationSection from './ApiOperationSection'
import CliCommandSection from './CLICommandSection'
-import { IAPISpec, ICommonFunc, IRefStaticDoc, ISpec, TypeSpec } from './Reference.types'
+import OldVersionAlert from './OldVersionAlert'
+import { IAPISpec, ICommonSection, IRefStaticDoc, ISpec, TypeSpec } from './Reference.types'
interface RefSectionHandlerProps {
- sections: ICommonFunc[]
+ sections: ICommonSection[]
spec?: ISpec | IAPISpec
typeSpec?: TypeSpec
pageProps: { docs: IRefStaticDoc[] }
type: 'client-lib' | 'cli' | 'api'
+ isOldVersion?: boolean
}
const RefSectionHandler = (props: RefSectionHandlerProps) => {
const router = useRouter()
- const slug = router.query.slug[0]
+ const [slug] = router.query.slug
// When user lands on a url like http://supabase.com/docs/reference/javascript/sign-up
// find the #sign-up element and scroll to that
useEffect(() => {
- if (document && slug !== 'start') {
- document.querySelector(`#${slug}`) && document.querySelector(`#${slug}`).scrollIntoView()
+ document.getElementById(slug)?.scrollIntoView()
+ }, [slug])
+
+ useEffect(() => {
+ function handler() {
+ const [slug] = window.location.pathname.split('/').slice(-1)
+ document.getElementById(slug)?.scrollIntoView()
}
- })
+
+ window.addEventListener('popstate', handler)
+
+ return () => {
+ window.removeEventListener('popstate', handler)
+ }
+ }, [])
function getPageTitle() {
switch (props.type) {
@@ -58,47 +71,50 @@ const RefSectionHandler = (props: RefSectionHandlerProps) => {
/>
+ {props.isOldVersion && }
- {props.sections.map((x, i) => {
- switch (x.type) {
+ {props.sections.map((section, i) => {
+ const sectionType = section.type
+ switch (sectionType) {
case 'markdown':
- const markdownData = props.pageProps.docs.find((doc) => doc.id === x.id)
+ const markdownData = props.pageProps.docs.find((doc) => doc.id === section.id)
- return
- break
+ return (
+
+ )
case 'function':
return (
)
case 'cli-command':
- return
- break
+ return (
+
+ )
case 'operation':
return (
)
default:
- return (
-
- )
- break
+ throw new Error(`Unknown common section type '${sectionType}'`)
}
})}
diff --git a/apps/docs/components/reference/Reference.types.ts b/apps/docs/components/reference/Reference.types.ts
index 4ff54b1b991..ce15320180e 100644
--- a/apps/docs/components/reference/Reference.types.ts
+++ b/apps/docs/components/reference/Reference.types.ts
@@ -33,19 +33,61 @@ export interface IFunctionDefinition {
examples?: []
}
-export interface ICommonFunc {
- id?: string
+export interface ICommonBase {
+ type: string
title: string
- slug?: string
- product?: string
- type?: string
- parent?: string
- items?: ICommonFunc[]
+ summary?: string
}
+export interface ICommonBaseSection extends ICommonBase {
+ id: string
+ slug: string
+ excludes?: string[]
+}
+
+export interface ICommonCategory extends ICommonBase {
+ type: 'category'
+ items: ICommonSection[]
+ excludes?: string[]
+}
+
+export interface ICommonMarkdown extends ICommonBaseSection {
+ type: 'markdown'
+}
+
+export interface ICommonFunctionGroup extends ICommonBaseSection {
+ type: 'function'
+ isFunc: false
+ product: string
+ items: ICommonFunction[]
+}
+
+export interface ICommonFunction extends ICommonBaseSection {
+ type: 'function'
+ product: string
+ parent?: string
+}
+
+export interface ICommonCliCommand extends ICommonBaseSection {
+ type: 'cli-command'
+}
+
+export interface ICommonApiOperation extends ICommonBaseSection {
+ type: 'operation'
+}
+
+export type ICommonSection =
+ | ICommonMarkdown
+ | ICommonFunctionGroup
+ | ICommonFunction
+ | ICommonCliCommand
+ | ICommonApiOperation
+
+export type ICommonItem = ICommonCategory | ICommonSection
+
export interface IRefFunctionSection {
funcData: any
- commonFuncData: ICommonFunc
+ commonFuncData: ICommonFunction
spec: any
typeSpec?: TypeSpec
}
diff --git a/apps/docs/components/reference/enrichments/cli/CliGlobalFlagsHandler.tsx b/apps/docs/components/reference/enrichments/cli/CliGlobalFlagsHandler.tsx
index 1de9c1971d0..e108730f65a 100644
--- a/apps/docs/components/reference/enrichments/cli/CliGlobalFlagsHandler.tsx
+++ b/apps/docs/components/reference/enrichments/cli/CliGlobalFlagsHandler.tsx
@@ -1,6 +1,5 @@
import RefSubLayout from '~/layouts/ref/RefSubLayout'
-// @ts-expect-error
import spec from '~/../../spec/cli_v1_commands.yaml' assert { type: 'yaml' }
import Param from '~/components/Params'
import Options from '~/components/Options'
diff --git a/apps/docs/data/footer.json b/apps/docs/data/footer.json
deleted file mode 100644
index 1a703f19a96..00000000000
--- a/apps/docs/data/footer.json
+++ /dev/null
@@ -1,10 +0,0 @@
-[
- { "title": "Contributing", "url": "/handbook/contributing" },
- { "title": "Changelog", "url": "https://supabase.com/changelog" },
- {
- "title": "Author Styleguide",
- "url": "https://github.com/supabase/supabase/blob/master/DEVELOPERS.md"
- },
- { "title": "Open Source", "url": "https://supabase.com/docs/oss" },
- { "title": "SupaSquad", "url": "https://supabase.com/supasquad" }
-]
diff --git a/apps/docs/data/footer.ts b/apps/docs/data/footer.ts
new file mode 100644
index 00000000000..15228f0e532
--- /dev/null
+++ b/apps/docs/data/footer.ts
@@ -0,0 +1,32 @@
+import { IconCheckCircle, IconLifeBuoy } from '~/../../packages/ui'
+
+export const primaryLinks = [
+ {
+ featherIcon: IconLifeBuoy,
+ text: 'Need some help?',
+ ctaLabel: 'Contact support',
+ url: 'https://app.supabase.com/support/new',
+ },
+ {
+ icon: 'M12.9521 10.5073C12.766 10.3212 12.5289 10.1943 12.2708 10.1427L10.6794 9.82467C9.80719 9.65024 8.90169 9.77152 8.10609 10.1693L7.89409 10.2747C7.0985 10.6725 6.193 10.7938 5.32076 10.6193L4.03343 10.362C3.81823 10.319 3.59574 10.3298 3.38571 10.3934C3.17569 10.457 2.9846 10.5715 2.82943 10.7267M5.33343 2.88867H10.6668L10.0001 3.55534V7.00334C10.0002 7.35693 10.1407 7.69602 10.3908 7.94601L13.7241 11.2793C14.5641 12.1193 13.9688 13.5553 12.7808 13.5553H3.21876C2.03076 13.5553 1.43609 12.1193 2.27609 11.2793L5.60943 7.94601C5.85949 7.69602 6.00002 7.35693 6.00009 7.00334V3.55534L5.33343 2.88867Z',
+ text: 'Lastest product updates?',
+ ctaLabel: 'See Changelog',
+ url: 'https://supabase.com/changelog',
+ },
+ {
+ featherIcon: IconCheckCircle,
+ text: "Something's not right?",
+ ctaLabel: 'Check system status',
+ url: 'https://status.supabase.com/',
+ },
+]
+
+export const secondaryLinks = [
+ { title: 'Contributing', url: '/handbook/contributing' },
+ {
+ title: 'Author Styleguide',
+ url: 'https://github.com/supabase/supabase/blob/master/DEVELOPERS.md',
+ },
+ { title: 'Open Source', url: 'https://supabase.com/open-source' },
+ { title: 'SupaSquad', url: 'https://supabase.com/supasquad' },
+]
diff --git a/apps/docs/data/nonGeneratedReferencePages.ts b/apps/docs/data/nonGeneratedReferencePages.ts
index 35ae2e4f540..e2d578ce2de 100644
--- a/apps/docs/data/nonGeneratedReferencePages.ts
+++ b/apps/docs/data/nonGeneratedReferencePages.ts
@@ -16,6 +16,8 @@ const nonGeneratedReferencePages = [
'docs/reference/csharp',
'docs/reference/csharp/installing',
'docs/reference/csharp/initializing',
+ 'docs/reference/kotlin/installing',
+ 'docs/reference/kotlin/initializing',
'docs/reference/api',
'docs/reference/api/release-notes',
'docs/reference/cli',
diff --git a/apps/docs/data/repos/realtime.json b/apps/docs/data/repos/realtime.json
index 7b356105892..4c81ebe334d 100644
--- a/apps/docs/data/repos/realtime.json
+++ b/apps/docs/data/repos/realtime.json
@@ -25,7 +25,7 @@
"site_admin": false
},
"html_url": "https://github.com/supabase/realtime",
- "description": "Listen to your to PostgreSQL database in realtime via websockets. Built with Elixir.",
+ "description": "Listen to your PostgreSQL database in realtime via websockets. Built with Elixir.",
"fork": false,
"url": "https://api.github.com/repos/supabase/realtime",
"forks_url": "https://api.github.com/repos/supabase/realtime/forks",
diff --git a/apps/docs/docs/ref/cli/global-flags.mdx b/apps/docs/docs/ref/cli/global-flags.mdx
index 39aaf77295b..088a10a07a0 100644
--- a/apps/docs/docs/ref/cli/global-flags.mdx
+++ b/apps/docs/docs/ref/cli/global-flags.mdx
@@ -1,5 +1,6 @@
---
title: Global Flags
+subtitle: 'Supabase CLI supports global flags for every command.'
description: 'Supabase CLI supports global flags for every command.'
---
diff --git a/apps/docs/docs/ref/csharp/introduction.mdx b/apps/docs/docs/ref/csharp/introduction.mdx
index e016c4f8338..18a06f5c963 100644
--- a/apps/docs/docs/ref/csharp/introduction.mdx
+++ b/apps/docs/docs/ref/csharp/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
C# Client Library
@supabase-community/supabase-csharp
diff --git a/apps/docs/docs/ref/dart/introduction.mdx b/apps/docs/docs/ref/dart/introduction.mdx
index e183e37889e..b99332b670d 100644
--- a/apps/docs/docs/ref/dart/introduction.mdx
+++ b/apps/docs/docs/ref/dart/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Flutter Client Library
supabase-flutter
diff --git a/apps/docs/docs/ref/dart/v0/introduction.mdx b/apps/docs/docs/ref/dart/v0/introduction.mdx
index fdbb9d766a5..1d1f27212ce 100644
--- a/apps/docs/docs/ref/dart/v0/introduction.mdx
+++ b/apps/docs/docs/ref/dart/v0/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Flutter Client Library
supabase-flutter
diff --git a/apps/docs/docs/ref/javascript/introduction.mdx b/apps/docs/docs/ref/javascript/introduction.mdx
index d3c14042cb6..b22c1b371ff 100644
--- a/apps/docs/docs/ref/javascript/introduction.mdx
+++ b/apps/docs/docs/ref/javascript/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Javascript Client Library
@supabase/supabase-js
diff --git a/apps/docs/docs/ref/javascript/v1/introduction.mdx b/apps/docs/docs/ref/javascript/v1/introduction.mdx
index a62134bdd69..8112558ffd6 100644
--- a/apps/docs/docs/ref/javascript/v1/introduction.mdx
+++ b/apps/docs/docs/ref/javascript/v1/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Javascript Client Library
@supabase/supabase-js
diff --git a/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx b/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx
index 01e843bbd42..d13e0311cae 100644
--- a/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx
+++ b/apps/docs/docs/ref/javascript/v1/upgrade-guide.mdx
@@ -89,7 +89,6 @@ The signIn() method has been deprecated in favor of more explicit method signatu
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { user, error } = await supabase
.auth
@@ -98,7 +97,6 @@ const { user, error } = await supabase
-{/* prettier-ignore */}
```ts
const {
data: { user },
@@ -128,7 +126,6 @@ const {
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -137,7 +134,6 @@ const { error } = await supabase
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -165,7 +161,6 @@ const { error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -174,7 +169,6 @@ const { error } = await supabase
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -201,7 +195,6 @@ const { error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -210,7 +203,6 @@ const { error } = await supabase
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -238,7 +230,6 @@ const { error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { error } = await supabase
.auth
@@ -248,16 +239,15 @@ const { error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.auth
.signInWithOtp({ phone })
-
+
// After receiving a SMS with a OTP.
const { data, error } = await supabase
-.auth
-.verifyOtp({ phone, token })
+ .auth
+ .verifyOtp({ phone, token })
```
@@ -281,7 +271,6 @@ const { data, error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.auth
@@ -291,7 +280,6 @@ const { data, error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.auth
@@ -390,7 +378,6 @@ const { user } = session
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { user, error } = await supabase
.auth
@@ -435,7 +422,6 @@ const { user, error } = supabase.auth.setAuth(access_token)
-{/* prettier-ignore */}
```ts
const supabase = createClient(
SUPABASE_URL,
@@ -486,7 +472,6 @@ Previously, these methods return inserted/updated/deleted rows by default (which
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -495,7 +480,6 @@ const { data, error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -524,7 +508,6 @@ const { data, error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -534,7 +517,6 @@ const { data, error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -564,7 +546,6 @@ const { data, error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -573,7 +554,6 @@ const { data, error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -602,7 +582,6 @@ const { data, error } = await supabase
defaultActiveId="1.0x"
>
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
@@ -612,7 +591,6 @@ const { data, error } = await supabase
-{/* prettier-ignore */}
```ts
const { data, error } = await supabase
.from('my_table')
diff --git a/apps/docs/docs/ref/kotlin/installing.mdx b/apps/docs/docs/ref/kotlin/installing.mdx
new file mode 100644
index 00000000000..8d341ad0f63
--- /dev/null
+++ b/apps/docs/docs/ref/kotlin/installing.mdx
@@ -0,0 +1,268 @@
+---
+id: installing
+title: 'Installing & Initialization'
+slug: installing
+custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
+---
+
+### Add one or more modules to your project
+
+
+
+
+ Add dependency to your build file:
+
+
+
+ ```kotlin
+ implementation("io.github.jan-tennert.supabase:[module]:VERSION")
+ ```
+
+
+
+
+ ```groovy
+ implementation 'io.github.jan-tennert.supabase:[module]:VERSION'
+ ```
+
+
+
+
+ ```xml
+
+ io.github.jan-tennert.supabase
+ [module]
+ VERSION
+
+ ```
+
+
+
+
+ The available modules are: **gotrue-kt**, **realtime-kt**, **storage-kt**, **functions-kt**, **postgrest-kt** and **apollo-graphql**
+
+ When using multiple modules, you can also use the BOM dependency to ensure that all modules use the same version:
+
+
+
+
+ ```kotlin
+ implementation(platform("io.github.jan-tennert.supabase:bom:VERSION"))
+ implementation("io.github.jan-tennert.supabase:postgrest-kt")
+ implementation("io.github.jan-tennert.supabase:realtime-kt")
+ ```
+
+
+
+
+ ```groovy
+ implementation platform("io.github.jan-tennert.supabase:bom:VERSION")
+ implementation 'io.github.jan-tennert.supabase:postgrest-kt'
+ implementation 'io.github.jan-tennert.supabase:realtime-kt'
+ ```
+
+
+
+
+ ```xml
+
+ io.github.jan-tennert.supabase
+ bom
+ VERSION
+ pom
+ import
+
+
+ io.github.jan-tennert.supabase
+ postgrest-kt
+
+
+ io.github.jan-tennert.supabase
+ realtime-kt
+
+ ```
+
+
+
+
+
+
+
+
+### Add Ktor Client Engine to each of your Kotlin targets (required)
+
+
+
+
+ You can find a list of engines [here](https://ktor.io/docs/http-client-engines.html)
+
+
+
+
+ ```kotlin
+ implementation("io.ktor:ktor-client-[engine]:KTOR_VERSION")
+ ```
+
+
+
+
+ ```groovy
+ implementation 'io.ktor:ktor-client-[engine]:KTOR_VERSION'
+ ```
+
+
+
+
+ ```xml
+
+ io.ktor
+ ktor-client-[engine]
+ KTOR_VERSION
+
+ ```
+
+
+
+
+ Multiplatform example:
+
+
+
+
+ ```kotlin
+ val commonMain by getting {
+ dependencies {
+ //supabase modules
+ }
+ }
+ val jvmMain by getting {
+ dependencies {
+ implementation("io.ktor:ktor-client-cio:KTOR_VERSION")
+ }
+ }
+ val androidMain by getting {
+ dependsOn(jvmMain)
+ }
+ val jsMain by getting {
+ dependencies {
+ implementation("io.ktor:ktor-client-js:KTOR_VERSION")
+ }
+ }
+ val iosMain by getting {
+ dependencies {
+ implementation("io.ktor:ktor-client-darwin:KTOR_VERSION")
+ }
+ }
+ ```
+
+
+
+
+
+
+
+
+### Add KotlinX Serialization (required for PostgREST and Realtime serialization)
+
+
+
+
+ Add the serialization plugin
+
+
+
+
+ ```kotlin
+ plugins {
+ kotlin("plugin.serialization") version "KOTLIN_VERSION"
+ }
+ ```
+
+
+
+
+ ```groovy
+ plugins {
+ id 'org.jetbrains.kotlin.plugin.serialization' version 'KOTLIN_VERSION'
+ }
+ ```
+
+
+
+
+ ```xml
+
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+
+
+ kotlinx-serialization
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-serialization
+ ${kotlin.version}
+
+
+
+
+
+ ```
+
+
+
+
+ Now you can create serializable classes in your project:
+ ```kotlin
+ @Serializable
+ data class Message(
+ val id: Int,
+ val content: String,
+ @SerialName("author_id")
+ val authorId: String
+ )
+ ```
+ And use them in your Supabase queries:
+ ```kotlin
+ val messages = client.postgrest["messages"].select().decodeList()
+ ```
+
+
+
+
diff --git a/apps/docs/docs/ref/kotlin/introduction.mdx b/apps/docs/docs/ref/kotlin/introduction.mdx
new file mode 100644
index 00000000000..36be6dd7a89
--- /dev/null
+++ b/apps/docs/docs/ref/kotlin/introduction.mdx
@@ -0,0 +1,33 @@
+---
+id: introduction
+title: Introduction
+hideTitle: true
+---
+
+
+
+
+
Kotlin Client Library
+ @supabase-community/supabase-kt
+
+
+
+
+
+This reference documents every object and method available in Supabase's Kotlin Multiplatform library, [supabase-kt](https://github.com/supabase-community/supabase-kt). You can use supabase-kt to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
+
+Supported Kotlin targets:
+
+- JVM
+- Android
+- iOS (Experimental)
+- JS (Browser)
+
+
+
+
+
The Kotlin client library is created and maintained by the Supabase community, and is not an official library. Please be tolerant of areas where the library is still being developed, and — as with all the libraries — feel free to contribute wherever you find issues.
+
+
Huge thanks to official maintainer, [jan-tennert](https://github.com/jan-tennert).
+
+
diff --git a/apps/docs/docs/ref/python/introduction.mdx b/apps/docs/docs/ref/python/introduction.mdx
index cecb5e86669..8b163faa745 100644
--- a/apps/docs/docs/ref/python/introduction.mdx
+++ b/apps/docs/docs/ref/python/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Python Client Library
@supabase-community/supabase-py
diff --git a/apps/docs/docs/ref/self-hosting-auth/introduction.mdx b/apps/docs/docs/ref/self-hosting-auth/introduction.mdx
index d33aee3de4f..0fe820ce9b3 100644
--- a/apps/docs/docs/ref/self-hosting-auth/introduction.mdx
+++ b/apps/docs/docs/ref/self-hosting-auth/introduction.mdx
@@ -14,9 +14,9 @@ hideTitle: true
- The Supabase Auth Server (GoTrue) is a JSON Web Token (JWT)-based API for managing users and issuing access tokens.
+ The Supabase Auth Server (GoTrue) is a JSON Web Token (JWT)-based API for managing users and issuing access tokens.
- GoTrue is an open-source API written in Golang, that acts as a self-standing API service for handling user registration and authentication for JAM projects. It's based on OAuth2 and JWT and handles user signup, authentication, and custom user data.
+ GoTrue is an open-source API written in Golang, that acts as a self-standing API service for handling user registration and authentication for JAM projects. It's based on OAuth2 and JWT and handles user signup, authentication, and custom user data.
diff --git a/apps/docs/docs/ref/self-hosting-storage/introduction.mdx b/apps/docs/docs/ref/self-hosting-storage/introduction.mdx
index 40fd27d4ce8..150820d09b2 100644
--- a/apps/docs/docs/ref/self-hosting-storage/introduction.mdx
+++ b/apps/docs/docs/ref/self-hosting-storage/introduction.mdx
@@ -14,12 +14,12 @@ hideTitle: true
- An S3 compatible object storage service that integrates with Postgres.
+ An S3 compatible object storage service that integrates with Postgres.
- - Uses Postgres as it's datastore for storing metadata
- - Authorization rules are written as Postgres Row Level Security policies
- - Integrates with S3 as the storage backend (with more in the pipeline!)
- - Extremely lightweight and performant
+ - Uses Postgres as it's datastore for storing metadata
+ - Authorization rules are written as Postgres Row Level Security policies
+ - Integrates with S3 as the storage backend (with more in the pipeline!)
+ - Extremely lightweight and performant
diff --git a/apps/docs/docs/ref/swift/introduction.mdx b/apps/docs/docs/ref/swift/introduction.mdx
index 80dc3584bd1..0d08cbed84f 100644
--- a/apps/docs/docs/ref/swift/introduction.mdx
+++ b/apps/docs/docs/ref/swift/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
Swift Client Library
@supabase-community/supabase-swift
@@ -13,17 +13,15 @@ hideTitle: true
-This reference documents every object and method available in Supabase's Swift library, [supabase-swift](https://github.com/supabase-community/supabase-swift). You can use supabase-swift to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
+This reference documents every object and method available in Supabase's Swift library, [supabase-swift](https://github.com/supabase-community/supabase-swift). You can use supabase-swift to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
+
+We also provide a [supabase](https://pub.dev/packages/supabase) package for non-Swift projects.
-We also provide a [supabase](https://pub.dev/packages/supabase) package for non-Swift projects.
The Swift client library is created and maintained by the Supabase community, and is not an official library. Please be tolerant of areas where the library is still being developed, and — as with all the libraries — feel free to contribute wherever you find issues.
-
- Huge thanks to official maintainer, [Maail](https://github.com/maail).
-
+
Huge thanks to official maintainer, [Maail](https://github.com/maail).
-
diff --git a/apps/docs/docs/reference/csharp/introduction.mdx b/apps/docs/docs/reference/csharp/introduction.mdx
index 6c699314937..3eb96ba2925 100644
--- a/apps/docs/docs/reference/csharp/introduction.mdx
+++ b/apps/docs/docs/reference/csharp/introduction.mdx
@@ -5,7 +5,7 @@ hideTitle: true
---
-
+
C# Client Library
supabase-csharp
diff --git a/apps/docs/docs/reference/dart/initializing.mdx b/apps/docs/docs/reference/dart/initializing.mdx
index 7d914d71efd..ba76c217cce 100644
--- a/apps/docs/docs/reference/dart/initializing.mdx
+++ b/apps/docs/docs/reference/dart/initializing.mdx
@@ -4,9 +4,6 @@ title: 'Initializing'
slug: initializing
---
-import Tabs from '@theme/Tabs'
-import TabItem from '@theme/TabItem'
-
## Flutter
For `supabase-flutter`, you will be using the static `initialize()` method on `Supabase` class.
@@ -30,8 +27,9 @@ final supabase = Supabase.instance.client;
### Call `initialize()` with custom headers
-You can pass `headers` to initialize your Supabase client with customer headers.
+You can pass `headers` to initialize your Supabase client with customer headers.
Here is an example of passing a custom auth header to Supabase client.
+
```dart title=main.dart
Future
main() async {
await Supabase.initialize(
diff --git a/apps/docs/docs/reference/dart/installing.mdx b/apps/docs/docs/reference/dart/installing.mdx
index 49822681a67..5565c145a91 100644
--- a/apps/docs/docs/reference/dart/installing.mdx
+++ b/apps/docs/docs/reference/dart/installing.mdx
@@ -4,9 +4,6 @@ title: 'Installing'
slug: installing
---
-import Tabs from '@theme/Tabs'
-import TabItem from '@theme/TabItem'
-
## Flutter
For Flutter project, you can use [supabase_flutter](https://pub.dev/packages/supabase_flutter) package.
diff --git a/apps/docs/docs/reference/javascript/v1/generating-types.mdx b/apps/docs/docs/reference/javascript/v1/generating-types.mdx
index a46fd7ba70d..8878f4c1911 100644
--- a/apps/docs/docs/reference/javascript/v1/generating-types.mdx
+++ b/apps/docs/docs/reference/javascript/v1/generating-types.mdx
@@ -5,9 +5,6 @@ slug: generating-types
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1.yml
---
-import Tabs from '@theme/Tabs'
-import TabItem from '@theme/TabItem'
-
Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript [through third-party tools](/docs/guides/database/api/generating-types).
## Usage with TypeScript
diff --git a/apps/docs/docs/reference/javascript/v1/initializing.mdx b/apps/docs/docs/reference/javascript/v1/initializing.mdx
index 7ea5f5cf164..5672bd80f57 100644
--- a/apps/docs/docs/reference/javascript/v1/initializing.mdx
+++ b/apps/docs/docs/reference/javascript/v1/initializing.mdx
@@ -5,9 +5,6 @@ slug: initializing
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1.yml
---
-import Tabs from '@theme/Tabs'
-import TabItem from '@theme/TabItem'
-
You can initialize a new Supabase client using the `createClient()` method.
The Supabase client is your entrypoint to the rest of the Supabase functionality
@@ -117,7 +114,7 @@ const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key
```
By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
-Go to `Settings > API > Schema` and add the schema which you want to expose to the API. You also need to grant `USAGE` on your new schema with the grants you desire, such as `SELECT, INSERT, UPDATE, DELETE`.
+Go to `Settings > API > Schema` and add the schema which you want to expose to the API. You also need to grant `USAGE` on your new schema with the grants you desire, such as `SELECT, INSERT, UPDATE, DELETE`.
Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
diff --git a/apps/docs/docs/reference/javascript/v1/installing.mdx b/apps/docs/docs/reference/javascript/v1/installing.mdx
index 4441c7253d7..e6e3abb6151 100644
--- a/apps/docs/docs/reference/javascript/v1/installing.mdx
+++ b/apps/docs/docs/reference/javascript/v1/installing.mdx
@@ -5,9 +5,6 @@ slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/spec/supabase_js_v1.yml
---
-import Tabs from '@theme/Tabs'
-import TabItem from '@theme/TabItem'
-
All JavaScript libraries are built directly by the Supabase team.
Other languages are built by the community and supported by Supabase.
diff --git a/apps/docs/docs/reference/postgres/changing-timezones.mdx b/apps/docs/docs/reference/postgres/changing-timezones.mdx
index d05e32afc8b..e836b1bf252 100644
--- a/apps/docs/docs/reference/postgres/changing-timezones.mdx
+++ b/apps/docs/docs/reference/postgres/changing-timezones.mdx
@@ -1,16 +1,12 @@
---
id: changing-timezones
-title: "Changing Timezones"
+title: 'Changing Timezones'
slug: changing-timezones
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
Data types.
-
```sql
-alter database postgres
+alter database postgres
set timezone to 'America/New_York';
```
-
-
-
-
-
## Notes
- View a full list of timezones on [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
-
-
-
-
-
-
-
-
-
## Examples
### Change timezone
-
-
```sql
-alter database postgres
+alter database postgres
set timezone to 'America/New_York';
```
-
@@ -77,7 +56,6 @@ Get a full list of timezones supported by your database. This will return the fo
- `utc_offset`: Offset from UTC (positive means east of Greenwich)
- `is_dst`: True if currently observing daylight savings
-
@@ -108,12 +85,11 @@ Use `ilike` (case insensitive search) to find specific timezones.
```sql
-select *
-from pg_timezone_names()
+select *
+from pg_timezone_names()
where name ilike '%york%';
```
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/columns.mdx b/apps/docs/docs/reference/postgres/columns.mdx
index 0ccaa830381..8ec74a21db2 100644
--- a/apps/docs/docs/reference/postgres/columns.mdx
+++ b/apps/docs/docs/reference/postgres/columns.mdx
@@ -1,16 +1,12 @@
---
id: columns
-title: "Columns"
+title: 'Columns'
slug: columns
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
Creating columns.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
## Examples
### During table creation
-
-
### Create column
-
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/connection-strings.mdx b/apps/docs/docs/reference/postgres/connection-strings.mdx
index 12e4f919c9c..4d7a60ae516 100644
--- a/apps/docs/docs/reference/postgres/connection-strings.mdx
+++ b/apps/docs/docs/reference/postgres/connection-strings.mdx
@@ -1,16 +1,12 @@
---
id: connection-strings
-title: "Connection Strings"
+title: 'Connection Strings'
slug: connection-strings
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
There are various ways to connect to your database, depending on the configuration of your Postgres instance and the tool which you are connecting with.
-
-
-
-
-
## Notes
- [Official Documentation](https://www.postgresql.org/docs/current/libpq-connect.html).
- Avoid using special characters usernames and passwords. If you use special characters in a connection URL, you'll need to URL encode any special characters.
-
-
-
-
-
-
-
-
-
## Examples
### Basic connection string
-If you're using a default setup, your postgres connection string will likely be in the format:
+If you're using a default setup, your postgres connection string will likely be in the format:
`postgres://{user}:{password}@{host}:{port}/{database_name}`
-
@@ -89,7 +69,6 @@ See full [documentation](http://jdbc.postgresql.org/documentation/head/connect.h
jdbc:postgresql://{host}:{port}/{database_name}
```
-
@@ -109,7 +88,6 @@ See full [documentation](http://npgsql.projects.postgresql.org/docs/manual/UserM
Server=host;Port=5432;User Id=username;Password=secret;Database=database_name;
```
-
@@ -129,7 +107,6 @@ See full [documentation](http://php.net/manual/en/book.pgsql.php).
host=hostname port=5432 dbname=databasename user=username password=secret
```
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/database-passwords.mdx b/apps/docs/docs/reference/postgres/database-passwords.mdx
index 9f58234b1a1..4cc8ec9fa8e 100644
--- a/apps/docs/docs/reference/postgres/database-passwords.mdx
+++ b/apps/docs/docs/reference/postgres/database-passwords.mdx
@@ -1,40 +1,16 @@
---
id: database-passwords
-title: "Database Passwords"
+title: 'Database Passwords'
slug: database-passwords
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
Manage the passwords of your database users using any super user.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
## Examples
### Password reset
-
-
```sql
-alter user postgres
+alter user postgres
with password 'new_password';
```
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/database-users.mdx b/apps/docs/docs/reference/postgres/database-users.mdx
index 8ccca2ce94a..d13e8621679 100644
--- a/apps/docs/docs/reference/postgres/database-users.mdx
+++ b/apps/docs/docs/reference/postgres/database-users.mdx
@@ -1,40 +1,16 @@
---
id: database-users
-title: "Database Users"
+title: 'Database Users'
slug: database-users
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
Users and Roles are almost interchangeable.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
## Examples
### Create New User
-
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/index.mdx b/apps/docs/docs/reference/postgres/index.mdx
index b6641472785..5d4e2e7a731 100644
--- a/apps/docs/docs/reference/postgres/index.mdx
+++ b/apps/docs/docs/reference/postgres/index.mdx
@@ -1,15 +1,11 @@
---
id: index
-title: "Getting started"
+title: 'Getting started'
slug: getting-started
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
-
-PostgreSQL, also known as Postgres, is a free and open-source relational
-database management system emphasizing extensibility and SQL compliance.
-It was originally named POSTGRES, referring to its origins as a successor
-to the Ingres database developed at the University of California, Berkeley.
\ No newline at end of file
+PostgreSQL, also known as Postgres, is a free and open-source relational
+database management system emphasizing extensibility and SQL compliance.
+It was originally named POSTGRES, referring to its origins as a successor
+to the Ingres database developed at the University of California, Berkeley.
diff --git a/apps/docs/docs/reference/postgres/publications.mdx b/apps/docs/docs/reference/postgres/publications.mdx
index 87559a38e34..aabcc783c99 100644
--- a/apps/docs/docs/reference/postgres/publications.mdx
+++ b/apps/docs/docs/reference/postgres/publications.mdx
@@ -1,42 +1,19 @@
---
id: publications
-title: "Publications"
+title: 'Publications'
slug: publications
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
-Publications are a way of grouping changes generated from a table or a group of tables.
+Publications are a way of grouping changes generated from a table or a group of tables.
These changes can then be sent to other systems (usually another Postgres database).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
## Examples
### Create a Publication
This publication will contain all changes to all tables.
-
```sql
-create publication publication_name
+create publication publication_name
for all tables;
```
-
### Create a Publication which listens to individual tables
-
-
```sql
-create publication publication_name
+create publication publication_name
for table table_one, table_two;
```
-
### Add tables to an existing publication
-
-
```sql
-alter publication publication_name
+alter publication publication_name
add table table_name;
```
-
### Listens to inserts only
-
-
```sql
-create publication publication_name
+create publication publication_name
for all tables
with (publish = 'insert');
```
-
### Listens to updates only
-
-
```sql
-create publication publication_name
+create publication publication_name
for all tables
with (publish = 'update');
```
-
### Listens to deletions only
-
-
```sql
-create publication publication_name
+create publication publication_name
for all tables
with (publish = 'delete');
```
-
### Remove a Publication
-
-
@@ -186,7 +144,6 @@ drop publication if exists publication_name;
If you are planning to re-create a publication, it's best to do it in a transaction to ensure the operation succeeds.
-
```sql
-begin;
+begin;
-- remove the realtime publication
- drop publication if exists publication_name;
+ drop publication if exists publication_name;
-- re-create the publication but don't enable it for any tables
- create publication publication_name;
+ create publication publication_name;
commit;
```
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/schemas.mdx b/apps/docs/docs/reference/postgres/schemas.mdx
index ad4fbf6d9ef..7b77f396b41 100644
--- a/apps/docs/docs/reference/postgres/schemas.mdx
+++ b/apps/docs/docs/reference/postgres/schemas.mdx
@@ -1,19 +1,15 @@
---
id: schemas
-title: "Schemas"
+title: 'Schemas'
slug: schemas
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
+Schemas are like "folders". They help to keep your database organized.
-Schemas are like "folders". They help to keep your database organized.
-
-Schemas are particularly useful for security. You can set different permissions on each schema.
+Schemas are particularly useful for security. You can set different permissions on each schema.
For example, you might want to use a `public` schema for user-facing data, and an `auth` schema for all logins and secured data.
-
-
-
-
-
## Notes
- Schemas contain [tables](/docs/reference/postgres/tables), columns, triggers, functions, etc.
- Postgres comes with a `public` schema set up by default.
- It is best practice to use lowercase and underscores when naming schemas. For example: `schema_name`, not `Schema Name`.
-
-
-
-
-
-
-
-
-
## Examples
### Creating a schema
-
-
### Removing a schema
-
-
@@ -96,7 +72,6 @@ drop schema if exists schema_name;
Although it's not recommended, you can use uppercase and spaces when naming your schema by wrapping the name with double-quotes.
As a result, you will always need to use double-quotes when referencing your schema.
-
-
\ No newline at end of file
+
diff --git a/apps/docs/docs/reference/postgres/tables.mdx b/apps/docs/docs/reference/postgres/tables.mdx
index 05df802a961..ad95ca5fda1 100644
--- a/apps/docs/docs/reference/postgres/tables.mdx
+++ b/apps/docs/docs/reference/postgres/tables.mdx
@@ -1,19 +1,15 @@
---
id: tables
-title: "Tables"
+title: 'Tables'
slug: tables
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml
---
-import Tabs from '@theme/Tabs';
-import TabsPanel from '@theme/TabsPanel';
-
Tables are similar to excel spreadsheets. They contain columns & rows of data. There are a few key differences from a spreadsheet however:
- Every column is a strict type of data. When you set up a column, you must define what "data type" it is.
- Tables can be joined together through relationships. For example you can have a "users" table, which is joined to a "teams" table.
-
-
-
-
-
## Notes
-- Tables contain columns, rows, triggers, comments,
+- Tables contain columns, rows, triggers, comments,
- It is best practice to use lowercase and underscores when naming tables. For example: `table_name`, not `Table Name`.
- Tables belong to [schemas](/docs/reference/postgres/schemas). If you don't explicitly pass the schema, Postgres will assume that you want to create the table in the `public` schema.
-
-
-
-
-
-
-
-
-
## Examples
### Create table
-
-
### Primary keys using multiple columns
-
-
### Multiple foreign keys to the same table
-
-
### Delete a table
-
-
-
\ No newline at end of file
+
diff --git a/apps/docs/generator/helpers.ts b/apps/docs/generator/helpers.ts
index e7796c9101f..30b8037d818 100644
--- a/apps/docs/generator/helpers.ts
+++ b/apps/docs/generator/helpers.ts
@@ -1,5 +1,5 @@
-import * as _ from 'lodash'
import * as fs from 'fs'
+import { mapValues, values } from 'lodash'
export const slugify = (text: string) => {
if (!text) return ''
@@ -34,8 +34,8 @@ export const writeToDisk = (fileName: string, content: any) => {
* Convert Object to Array of values
*/
export const toArrayWithKey = (obj: object, keyAs: string) =>
- _.values(
- _.mapValues(obj, (value: any, key: string) => {
+ values(
+ mapValues(obj, (value: any, key: string) => {
value[keyAs] = key
return value
})
diff --git a/apps/docs/internals/files/reference-lib.mjs b/apps/docs/internals/files/reference-lib.mjs
index ee95d4ee625..71c6c3bc368 100644
--- a/apps/docs/internals/files/reference-lib.mjs
+++ b/apps/docs/internals/files/reference-lib.mjs
@@ -8,10 +8,11 @@ const flatCommonLibSections = flattenSections(commonLibSections)
const clientLibFiles = [
{ fileName: 'supabase_js_v2', label: 'javascript', version: 'v2', versionSlug: false },
- { fileName: 'supabase_js_v1', label: 'javascript', version: 'v1', versionSlug: true },
{ fileName: 'supabase_dart_v1', label: 'dart', version: 'v1', versionSlug: false },
- { fileName: 'supabase_dart_v0', label: 'dart', version: 'v0', versionSlug: true },
- { fileName: 'supabase_dart_v0', label: 'dart', version: 'v0', versionSlug: true },
+ { fileName: 'supabase_py_v2', label: 'python', version: 'v2', versionSlug: false },
+ { fileName: 'supabase_csharp_v0', label: 'csharp', version: 'v0', versionSlug: false },
+ { fileName: 'supabase_swift_v0', label: 'swift', version: 'v0', versionSlug: false },
+ { fileName: 'supabase_kt_v0', label: 'kotlin', version: 'v0', versionSlug: false },
]
export function generateReferencePages() {
diff --git a/apps/docs/layouts/DefaultLayout.tsx b/apps/docs/layouts/DefaultLayout.tsx
index b8338b9d451..393b86abf29 100644
--- a/apps/docs/layouts/DefaultLayout.tsx
+++ b/apps/docs/layouts/DefaultLayout.tsx
@@ -12,6 +12,7 @@ interface Props {
description?: string
hide_table_of_contents?: boolean
video?: string
+ tocVideo?: string
canonical?: string
}
children: any
@@ -20,7 +21,7 @@ interface Props {
}
const Layout: FC = (props: Props) => {
- const { asPath, basePath } = useRouter()
+ const { asPath } = useRouter()
const hasTableOfContents =
props.toc !== undefined &&
@@ -59,26 +60,30 @@ const Layout: FC = (props: Props) => {
},
}}
/>
-
- {/*
Tutorials
*/}
-
- {props.meta.title}
- {/*
*/}
-
-
-
- {hasTableOfContents && !props.meta?.hide_table_of_contents && (
-
-
+
+
+
+ {props.meta.title}
+
+
- )}
+ {hasTableOfContents && !props.meta?.hide_table_of_contents && (
+
+ )}
+
>
)
}
+export const LayoutMainContent: FC<{ className?: string }> = ({ className, children }) => (
+
{children}
+)
+
export default Layout
diff --git a/apps/docs/layouts/HomeLayout.tsx b/apps/docs/layouts/HomeLayout.tsx
new file mode 100644
index 00000000000..3f4928902fb
--- /dev/null
+++ b/apps/docs/layouts/HomeLayout.tsx
@@ -0,0 +1,86 @@
+import { MDXProvider } from '@mdx-js/react'
+import { NextSeo } from 'next-seo'
+import Head from 'next/head'
+import { useRouter } from 'next/router'
+import { FC } from 'react'
+import components from '~/components'
+import TableOfContents from '~/components/TableOfContents'
+import HomePageCover from '../components/HomePageCover'
+import { LayoutMainContent } from './DefaultLayout'
+
+interface Props {
+ meta: {
+ title: string
+ description?: string
+ hide_table_of_contents?: boolean
+ video?: string
+ canonical?: string
+ }
+ children: any
+ toc?: any
+ menuItems: any
+}
+
+const HomeLayout: FC
= (props: Props) => {
+ const { asPath } = useRouter()
+
+ const hasTableOfContents =
+ props.toc !== undefined &&
+ props.toc.json.filter((item) => item.lvl !== 1 && item.lvl <= 3).length > 0
+
+ return (
+ <>
+
+ {asPath === '/' ? 'Supabase Docs' : `${props.meta?.title} | Supabase Docs`}
+
+
+
+
+
+
+
+
+
+ {hasTableOfContents && !props.meta?.hide_table_of_contents && (
+
+ )}
+
+ >
+ )
+}
+
+export default HomeLayout
diff --git a/apps/docs/layouts/SiteLayout.tsx b/apps/docs/layouts/SiteLayout.tsx
index 08cb34e0835..ff35c1af441 100644
--- a/apps/docs/layouts/SiteLayout.tsx
+++ b/apps/docs/layouts/SiteLayout.tsx
@@ -4,11 +4,10 @@ import Link from 'next/link'
import NavigationMenu from '~/components/Navigation/NavigationMenu/NavigationMenu'
import TopNavBarRef from '~/components/Navigation/NavigationMenu/TopNavBarRef'
-import { memo, useEffect } from 'react'
+import Head from 'next/head'
+import { PropsWithChildren, memo } from 'react'
import Footer from '~/components/Navigation/Footer'
import { menuState, useMenuLevelId, useMenuMobileOpen } from '~/hooks/useMenuState'
-import Head from 'next/head'
-import { Announcement, AnnouncementCountdown } from 'ui'
const levelsData = {
home: {
@@ -91,10 +90,14 @@ const levelsData = {
icon: '/docs/img/icons/menu/reference-python',
name: 'Python Reference v2.0',
},
- reference_swift_v1: {
+ reference_swift_v0: {
icon: '/docs/img/icons/menu/reference-swift',
name: 'Swift Reference v1.0',
},
+ reference_kotlin_v0: {
+ icon: '/docs/img/icons/menu/reference-kotlin',
+ name: 'Kotlin Reference v0.0',
+ },
reference_cli: {
icon: '/docs/img/icons/menu/reference-cli',
name: 'CLI Reference',
@@ -198,7 +201,7 @@ const MobileMenuBackdrop = memo(function MobileMenuBackdrop() {
'left-0',
'right-0',
'z-10',
- 'backdrop-blur-sm backdrop-filter bg-white-1200 dark:bg-blackA-600',
+ 'backdrop-blur-sm backdrop-filter bg-white-1200 dark:bg-scale-200/90',
mobileMenuOpen ? 'absolute h-full w-full top-0 left-0' : 'hidden h-0',
// always hide on desktop
'lg:hidden',
@@ -208,25 +211,6 @@ const MobileMenuBackdrop = memo(function MobileMenuBackdrop() {
)
})
-const SideMenu = memo(function SideMenu() {
- return (
-
-
-
- )
-})
-
const HeaderLogo = memo(function HeaderLogo() {
const { isDarkMode } = useTheme()
return (
@@ -292,7 +276,7 @@ const NavContainer = memo(function NavContainer() {
'relative',
'w-auto',
'border-r overflow-auto h-screen',
- 'backdrop-blur backdrop-filter bg-white-1200 dark:bg-blackA-300',
+ 'backdrop-blur backdrop-filter bg-white-1200 dark:bg-scale-200',
'flex flex-col',
].join(' ')}
>
@@ -312,24 +296,32 @@ const NavContainer = memo(function NavContainer() {
-
+
+
+
)
})
-const SiteLayout = ({ children }) => {
+const SiteLayout = ({ children }: PropsWithChildren<{}>) => {
return (
<>
Supabase Docs
-
@@ -340,14 +332,14 @@ const SiteLayout = ({ children }) => {
className={[
'sticky transition-all top-0',
'z-10',
- 'backdrop-blur backdrop-filter bg-white-1200 dark:bg-blackA-300',
+ 'backdrop-blur backdrop-filter bg-white-1200 dark:bg-scale-200',
].join(' ')}
>
-
+
{children}
diff --git a/apps/docs/layouts/guides/index.tsx b/apps/docs/layouts/guides/index.tsx
index e24008fe864..d952b6b50be 100644
--- a/apps/docs/layouts/guides/index.tsx
+++ b/apps/docs/layouts/guides/index.tsx
@@ -7,19 +7,22 @@ import { FC, useEffect, useRef, useState } from 'react'
import { IconExternalLink } from 'ui'
import components from '~/components'
import { highlightSelectedTocItem } from '~/components/CustomHTMLElements/CustomHTMLElements.utils'
-import FooterHelpCallout, { FooterHelpCalloutType } from '~/components/FooterHelpCallout'
+import { FooterHelpCalloutType } from '~/components/FooterHelpCallout'
import GuidesTableOfContents from '~/components/GuidesTableOfContents'
import useHash from '~/hooks/useHash'
+import { LayoutMainContent } from '../DefaultLayout'
+import ExpandableVideo from 'ui/src/components/ExpandableVideo/ExpandableVideo'
interface Props {
meta: {
title: string
- description?: string
+ description?: string // used in meta tags
hide_table_of_contents?: boolean
breadcrumb?: string
- subtitle?: string
+ subtitle?: string // used on the page under the H1
footerHelpType?: FooterHelpCalloutType
video?: string
+ tocVideo?: string
canonical?: string
}
children: any
@@ -35,7 +38,6 @@ const Layout: FC
= (props) => {
const [tocList, setTocList] = useState([])
const { asPath } = useRouter()
-
const router = useRouter()
const EDIT_BUTTON_EXCLUDE_LIST = ['/404']
@@ -63,6 +65,7 @@ const Layout: FC = (props) => {
}, [])
const hasTableOfContents = tocList.length > 0
+ const tocVideoPreview = `http://img.youtube.com/vi/${props.meta.tocVideo}/0.jpg`
// page type, ie, Auth, Database, Storage etc
const ogPageType = asPath.split('/')[2]
@@ -103,69 +106,75 @@ const Layout: FC = (props) => {
},
}}
/>
-
-
- {props.meta.breadcrumb && (
-
{props.meta.breadcrumb}
- )}
-
- {props.meta.title}
- {props.meta.subtitle && (
- {props.meta.subtitle}
- )}
-
- {props.children}
-
- {EDIT_BUTTON_EXCLUDE_LIST.includes(router.route) ? (
- <>>
- ) : (
-
- )}
-
-
- {!props.hideToc && hasTableOfContents && !props.meta?.hide_table_of_contents && (
+
+
-
-
- On this page
-
-
-
+ {props.meta.breadcrumb && (
+
{props.meta.breadcrumb}
+ )}
+
+ {props.meta.title}
+ {props.meta.subtitle && (
+ {props.meta.subtitle}
+ )}
+
+ {props.children}
+
+ {EDIT_BUTTON_EXCLUDE_LIST.includes(router.route) ? (
+ <>>
+ ) : (
+
+ )}
+
- )}
-
-
+ {!props.hideToc && hasTableOfContents && !props.meta?.hide_table_of_contents && (
+
+
+ {props.meta?.tocVideo && !!tocVideoPreview && (
+
+
+
+ )}
+
+ On this page
+
+
+
+
+ )}
+
+
>
)
}
diff --git a/apps/docs/layouts/ref/RefSubLayout.tsx b/apps/docs/layouts/ref/RefSubLayout.tsx
index fb3668fc594..dc700bc4858 100644
--- a/apps/docs/layouts/ref/RefSubLayout.tsx
+++ b/apps/docs/layouts/ref/RefSubLayout.tsx
@@ -51,7 +51,11 @@ interface ISectionDetails {}
interface ISectionExamples {}
const RefSubLayout: FC & RefSubLayoutSubComponents = (props) => {
- return {props.children}
+ return (
+
+ {props.children}
+
+ )
}
const Section: FC = (props) => {
@@ -128,7 +132,7 @@ const StickyHeader: FC = ({ icon, ...props }) => {
}
const Details: FC = (props) => {
- return {props.children}
+ return {props.children}
}
const Examples: FC = (props) => {
diff --git a/apps/docs/layouts/tutorials/TutorialLayout.tsx b/apps/docs/layouts/tutorials/TutorialLayout.tsx
index ba3ffe68f6e..47557e96b1b 100644
--- a/apps/docs/layouts/tutorials/TutorialLayout.tsx
+++ b/apps/docs/layouts/tutorials/TutorialLayout.tsx
@@ -6,7 +6,13 @@ import SideBar from '~/components/Navigation/SideBar'
import TableOfContents from '~/components/TableOfContents'
interface Props {
- meta: { title: string; description?: string; hide_table_of_contents?: boolean; video?: string }
+ meta: {
+ title: string
+ description?: string
+ hide_table_of_contents?: boolean
+ video?: string
+ tocVideo?: string
+ }
children: any
toc?: any
menuItems: any
diff --git a/apps/docs/lib/constants.ts b/apps/docs/lib/constants.ts
index d1bbedbf47c..42c12c0d3f4 100644
--- a/apps/docs/lib/constants.ts
+++ b/apps/docs/lib/constants.ts
@@ -1,2 +1,3 @@
export const IS_PLATFORM = process.env.NEXT_PUBLIC_IS_PLATFORM === 'true'
export const LOCAL_SUPABASE = process.env.NEXT_PUBLIC_LOCAL_SUPABASE === 'true'
+export const API_URL = process.env.NEXT_PUBLIC_API_URL
diff --git a/apps/docs/lib/fetchWrappers.tsx b/apps/docs/lib/fetchWrappers.tsx
index c573a0d37dc..0313e49565f 100644
--- a/apps/docs/lib/fetchWrappers.tsx
+++ b/apps/docs/lib/fetchWrappers.tsx
@@ -1,7 +1,5 @@
interface DataProps {
- referrer?: string
- title: string
- route?: string
+ [prop: string]: any
}
export const post = (url: string, data: DataProps, options = {}) => {
diff --git a/apps/docs/lib/helpers.ts b/apps/docs/lib/helpers.ts
index 7a6c5de3d45..112898e065a 100644
--- a/apps/docs/lib/helpers.ts
+++ b/apps/docs/lib/helpers.ts
@@ -1,6 +1,4 @@
-// [Joshen] I think this can be done better, as its mostly used to choose what
-
-import { ICommonFunc } from '../components/reference/Reference.types'
+import { ICommonBase, ICommonItem, ICommonSection } from '../components/reference/Reference.types'
// menus to render in the SideBar.js (Ref Nav.constants.ts)
export function getPageType(asPath: string) {
@@ -36,18 +34,25 @@ export function getPageType(asPath: string) {
return page
}
-export function flattenSections(sections: ICommonFunc[]) {
- let a: ICommonFunc[] = []
- for (let i = 0; i < sections.length; i++) {
- if (sections[i].id) {
- // only push a section that has an id
- // these are reserved for sidebar subtitles
- a.push(sections[i])
+/**
+ * Flattens common sections recursively by their `items`.
+ *
+ * _Note:_ `sections` type set to `ICommonBase[]` instead of
+ * `ICommonItem[]` until TypeScript supports JSON imports as const:
+ * https://github.com/microsoft/TypeScript/issues/32063
+ */
+export function flattenSections(sections: ICommonBase[]): ICommonSection[] {
+ return sections.reduce((acc, section: ICommonItem) => {
+ // Flatten sub-items
+ if ('items' in section) {
+ let newSections = acc
+
+ if (section.type !== 'category') {
+ newSections.push(section)
+ }
+
+ return newSections.concat(flattenSections(section.items))
}
- if (sections[i].items) {
- // if there are subitems, loop through
- a = a.concat(flattenSections(sections[i].items))
- }
- }
- return a
+ return acc.concat(section)
+ }, [])
}
diff --git a/apps/docs/lib/mdx/generateRefMarkdown.tsx b/apps/docs/lib/mdx/generateRefMarkdown.tsx
index 1d5f7a539e9..5d959560ade 100644
--- a/apps/docs/lib/mdx/generateRefMarkdown.tsx
+++ b/apps/docs/lib/mdx/generateRefMarkdown.tsx
@@ -2,12 +2,9 @@ import fs from 'fs'
import matter from 'gray-matter'
import { serialize } from 'next-mdx-remote/serialize'
+import { ICommonMarkdown } from '~/components/reference/Reference.types'
-// import { remarkCodeHike } from '@code-hike/mdx'
-// import codeHikeTheme from '~/codeHikeTheme.js'
-// import theme from 'shiki/themes/solarized-dark.json'
-
-async function generateRefMarkdown(sections, slug) {
+async function generateRefMarkdown(sections: ICommonMarkdown[], slug: string) {
let markdownContent = []
/**
* Read all the markdown files that might have
@@ -16,10 +13,8 @@ async function generateRefMarkdown(sections, slug) {
* - important notes regarding implementation
*/
await Promise.all(
- sections.map(async (x, i) => {
- if (!x.id) return null
-
- const pathName = `docs/ref${slug}/${x.id}.mdx`
+ sections.map(async (section) => {
+ const pathName = `docs/ref${slug}/${section.id}.mdx`
function checkFileExists(x) {
if (fs.existsSync(x)) {
@@ -37,8 +32,8 @@ async function generateRefMarkdown(sections, slug) {
const { data, content } = matter(fileContents)
markdownContent.push({
- id: x.id,
- title: x.title,
+ id: section.id,
+ title: section.title,
meta: data,
// introPage: introPages.includes(x),
content: content
diff --git a/apps/docs/lib/mdx/getConfig.tsx b/apps/docs/lib/mdx/getConfig.tsx
index 4cd95686c7f..2341e23b3e2 100644
--- a/apps/docs/lib/mdx/getConfig.tsx
+++ b/apps/docs/lib/mdx/getConfig.tsx
@@ -1,12 +1,7 @@
-// @ts-expect-error
import specStorageV0 from '~/../../spec/storage_v0_config.yaml' assert { type: 'yml' }
-// @ts-expect-error
import specRealtimeV0 from '~/../../spec/realtime_v0_config.yaml' assert { type: 'yml' }
-// @ts-expect-error
import specAuthV1 from '~/../../spec/gotrue_v1_config.yaml' assert { type: 'yml' }
-// @ts-expect-error
import specAnalyticsV0 from '~/../../spec/analytics_v0_config.yaml' assert { type: 'yml' }
-// @ts-expect-error
import specFunctionsV0 from '~/../../spec/functions_v0_config.yaml' assert { type: 'yml' }
function getStorageConfigV0() {
diff --git a/apps/docs/lib/mdx/handleRefStaticPaths.tsx b/apps/docs/lib/mdx/handleRefStaticPaths.tsx
index c1f13e4a8c4..f458f4f3e8b 100644
--- a/apps/docs/lib/mdx/handleRefStaticPaths.tsx
+++ b/apps/docs/lib/mdx/handleRefStaticPaths.tsx
@@ -1,13 +1,11 @@
-import { getAllDocs } from '../docs'
-
-async function handleRefGetStaticPaths() {
- let docs = getAllDocs()
+import { ICommonSection } from '~/components/reference/Reference.types'
+async function handleRefGetStaticPaths(sections: ICommonSection[]) {
return {
- paths: docs.map(() => {
+ paths: sections.map((section) => {
return {
params: {
- slug: docs.map((d) => d.slug),
+ slug: [section.slug],
},
}
}),
diff --git a/apps/docs/lib/mdx/handleRefStaticProps.tsx b/apps/docs/lib/mdx/handleRefStaticProps.tsx
index c97245387f9..56c6c159ed0 100644
--- a/apps/docs/lib/mdx/handleRefStaticProps.tsx
+++ b/apps/docs/lib/mdx/handleRefStaticProps.tsx
@@ -1,7 +1,11 @@
+import { ICommonMarkdown, ICommonSection } from '~/components/reference/Reference.types'
import generateRefMarkdown from '~/lib/mdx/generateRefMarkdown'
-async function handleRefStaticProps(sections, librarypath) {
- let markdownContent = await generateRefMarkdown(sections, librarypath)
+async function handleRefStaticProps(sections: ICommonSection[], libraryPath: string) {
+ const markdownSections = sections.filter(
+ (section): section is ICommonMarkdown => section.type === 'markdown'
+ )
+ const markdownContent = await generateRefMarkdown(markdownSections, libraryPath)
return {
props: {
diff --git a/apps/docs/lib/refGenerator/helpers.ts b/apps/docs/lib/refGenerator/helpers.ts
index 3325d45786f..d7c6ec52147 100644
--- a/apps/docs/lib/refGenerator/helpers.ts
+++ b/apps/docs/lib/refGenerator/helpers.ts
@@ -3,6 +3,7 @@ import { TsDoc } from '../../generator/legacy/definitions'
import { values, mapValues } from 'lodash'
import { OpenAPIV3 } from 'openapi-types'
import { flattenSections } from '../helpers'
+import { ICommonItem } from '~/components/reference/Reference.types'
export function extractTsDocNode(nodeToFind: string, definition: any) {
const nodePath = nodeToFind.split('.')
@@ -294,12 +295,13 @@ export const toArrayWithKey = (obj: object, keyAs: string) =>
})
)
-export function generateAllowedClientLibKeys(sections, spec) {
+/**
+ * Get a list of common section IDs that are available in this spec
+ */
+export function getAvailableSectionIds(sections: ICommonItem[], spec: any) {
// Filter parent sections first
- const specIds = spec.functions.map((func) => {
- return func.id
- })
+ const specIds = spec.functions.map(({ id }) => id)
const newShape = flattenSections(sections).filter((section) => {
if (specIds.includes(section.id)) {
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
index b3c71cae82e..47fe88b4ffa 100644
--- a/apps/docs/next.config.mjs
+++ b/apps/docs/next.config.mjs
@@ -6,6 +6,12 @@ import rehypeSlug from 'rehype-slug'
import withTM from 'next-transpile-modules'
import withYaml from 'next-plugin-yaml'
+import configureBundleAnalyzer from '@next/bundle-analyzer'
+
+const withBundleAnalyzer = configureBundleAnalyzer({
+ enabled: process.env.ANALYZE === 'true',
+})
+
// import admonitions from 'remark-admonitions'
// import { remarkCodeHike } from '@code-hike/mdx'
@@ -39,7 +45,7 @@ const withMDX = nextMdx({
},
})
-// /** @type {NextConfig} */
+/** @type {import('next').NextConfig} nextConfig */
const nextConfig = {
// Append the default value with md extensions
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
@@ -54,10 +60,16 @@ const nextConfig = {
'user-images.githubusercontent.com',
'raw.githubusercontent.com',
'weweb-changelog.ghost.io',
+ 'img.youtube.com',
],
},
experimental: {
mdxRs: true,
+ modularizeImports: {
+ lodash: {
+ transform: 'lodash/{{member}}',
+ },
+ },
},
async headers() {
return [
@@ -92,9 +104,14 @@ const nextConfig = {
},
}
-// next.config.js
-export default () => {
- // const plugins = [withMDX]/
- const plugins = [withTM(['ui', 'common', '@supabase/auth-helpers-nextjs']), withMDX, withYaml]
+const configExport = () => {
+ const plugins = [
+ withTM(['ui', 'common', '@supabase/auth-helpers-nextjs']),
+ withMDX,
+ withYaml,
+ withBundleAnalyzer,
+ ]
return plugins.reduce((acc, next) => next(acc), nextConfig)
}
+
+export default configExport
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 0eb29301d62..28ce0d084d8 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -6,6 +6,7 @@
"dev": "next dev --port 3001",
"dev:secrets:pull": "AWS_PROFILE=supabase-dev node internals/getSecrets.js",
"build": "npm run generate:all && next build",
+ "build:analyze": "ANALYZE=true next build",
"start": "next start",
"lint": "next lint",
"build:sitemap": "node ./internals/generate-sitemap.mjs",
@@ -46,6 +47,7 @@
"@docsearch/react": "^3.3.0",
"@mdx-js/loader": "^1.6.22",
"@mdx-js/react": "^1.6.22",
+ "@next/bundle-analyzer": "^13.4.0",
"@next/mdx": "^12.0.4",
"@octokit/auth-app": "^4.0.9",
"@octokit/core": "^4.2.0",
@@ -59,6 +61,7 @@
"clsx": "^1.2.1",
"common": "*",
"config": "*",
+ "framer-motion": "^6.5.1",
"github-slugger": "^2.0.0",
"gray-matter": "^4.0.3",
"isbot": "^3.6.5",
diff --git a/apps/docs/pages/_app.tsx b/apps/docs/pages/_app.tsx
index 0ac7df56c63..6b24c000d4b 100644
--- a/apps/docs/pages/_app.tsx
+++ b/apps/docs/pages/_app.tsx
@@ -1,16 +1,13 @@
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { SessionContextProvider } from '@supabase/auth-helpers-react'
-import { AuthProvider, ThemeProvider } from 'common'
+import { AuthProvider, ThemeProvider, useTelemetryProps } from 'common'
import { useRouter } from 'next/router'
-import { useEffect, useState } from 'react'
-import ReactMarkdown from 'react-markdown'
-import remarkGfm from 'remark-gfm'
+import { useCallback, useEffect, useState } from 'react'
import { AppPropsWithLayout } from 'types'
import { CommandMenuProvider } from 'ui'
-import components from '~/components'
import Favicons from '~/components/Favicons'
import SiteLayout from '~/layouts/SiteLayout'
-import { IS_PLATFORM, LOCAL_SUPABASE } from '~/lib/constants'
+import { API_URL, IS_PLATFORM, LOCAL_SUPABASE } from '~/lib/constants'
import { post } from '~/lib/fetchWrappers'
import '../styles/ch.scss'
import '../styles/main.scss?v=1.0.0'
@@ -19,18 +16,26 @@ import '../styles/prism-okaidia.scss'
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const router = useRouter()
+ const telemetryProps = useTelemetryProps()
const [supabase] = useState(() =>
IS_PLATFORM || LOCAL_SUPABASE ? createBrowserSupabaseClient() : undefined
)
- function handlePageTelemetry(route: string) {
- return post(`https://api.supabase.io/platform/telemetry/page`, {
- referrer: document.referrer,
- title: document.title,
- route,
- })
- }
+ const handlePageTelemetry = useCallback(
+ (route: string) => {
+ return post(`${API_URL}/telemetry/page`, {
+ referrer: document.referrer,
+ title: document.title,
+ route,
+ ga: {
+ screen_resolution: telemetryProps?.screenResolution,
+ language: telemetryProps?.language,
+ },
+ })
+ },
+ [telemetryProps]
+ )
useEffect(() => {
function handleRouteChange(url: string) {
@@ -57,16 +62,35 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
- }, [router.events])
+ }, [router, handlePageTelemetry])
useEffect(() => {
/**
* Send page telemetry on first page load
*/
if (router.isReady) {
- handlePageTelemetry(router.asPath)
+ handlePageTelemetry(router.basePath + router.asPath)
}
- }, [router.isReady])
+ }, [router, handlePageTelemetry])
+
+ /**
+ * Reference docs use `history.pushState()` to jump to
+ * sub-sections without causing a re-render.
+ *
+ * We need to the below handler to manually force a re-render
+ * when navigating away from, then back to reference docs
+ */
+ useEffect(() => {
+ function handler() {
+ router.replace(window.location.href)
+ }
+
+ window.addEventListener('popstate', handler)
+
+ return () => {
+ window.removeEventListener('popstate', handler)
+ }
+ }, [router])
const SITE_TITLE = 'Supabase Documentation'
@@ -85,12 +109,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
- (
-
- )}
- >
+
diff --git a/apps/docs/pages/guides/api.mdx b/apps/docs/pages/guides/api.mdx
index 3b518ced47b..390dcadd33d 100644
--- a/apps/docs/pages/guides/api.mdx
+++ b/apps/docs/pages/guides/api.mdx
@@ -32,6 +32,7 @@ Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This
It provides everything you need from a CRUD API at the URL `https://.supabase.co/rest/v1/`.
The REST interface is automatically reflected from your database's schema and supports:
+
- Basic CRUD operations (Create/Read/Update/Delete)
- Arbitrarily deep relationships among tables/views, functions that return table types can also nest related tables/views.
- Works with Postgres Views, Materialized Views and Foreign Tables
@@ -42,6 +43,7 @@ The REST interface is automatically reflected from your database's schema and su
The REST API resolves all requests to a single SQL statement leading to fast response times and high throughput.
Reference:
+
- [Docs](https://postgrest.org/)
- [Source Code](https://github.com/PostgREST/postgrest)
@@ -52,6 +54,7 @@ You can introspect and query the GraphQL API of an existing Supabase project wit
or navigate there manually at `API Docs > GraphQL > GraphiQL`.
The GraphQL interface is automatically reflected from your database's schema and supports:
+
- Basic CRUD operations (Create/Read/Update/Delete)
- Support for Tables, Views, Materialized Views, and Foreign Tables
- Arbitrarily deep relationships among tables/views
@@ -61,6 +64,7 @@ The GraphQL interface is automatically reflected from your database's schema and
The GraphQL API resolves all requests in a single round-trip leading to fast response times and high throughput.
Reference:
+
- [Docs](https://supabase.github.io/pg_graphql/)
- [Source Code](https://github.com/supabase/pg_graphql)
diff --git a/apps/docs/pages/guides/api/joins-and-nesting.mdx b/apps/docs/pages/guides/api/joins-and-nesting.mdx
index 205e1ceece0..1ee2d396193 100644
--- a/apps/docs/pages/guides/api/joins-and-nesting.mdx
+++ b/apps/docs/pages/guides/api/joins-and-nesting.mdx
@@ -40,24 +40,25 @@ Let's use an example database that stores `countries` and `cities`:
```sql
-create table
- countries ("id" serial primary key, "name" text);
+create table countries (
+ "id" serial primary key,
+ "name" text
+);
-insert into
- countries (id, name)
+insert into countries
+ (id, name)
values
(1, 'United Kingdom'),
(2, 'United States');
-create table
- cities (
- "id" serial primary key,
- "name" text,
- "country_id" int references "countries"
- );
+create table cities (
+ "id" serial primary key,
+ "name" text,
+ "country_id" int references "countries"
+);
-insert into
- cities (name, country_id)
+insert into cities
+ (name, country_id)
values
('London', 1),
('Manchester', 1),
@@ -130,18 +131,21 @@ GET https://[REF].supabase.co/rest/v1/countries?select=id,name,cities(id,name)
The Serverless APIs will detect many-to-many joins. For example, if you have a database which stored teams of users (where each user could belong to many teams):
```sql
-create table
- users ("id" serial primary key, "name" text);
+create table users (
+ "id" serial primary key,
+ "name" text
+);
-create table
- teams ("id" serial primary key, "team_name" text);
+create table teams (
+ "id" serial primary key,
+ "team_name" text
+);
-create table
- members (
- "user_id" int references users,
- "team_id" int references teams,
- primary key(user_id, team_id)
- );
+create table members (
+ "user_id" int references users,
+ "team_id" int references teams,
+ primary key (user_id, team_id)
+);
```
In these cases you don't need to explicitly define the joining table (members). If we wanted to fetch all the teams and the members in each team:
diff --git a/apps/docs/pages/guides/api/securing-your-api.mdx b/apps/docs/pages/guides/api/securing-your-api.mdx
index 70fa2ef38ae..5887a6a33b8 100644
--- a/apps/docs/pages/guides/api/securing-your-api.mdx
+++ b/apps/docs/pages/guides/api/securing-your-api.mdx
@@ -49,10 +49,8 @@ To confirm that safeupdate is enabled for API queries, run the following query:
select
usename,
useconfig
-from
- pg_shadow
-where
- usename = 'authenticator';
+from pg_shadow
+where usename = 'authenticator';
```
The expected value for `useconfig` should be:
diff --git a/apps/docs/pages/guides/auth/auth-captcha.mdx b/apps/docs/pages/guides/auth/auth-captcha.mdx
index 6aaee2f4388..b2546a5c7b6 100644
--- a/apps/docs/pages/guides/auth/auth-captcha.mdx
+++ b/apps/docs/pages/guides/auth/auth-captcha.mdx
@@ -7,7 +7,7 @@ export const meta = {
video: 'https://www.youtube.com/v/em1cpOAXknM',
}
-Supabase provides you with the option of adding captcha to your sign-in, sign-up, and password reset forms. This keeps your website safe from bots and malicious scripts. Supabase authentication has support for [hCaptcha](https://www.hcaptcha.com/).
+Supabase provides you with the option of adding captcha to your sign-in, sign-up, and password reset forms. This keeps your website safe from bots and malicious scripts. Supabase authentication has support for [hCaptcha](https://www.hcaptcha.com/) and [Cloudflare Turnstile](https://www.cloudflare.com/products/turnstile/).
-## Sign up for hCaptcha
+## Sign up for Captcha
+
+
Go to the [hCaptcha](https://www.hcaptcha.com/) website and sign up for an account. On the welcome page, copy the **Sitekey** and **Secret key**.
If you have already signed up and didn't copy this information from the welcome page, you can get the **Secret key** from the settings page.
@@ -34,17 +41,34 @@ In the Settings page, look for the **Sitekey** section and copy the key.

-## Enable hCaptcha protection for your Supabase project
+
-Navigate to the **[Authentication](https://app.supabase.com/project/_/settings/auth)** page in the Supabase Dashboard and find the **Enable hCaptcha protection** toggle under the **Security and Protection** section.
+
+ Go to the [Cloudflare website](https://dash.cloudflare.com/login) and sign up for an account. On the welcome page, head to the Turnstile section and add a new site. Create a site and take note of the **Sitekey** and **Secret Key** as shown below
+ 
+
+
+
+## Enable Captcha protection for your Supabase project
+
+Navigate to the **[Authentication](https://app.supabase.com/project/_/settings/auth)** page in the Supabase Dashboard and find the **Enable Captcha protection** toggle under the **Security and Protection** section.

-Enter your hCaptcha **Secret key** and click **Save**.
+Enter your Captcha **Secret key** and click **Save**.
-## Add the hCaptcha frontend component
+## 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 hCaptcha React component, but hCaptcha 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.
+
+
+
+
Install `@hcaptcha/react-hcaptcha` in your project as a dependency.
@@ -58,7 +82,7 @@ Now import the `HCaptcha` component from the `@hcaptcha/react-hcaptcha` library.
import HCaptcha from '@hcaptcha/react-hcaptcha'
```
-Let’s create a empty state to store our `captchaToken`
+Let's create a empty state to store our `captchaToken`
```jsx
const [captchaToken, setCaptchaToken] = useState()
@@ -75,7 +99,7 @@ We will pass it the sitekey we copied from the hCaptcha website as a property al
```jsx
{ setCaptchaToken(token) }
+ onVerify={(token) => { setCaptchaToken(token) }
/>
```
@@ -117,6 +141,60 @@ captcha.current.resetCaptcha()
In order to test that this works locally we will need to use something like [ngrok](https://ngrok.com/) or add an entry to your hosts file. You can read more about this in the [hCaptcha docs](https://docs.hcaptcha.com/#local-development).
+
+
+
+
+ The frontend requires some changes to provide the captcha on-screen for the user. This example uses React and the Turnstile React component, but Turnstile can be used with any JavaScript framework.
+
+Install @marsidev/react-turnstile in your project as a dependency.
+
+```bash
+npm install @marsidev/react-turnstile
+```
+
+Now import the Turnstile component from the @marsidev/react-turnstile library.
+
+```jsx
+import { Turnstile } from '@marsidev/react-turnstile'
+```
+
+Let's create an empty state to store our `captchaToken`
+
+```jsx
+const [captchaToken, setCaptchaToken] = useState()
+```
+
+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`
+
+```jsx
+ { setCaptchaToken(token) }
+/>
+```
+
+We can now use the captchaToken we receive in our Supabase `signUp` function.
+
+```jsx
+await supabase.auth.signUp({
+ email,
+ password,
+ options: { captchaToken },
+})
+```
+
+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/)
+
+
+
+
Run the application and you should now be provided with a captcha challenge.
export const Page = ({ children }) =>
diff --git a/apps/docs/pages/guides/auth/auth-helpers/auth-ui.mdx b/apps/docs/pages/guides/auth/auth-helpers/auth-ui.mdx
index 66e26a91c2d..53cc8a37d90 100644
--- a/apps/docs/pages/guides/auth/auth-helpers/auth-ui.mdx
+++ b/apps/docs/pages/guides/auth/auth-helpers/auth-ui.mdx
@@ -94,7 +94,7 @@ The Auth component is currently shipped with the following views:
- Update password
- Forgotten password
-We are planning on adding more views in the future. Follow along on that [repo](https://github.com/supabase/auth-ui).
+We are planning on adding more views in the future. Follow along on that [repo](https://github.com/supabase/auth-ui).
## Customization
@@ -202,10 +202,7 @@ See the list of [tokens within a theme](https://github.com/supabase/auth-ui/blob
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
-const supabase = createClient(
- '',
- ''
-)
+const supabase = createClient('', '')
const customTheme = {
default: {
@@ -214,6 +211,7 @@ const customTheme = {
brandAccent: 'hsl(154 54.8% 45.1%)',
brandButtonText: 'white',
// ..
+ },
},
dark: {
colors: {
@@ -238,7 +236,7 @@ const App = () => (
)
```
diff --git a/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx b/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
index 5cad755ec61..be152b784ce 100644
--- a/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
+++ b/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
@@ -10,7 +10,7 @@ export const meta = {
The Next.js Auth Helpers package configures Supabase Auth to store the user's session in a cookie, rather than `localStorage`. This makes the users's session available server-side - in Server Components and Route Handlers - and is automatically sent along with any requests to Supabase.
-> The `app` directory in Next.js is still in beta and expected to change. For examples using the `pages` directory check out [Auth Helpers in Next.js](/docs/guides/auth/auth-helpers/nextjs).
+> Note: If you are using the `pages` directory, check out [Auth Helpers in Next.js](/docs/guides/auth/auth-helpers/nextjs).
-