fix: Handle NavData component

This commit is contained in:
Jeremias Menichelli committed 2026-06-11 16:22:08 +02:00
1 parent 8b3239fbb3
commit 4498f69bff
6 files changed
+335 -113

No files matched your search

-14
View File
@@ -1,14 +0,0 @@
import { ReactNode } from 'react'
import { navDataForMdx } from './Navigation/NavigationMenu/NavigationMenu.constants'
export function NavData({
data,
children,
}: {
data: keyof typeof navDataForMdx
children: (navItems: (typeof navDataForMdx)[keyof typeof navDataForMdx]) => ReactNode
}) {
const navItems = navDataForMdx[data]
return children(navItems)
}
+139 -22
View File
@@ -21,28 +21,145 @@ There are several reasons why you might want to add social login to your applica
Supabase supports a suite of social providers. Follow these guides to configure a social provider for your platform.
<div className="grid grid-cols-12 xs:gap-x-10 gap-y-10 not-prose py-8">
<NavData data="socialLoginItems">
{(data) =>
data.map((item) => (
<Link
href={`${item.url}`}
key={item.name}
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel
title={item.name}
span="col-span-6"
icon={item.icon}
isDarkMode={item.isDarkMode}
hasLightIcon={item.hasLightIcon}
>
{item.description}
</IconPanel>
</Link>
))
}
</NavData>
<Link
href="/guides/auth/social-login/auth-google"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Google" span="col-span-6" icon="/docs/img/icons/google-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-facebook"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Facebook" span="col-span-6" icon="/docs/img/icons/facebook-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-apple"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Apple" span="col-span-6" icon="/docs/img/icons/apple-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-azure"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Azure (Microsoft)" span="col-span-6" icon="/docs/img/icons/microsoft-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-twitter"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Twitter" span="col-span-6" icon="/docs/img/icons/twitter-icon" hasLightIcon />
</Link>
<Link
href="/guides/auth/social-login/auth-github"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel
title="GitHub"
span="col-span-6"
icon="/docs/img/icons/github-icon"
isDarkMode
hasLightIcon
/>
</Link>
<Link
href="/guides/auth/social-login/auth-gitlab"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Gitlab" span="col-span-6" icon="/docs/img/icons/gitlab-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-bitbucket"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Bitbucket" span="col-span-6" icon="/docs/img/icons/bitbucket-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-discord"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Discord" span="col-span-6" icon="/docs/img/icons/discord-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-figma"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Figma" span="col-span-6" icon="/docs/img/icons/figma-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-kakao"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Kakao" span="col-span-6" icon="/docs/img/icons/kakao-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-keycloak"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Keycloak" span="col-span-6" icon="/docs/img/icons/keycloak-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-linkedin"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="LinkedIn" span="col-span-6" icon="/docs/img/icons/linkedin-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-notion"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Notion" span="col-span-6" icon="/docs/img/icons/notion-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-slack"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Slack" span="col-span-6" icon="/docs/img/icons/slack-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-spotify"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Spotify" span="col-span-6" icon="/docs/img/icons/spotify-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-twitch"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Twitch" span="col-span-6" icon="/docs/img/icons/twitch-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-workos"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="WorkOS" span="col-span-6" icon="/docs/img/icons/workos-icon" />
</Link>
<Link
href="/guides/auth/social-login/auth-zoom"
passHref
className="col-span-12 xs:col-span-6 lg:col-span-4 xl:col-span-3"
>
<IconPanel title="Zoom" span="col-span-6" icon="/docs/img/icons/zoom-icon" />
</Link>
</div>
<Admonition type="tip">
@@ -32,32 +32,54 @@ The IPv4 add-on is not dual-stack: enabling it swaps the project's IPv6 (AAAA) D
## Quickstarts
<div className="grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-6 not-prose">
<NavData data="ormQuickstarts">
{(data) =>
data.items?.map((quickstart) => (
<Link key={quickstart.url} href={quickstart.url} passHref>
<GlassPanel
key={quickstart.name}
title={quickstart.name}
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
))
}
</NavData>
<NavData data="guiQuickstarts">
{(data) =>
data.items?.map((quickstart) => (
<Link key={quickstart.url} href={quickstart.url} passHref>
<GlassPanel
key={quickstart.name}
title={quickstart.name}
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
))
}
</NavData>
<Link href="/guides/database/prisma" passHref>
<GlassPanel
title="Prisma"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/drizzle" passHref>
<GlassPanel
title="Drizzle"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/postgres-js" passHref>
<GlassPanel
title="Postgres.js"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/pgadmin" passHref>
<GlassPanel
title="pgAdmin"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/psql" passHref>
<GlassPanel
title="PSQL"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/dbeaver" passHref>
<GlassPanel
title="DBeaver"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/metabase" passHref>
<GlassPanel
title="Metabase"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
<Link href="/guides/database/beekeeper-studio" passHref>
<GlassPanel
title="Beekeeper Studio"
className="[&>div]:p-2 flex justify-center [&_p]:text-foreground-light"
/>
</Link>
</div>
## Data APIs and client libraries
@@ -6,20 +6,104 @@ Learn how to migrate to Supabase from another database service.
## Migration guides
<NavData data="migrationPages">
{(migrationPages) => (
<div className="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-6 mb-6 not-prose">
{migrationPages.map((page) => (
<Link href={`${page.url}`} key={page.url} passHref>
<GlassPanel
icon={page.icon}
title={page.name}
hasLightIcon={page.hasLightIcon}
background={false}
className="[&>div]:p-4"
/>
</Link>
))}
</div>
)}
</NavData>
<div className="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-6 mb-6 not-prose">
<Link href="/guides/platform/migrating-to-supabase/auth0" passHref>
<GlassPanel
icon="/docs/img/icons/auth0-icon"
title="Auth0"
hasLightIcon
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/firebase-auth" passHref>
<GlassPanel
icon="/docs/img/icons/firebase-icon"
title="Firebase Auth"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/firestore-data" passHref>
<GlassPanel
icon="/docs/img/icons/firebase-icon"
title="Firestore Data"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/firebase-storage" passHref>
<GlassPanel
icon="/docs/img/icons/firebase-icon"
title="Firebase Storage"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/heroku" passHref>
<GlassPanel
icon="/docs/img/icons/heroku-icon"
title="Heroku"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/render" passHref>
<GlassPanel
icon="/docs/img/icons/render-icon"
title="Render"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/amazon-rds" passHref>
<GlassPanel
icon="/docs/img/icons/aws-rds-icon"
title="Amazon RDS"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/postgres" passHref>
<GlassPanel
icon="/docs/img/icons/postgres-icon"
title="Postgres"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/vercel-postgres" passHref>
<GlassPanel
icon="/docs/img/icons/vercel-icon"
title="Vercel Postgres"
hasLightIcon
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/neon" passHref>
<GlassPanel
icon="/docs/img/icons/neon-icon"
title="Neon"
hasLightIcon
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/mysql" passHref>
<GlassPanel
icon="/docs/img/icons/mysql-icon"
title="MySQL"
background={false}
className="[&>div]:p-4"
/>
</Link>
<Link href="/guides/platform/migrating-to-supabase/mssql" passHref>
<GlassPanel
icon="/docs/img/icons/mssql-icon"
title="MSSQL"
background={false}
className="[&>div]:p-4"
/>
</Link>
</div>
@@ -10,7 +10,6 @@ import { Extensions } from '~/components/Extensions'
import Image, { type ImageProps } from '~/components/Image'
import { Mermaid } from '~/components/Mermaid'
import { MetricsStackCards } from '~/components/MetricsStackCards'
import { NavData } from '~/components/NavData'
import { Price } from '~/components/Price'
import { ProjectConfigVariables } from '~/components/ProjectConfigVariables'
import { RealtimeLimitsEstimator } from '~/components/RealtimeLimitsEstimator'
@@ -89,7 +88,6 @@ const components = {
Mermaid,
MetricsStackCards,
NamedCodeBlock,
NavData,
ProjectConfigVariables,
RealtimeLimitsEstimator,
RegionsList,
+47 -32
View File
@@ -245,40 +245,55 @@ function convertLinkPanels(content: string): string {
if (!hrefMatch) return full
const href = withDocsBasePath(hrefMatch[1])
const panelOpen = body.match(/<(GlassPanel|IconPanel)\b/)
if (!panelOpen) return full
const panelName = panelOpen[1]
const panelStart = panelOpen.index ?? 0
const panelOpen = body.match(/<(GlassPanel|IconPanel)\b/)
if (!panelOpen) return full
const panelName = panelOpen[1]
const panelStart = panelOpen.index ?? 0
// Walk past the opening tag, respecting JSX expression braces so attribute
// values like `title={<span>...</span>}` don't terminate parsing early.
let i = panelStart + panelOpen[0].length
let depth = 0
while (i < body.length) {
const ch = body[i]
if (ch === '{') depth++
else if (ch === '}') depth--
else if (ch === '>' && depth === 0) break
i++
// Walk past the opening tag, respecting both JSX `{}` expression depth
// (so `title={<span>...</span>}` doesn't terminate early) and quoted
// attribute values (so `>` inside `className="[&>div]..."` is ignored).
let i = panelStart + panelOpen[0].length
let depth = 0
let quote: string | null = null
while (i < body.length) {
const ch = body[i]
if (quote) {
if (ch === quote) quote = null
} else if (ch === '"' || ch === "'") {
quote = ch
} else if (ch === '{') {
depth++
} else if (ch === '}') {
depth--
} else if (ch === '>' && depth === 0) {
break
}
i++
}
if (i >= body.length) return full
const panelAttrs = body.slice(panelStart + panelOpen[0].length, i)
const title = extractTitleAttr(panelAttrs)
if (!title) return full
// Self-closing panels (`<GlassPanel ... />`) carry no description.
const isSelfClosing = panelAttrs.trimEnd().endsWith('/')
let description = ''
if (!isSelfClosing) {
const closingTag = `</${panelName}>`
const closeIdx = body.indexOf(closingTag, i)
if (closeIdx === -1) return full
description = body
.slice(i + 1, closeIdx)
.replace(/<[^>]+>/g, ' ')
.replace(/\s+/g, ' ')
.trim()
}
return `- [${title}](${href})${description ? `. ${description}` : ''}`
}
if (i >= body.length) return full
const panelAttrs = body.slice(panelStart + panelOpen[0].length, i)
const closingTag = `</${panelName}>`
const closeIdx = body.indexOf(closingTag, i)
if (closeIdx === -1) return full
const title = extractTitleAttr(panelAttrs)
if (!title) return full
const description = body
.slice(i + 1, closeIdx)
.replace(/<[^>]+>/g, ' ')
.replace(/\s+/g, ' ')
.trim()
return `- [${title}](${href})${description ? `. ${description}` : ''}`
})
)
}
/**