This commit is contained in:
Alan Daniel committed 2026-03-17 14:29:19 -04:00
1 parent 1038d88241
commit 4e986a4ef2
4 files changed
+204 -192

No files matched your search

@@ -17,30 +17,29 @@ export function ExamplesSection() {
const gridExamples = examples.slice(2, 6)
return (
<div>
{/* Header row */}
<div className="border-b border-border">
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 border-x border-border">
<div className="flex items-end justify-between pt-40 pb-8">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
What you can build <br />
<span className="text-foreground">with Edge Functions</span>
</h3>
<Link
href="/docs/guides/functions#examples"
className="text-sm text-foreground-light hover:text-foreground underline"
>
View all examples
</Link>
</div>
<div className="py-24 flex flex-col gap-16">
{/* Header */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 w-full">
<div className="flex items-end justify-between">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
What you can build <br />
<span className="text-foreground">with Edge Functions</span>
</h3>
<Link
href="/docs/guides/functions#examples"
className="text-sm text-foreground-light hover:text-foreground underline"
>
View all examples
</Link>
</div>
</div>
{/* Featured row - 2 large cells */}
<div className="border-b border-border max-w-[var(--container-max-w,75rem)] mx-auto">
<div className="border-x border-border">
<div className="grid grid-cols-1 md:grid-cols-2">
{featuredExamples.map((example) => {
{/* Cards */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] w-full">
<div className="border border-border rounded-md overflow-clip">
{/* Featured row - 2 large cells */}
<div className="grid grid-cols-1 md:grid-cols-2 border-b border-border">
{featuredExamples.map((example, i) => {
const tag = example.tags?.[0]
const icon = tag ? EXAMPLE_ICON[tag] : undefined
return (
@@ -48,7 +47,45 @@ export function ExamplesSection() {
key={example.title}
href={example.repo_url ?? '#'}
target="_blank"
className="group flex flex-col border-b md:border-b-0 md:border-r border-border last:border-r-0 last:border-b-0 px-6 py-8 hover:bg-surface-75/50 transition-colors"
className={`group flex flex-col px-6 py-8 hover:bg-surface-75/50 transition-colors ${
i < featuredExamples.length - 1
? 'border-b md:border-b-0 md:border-r border-border'
: ''
}`}
>
<div className="flex items-center gap-2 mb-4">
{icon && (
<img
src={icon.src}
alt=""
className={`${icon.className} object-contain${icon.invert ? ' dark:invert' : ''}`}
/>
)}
</div>
<h4 className="text-foreground text-sm font-medium">{example.title}</h4>
<p className="text-foreground-lighter text-sm mt-1 line-clamp-2">
{example.description}
</p>
</Link>
)
})}
</div>
{/* Grid row - 4 smaller cells */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4">
{gridExamples.map((example, i) => {
const tag = example.tags?.[0]
const icon = tag ? EXAMPLE_ICON[tag] : undefined
return (
<Link
key={example.title}
href={example.repo_url ?? '#'}
target="_blank"
className={`group flex flex-col px-6 py-8 hover:bg-surface-75/50 transition-colors ${
i < gridExamples.length - 1
? 'border-b sm:border-b-0 sm:border-r border-border'
: ''
}`}
>
<div className="flex items-center gap-2 mb-4">
{icon && (
@@ -69,38 +106,6 @@ export function ExamplesSection() {
</div>
</div>
</div>
{/* Grid row - 4 smaller cells */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] border-x border-border">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4">
{gridExamples.map((example) => {
const tag = example.tags?.[0]
const icon = tag ? EXAMPLE_ICON[tag] : undefined
return (
<Link
key={example.title}
href={example.repo_url ?? '#'}
target="_blank"
className="group flex flex-col border-b sm:border-b-0 sm:border-r border-border last:border-r-0 last:border-b-0 px-6 py-8 hover:bg-surface-75/50 transition-colors"
>
<div className="flex items-center gap-2 mb-4">
{icon && (
<img
src={icon.src}
alt=""
className={`${icon.className} object-contain${icon.invert ? ' dark:invert' : ''}`}
/>
)}
</div>
<h4 className="text-foreground text-sm font-medium">{example.title}</h4>
<p className="text-foreground-lighter text-sm mt-1 line-clamp-2">
{example.description}
</p>
</Link>
)
})}
</div>
</div>
</div>
)
}
@@ -72,109 +72,109 @@ export function IntegratesSectionClient({ useCases }: { useCases: UseCase[] }) {
}
return (
<div ref={inViewRef}>
{/* Header row */}
<div className="border-b border-border">
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 border-x border-border">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl pt-40 pb-8">
Integrates with the <span className="text-foreground">Supabase ecosystem</span>
</h3>
</div>
<div ref={inViewRef} className="py-24 flex flex-col gap-16 border-b border-border">
{/* Header */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 w-full">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
Integrates with the <span className="text-foreground">Supabase ecosystem</span>
</h3>
</div>
{/* Content */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] border-x border-border">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-0">
{/* Left: vertical tabs */}
<div className="flex flex-col">
{useCases.map((useCase, index) => {
const isActive = index === activeIdx
return (
<button
key={useCase.label}
onClick={() => handleTabClick(index)}
className={cn(
'relative text-left flex flex-col gap-1 px-6 py-5 transition-colors',
isActive
? 'bg-surface-75 text-foreground'
: 'text-foreground-muted hover:text-foreground-light hover:bg-surface-75/50'
)}
>
<h4 className="text-sm font-medium flex items-center gap-2">
{(() => {
const Icon = ICONS[useCase.icon]
return <Icon size={14} strokeWidth={2} />
})()}
{useCase.label}
</h4>
<p
<div className="mx-auto max-w-[var(--container-max-w,75rem)] w-full">
<div className="border border-border rounded-md overflow-clip">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-0">
{/* Left: vertical tabs */}
<div className="flex flex-col">
{useCases.map((useCase, index) => {
const isActive = index === activeIdx
return (
<button
key={useCase.label}
onClick={() => handleTabClick(index)}
className={cn(
'text-sm transition-colors',
isActive ? 'text-foreground-lighter' : 'text-foreground-muted'
'relative text-left flex flex-col gap-1 px-6 py-5 transition-colors',
isActive
? 'bg-surface-75 text-foreground'
: 'text-foreground-muted hover:text-foreground-light hover:bg-surface-75/50'
)}
>
{useCase.paragraph}
</p>
{/* Progress bar — hide on last item to avoid doubling with section border-y */}
<div className={cn("absolute bottom-0 left-0 right-0 h-[1px] bg-border-strong overflow-hidden", index === useCases.length - 1 && 'hidden')}>
{isActive && (
<motion.div
className={cn(
'absolute inset-0 w-full right-full bg-foreground-muted h-full transition-opacity',
progress > 99.5 ? 'opacity-0' : 'opacity-100'
)}
style={{ x: `${progress - 100}%` }}
/>
)}
</div>
</button>
)
})}
</div>
<h4 className="text-sm font-medium flex items-center gap-2">
{(() => {
const Icon = ICONS[useCase.icon]
return <Icon size={14} strokeWidth={2} />
})()}
{useCase.label}
</h4>
<p
className={cn(
'text-sm transition-colors',
isActive ? 'text-foreground-lighter' : 'text-foreground-muted'
)}
>
{useCase.paragraph}
</p>
{/* Progress bar — hide on last item to avoid doubling with section border */}
<div className={cn("absolute bottom-0 left-0 right-0 h-[1px] bg-border-strong overflow-hidden", index === useCases.length - 1 && 'hidden')}>
{isActive && (
<motion.div
className={cn(
'absolute inset-0 w-full right-full bg-foreground-muted h-full transition-opacity',
progress > 99.5 ? 'opacity-0' : 'opacity-100'
)}
style={{ x: `${progress - 100}%` }}
/>
)}
</div>
</button>
)
})}
</div>
{/* Right: code area */}
<div className="relative min-h-[440px] overflow-auto lg:border-l border-border">
<AnimatePresence mode="wait">
<motion.div
key={active.label}
initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15, delay: 0.05 } }}
exit={{ opacity: 0, transition: { duration: 0.05 } }}
{/* Right: code area */}
<div className="relative min-h-[440px] overflow-auto lg:border-l border-border">
<AnimatePresence mode="wait">
<motion.div
key={active.label}
initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15, delay: 0.05 } }}
exit={{ opacity: 0, transition: { duration: 0.05 } }}
>
<div
dangerouslySetInnerHTML={{ __html: active.darkHtml }}
className="hidden dark:block [&_pre]:!bg-transparent [&_pre]:m-0 [&_pre]:p-6"
style={{ fontSize: '0.8125rem', fontWeight: 500, lineHeight: 1.7 }}
/>
<div
dangerouslySetInnerHTML={{ __html: active.lightHtml }}
className="block dark:hidden [&_pre]:!bg-transparent [&_pre]:m-0 [&_pre]:p-6"
style={{ fontSize: '0.8125rem', fontWeight: 500, lineHeight: 1.7 }}
/>
</motion.div>
</AnimatePresence>
<Link
href="/docs/guides/functions"
className="absolute bottom-4 right-4 flex items-center gap-1.5 rounded-full bg-surface-100 border border-border px-3 py-1.5 text-xs text-foreground-light hover:text-foreground hover:bg-surface-200 transition-colors whitespace-nowrap"
>
<div
dangerouslySetInnerHTML={{ __html: active.darkHtml }}
className="hidden dark:block [&_pre]:!bg-transparent [&_pre]:m-0 [&_pre]:p-6"
style={{ fontSize: '0.8125rem', fontWeight: 500, lineHeight: 1.7 }}
/>
<div
dangerouslySetInnerHTML={{ __html: active.lightHtml }}
className="block dark:hidden [&_pre]:!bg-transparent [&_pre]:m-0 [&_pre]:p-6"
style={{ fontSize: '0.8125rem', fontWeight: 500, lineHeight: 1.7 }}
/>
</motion.div>
</AnimatePresence>
<Link
href="/docs/guides/functions"
className="absolute bottom-4 right-4 flex items-center gap-1.5 rounded-full bg-surface-100 border border-border px-3 py-1.5 text-xs text-foreground-light hover:text-foreground hover:bg-surface-200 transition-colors whitespace-nowrap"
>
Documentation
<svg
width={12}
height={12}
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="shrink-0"
>
<path
d="M3.5 2.5H9.5V8.5M9.5 2.5L2.5 9.5"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</Link>
Documentation
<svg
width={12}
height={12}
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="shrink-0"
>
<path
d="M3.5 2.5H9.5V8.5M9.5 2.5L2.5 9.5"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</Link>
</div>
</div>
</div>
</div>
@@ -123,38 +123,38 @@ function LocalDXCard() {
export function LocalDXSection() {
return (
<div>
{/* Header row */}
<div className="border-b border-border">
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 border-x border-border">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 items-end pt-40 pb-8">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
Delightful DX from <br />
<span className="text-foreground">local to production</span>
</h3>
<p className="text-foreground-lighter text-sm lg:text-base">
Edge Functions are developed using{' '}
<Link
href="https://deno.com/"
className="underline hover:text-foreground-light transition-colors"
target="_blank"
>
Deno
</Link>
, an open source JavaScript runtime that ensures maximum power and flexibility.
Migrate in and out at any time with no vendor lock-in.
</p>
</div>
<div className="py-24 flex flex-col gap-16">
{/* Header */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 w-full">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 items-end">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
Delightful DX from <br />
<span className="text-foreground">local to production</span>
</h3>
<p className="text-foreground-lighter text-sm lg:text-base">
Edge Functions are developed using{' '}
<Link
href="https://deno.com/"
className="underline hover:text-foreground-light transition-colors"
target="_blank"
>
Deno
</Link>
, an open source JavaScript runtime that ensures maximum power and flexibility. Migrate
in and out at any time with no vendor lock-in.
</p>
</div>
</div>
{/* Bento grid */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] border-x border-border">
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 grid-flow-dense">
<LocalDXCard />
<ParityCard />
<CICard />
<EcosystemCard />
<div className="mx-auto max-w-[var(--container-max-w,75rem)] w-full">
<div className="border border-border rounded-md overflow-clip">
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 grid-flow-dense">
<LocalDXCard />
<ParityCard />
<CICard />
<EcosystemCard />
</div>
</div>
</div>
</div>
@@ -55,26 +55,33 @@ function ObservabilityCard({
export function ObservabilitySection() {
return (
<div>
{/* Header row */}
<div className="border-b border-border">
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 border-x border-border">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl pt-40 pb-8">
Built-in <span className="text-foreground">observability</span>
<div className="py-24 flex flex-col gap-16">
{/* Header */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] px-6 w-full">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 items-end">
<h3 className="text-2xl md:text-4xl text-foreground-lighter max-w-xl">
Debug and monitor with <br />
<span className="text-foreground">built-in observability</span>
</h3>
<p className="text-foreground-lighter text-sm lg:text-base">
Monitor, debug, and optimize your Edge Functions with realtime logs, queryable log
explorer, and health dashboards — all built into the Supabase Dashboard.
</p>
</div>
</div>
{/* 3-column grid */}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] border-x border-border">
<div className="grid grid-cols-1 md:grid-cols-3">
{cards.map((card, i) => (
<ObservabilityCard
key={card.id}
card={card}
className={cn(i < cards.length - 1 && 'md:border-r')}
/>
))}
<div className="mx-auto max-w-[var(--container-max-w,75rem)] w-full">
<div className="border border-border rounded-md overflow-clip">
<div className="grid grid-cols-1 md:grid-cols-3">
{cards.map((card, i) => (
<ObservabilityCard
key={card.id}
card={card}
className={cn(i < cards.length - 1 && 'md:border-r border-border')}
/>
))}
</div>
</div>
</div>
</div>