docs walkthrough

This commit is contained in:
Saxon Fletcher committed 2025-07-23 18:06:31 +10:00
1 parent 478ca3cb8e
commit d1dcc248ae
7 files changed
+923

No files matched your search

+6
View File
@@ -148,6 +148,12 @@ const clientLibraries = [
]
const additionalResources = [
{
title: 'Interactive Walkthrough',
description: 'A step-by-step guide to building with Supabase.',
icon: 'compass',
href: '/walkthrough',
},
{
title: 'Management API',
description: 'Manage your Supabase projects and organizations.',
+448
View File
@@ -0,0 +1,448 @@
'use client'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
import { useState } from 'react'
import {
Button,
ToggleGroup,
ToggleGroupItem,
Card,
CardHeader,
CardTitle,
CardContent,
Checkbox_Shadcn_,
} from 'ui'
import { IconPanel } from 'ui-patterns/IconPanel'
import { useBreakpoint } from 'common'
import {
Tabs_Shadcn_ as Tabs,
TabsContent_Shadcn_ as TabsContent,
TabsList_Shadcn_ as TabsList,
TabsTrigger_Shadcn_ as TabsTrigger,
} from 'ui'
import { cn } from 'ui'
import { Code, MousePointerClick, Check } from 'lucide-react'
const steps = [
{ id: 'step1', title: '1. Choose Workflow' },
{ id: 'step2', title: '2. Create a Project' },
{ id: 'step3', title: '3. Modify Schema' },
{ id: 'step4', title: '4. Configure Auth' },
{ id: 'step5', title: '5. Connect to App' },
{ id: 'step6', title: '6. Go to Production' },
{ id: 'step7', title: '7. Branching' },
]
type Workflow = 'code-first' | 'no-code'
interface WalkthroughClientPageProps {
codeFirstSchemaContent: React.ReactNode
noCodeSchemaContent: React.ReactNode
codeFirstAuthConfig: React.ReactNode
noCodeAuthConfig: React.ReactNode
connectToAppContent: React.ReactNode
createProjectContent: React.ReactNode
codeFirstBranchingContent: React.ReactNode
noCodeBranchingContent: React.ReactNode
}
const checklistItems = [
{
id: 'security',
title: 'Security',
description:
'Enable RLS on tables, configure SSL and Network Restrictions, and use MFA to protect your account. Use the Security Advisor to find issues.',
},
{
id: 'performance',
title: 'Performance',
description:
'Add database indexes, perform load testing, and upgrade your database if needed. Use the Performance Advisor for suggestions.',
},
{
id: 'availability',
title: 'Availability',
description:
'Use a custom SMTP server for auth emails. For critical applications, upgrade to a paid plan and configure PITR and Read Replicas.',
},
{
id: 'rate-limiting',
title: 'Rate Limiting and Abuse Prevention',
description: 'Be aware of rate limits. Use CAPTCHA on auth endpoints to prevent abuse.',
},
{
id: 'status-page',
title: 'Subscribe to Status Page',
description: 'Stay informed about Supabase service status by subscribing to the status page.',
},
]
const ProductionChecklist = () => {
const [checkedState, setCheckedState] = useState<Record<string, boolean>>({})
const handleCheckedChange = (id: string, checked: boolean) => {
setCheckedState((prev) => ({ ...prev, [id]: checked }))
}
return (
<div>
<h2 className="text-3xl font-medium mb-2">Getting Ready for Production</h2>
<p className="text-foreground-light text-lg mb-8">
Here are the final steps to get your application ready for production users. This is a
summary of our{' '}
<a
href="/docs/guides/deployment/going-into-prod"
target="_blank"
className="text-brand underline"
>
Production Checklist
</a>
.
</p>
<Card className="mt-8">
<CardHeader>
<CardTitle>Production Checklist</CardTitle>
</CardHeader>
<CardContent className="p-0">
<ul className="text-foreground-light">
{checklistItems.map((item, index) => (
<li
key={item.id}
className={cn(
'flex items-start gap-4 py-4 px-6',
index < checklistItems.length - 1 && 'border-b'
)}
>
<Checkbox_Shadcn_
id={item.id}
checked={checkedState[item.id] ?? false}
onCheckedChange={(checked) => handleCheckedChange(item.id, !!checked)}
className="mt-1"
/>
<div className="grid gap-1.5 leading-none">
<label
htmlFor={item.id}
className="font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
{item.title}
</label>
<p className="text-sm text-foreground-lighter">{item.description}</p>
</div>
</li>
))}
</ul>
</CardContent>
</Card>
</div>
)
}
export function WalkthroughClientPage({
codeFirstSchemaContent,
noCodeSchemaContent,
codeFirstAuthConfig,
noCodeAuthConfig,
connectToAppContent,
createProjectContent,
codeFirstBranchingContent,
noCodeBranchingContent,
}: WalkthroughClientPageProps) {
const router = useRouter()
const [workflow, setWorkflow] = useState<Workflow | null>('code-first')
const [currentStep, setCurrentStep] = useState(steps[0].id)
const handleNext = () => {
const currentIndex = steps.findIndex((s) => s.id === currentStep)
if (currentIndex === steps.length - 1) {
router.push('/docs')
} else if (currentIndex < steps.length - 1) {
setCurrentStep(steps[currentIndex + 1].id)
}
}
const handleBack = () => {
const currentIndex = steps.findIndex((s) => s.id === currentStep)
if (currentIndex > 0) {
setCurrentStep(steps[currentIndex - 1].id)
}
}
const Step1 = (
<div>
<h2 className="text-3xl font-medium mb-2">Choose Your Preferred Workflow</h2>
<p className="mb-6 text-foreground-light">
Supabase can be used in a code-first or no-code approach. When your needs change you can
transition between the two.
</p>
<ToggleGroup
type="single"
value={workflow ?? ''}
onValueChange={(value) => {
setWorkflow(value ? (value as Workflow) : null)
}}
className="grid grid-cols-1 md:grid-cols-2 gap-4"
>
<ToggleGroupItem
value="code-first"
className="p-6 h-auto flex-col gap-2 border data-[state=on]:border-1 data-[state=on]:border"
aria-label="Code-first"
>
<Code className="w-8 h-8 mb-2" strokeWidth={1.5} />
<h3 className="font-bold">Code-first</h3>
<p className="text-sm text-foreground-light font-normal">
Your schema, functions and configuration are defined in code.
</p>
</ToggleGroupItem>
<ToggleGroupItem
value="no-code"
className="p-6 h-auto flex-col gap-2 border data-[state=on]:border-1 data-[state=on]:border"
aria-label="No-code"
>
<MousePointerClick className="w-8 h-8 mb-2" strokeWidth={1.5} />
<h3 className="font-bold">No-code</h3>
<p className="text-sm text-foreground-light font-normal">
Use the Supabase Dashboard to manage your database, functions and project configuration
</p>
</ToggleGroupItem>
</ToggleGroup>
{workflow && (
<Card className="mt-8">
<CardHeader>
<CardTitle>Ideal for</CardTitle>
</CardHeader>
<CardContent className="p-0">
{workflow === 'code-first' ? (
<ul className="text-foreground-light">
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Complex applications with custom business logic.
</li>
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Teams that use Git for version control and CI/CD.
</li>
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Automated testing and deployment pipelines.
</li>
<li className="flex items-center gap-2 py-3 px-6">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Projects that require fine-grained control over the database schema.
</li>
</ul>
) : (
<ul className="text-foreground-light">
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Rapid prototyping and MVPs.
</li>
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Internal tools and dashboards.
</li>
<li className="flex items-center gap-2 py-3 px-6 border-b">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Simple applications with standard features.
</li>
<li className="flex items-center gap-2 py-3 px-6">
<Check className="text-foreground-lighter" strokeWidth={1.5} size={16} />
Developers who prefer a visual interface for speed.
</li>
</ul>
)}
</CardContent>
</Card>
)}
</div>
)
const Step2 = <div>{createProjectContent}</div>
const Step3 = (
<div>
<h2 className="text-3xl font-medium mb-2">Modifying Your Database Schema</h2>
{!workflow ? (
<p className="text-foreground-light">Please select a workflow in Step 1.</p>
) : workflow === 'code-first' ? (
codeFirstSchemaContent
) : (
noCodeSchemaContent
)}
</div>
)
const Step4 = (
<div>
<h2 className="text-3xl font-medium mb-2">Configure Authentication</h2>
{!workflow ? (
<p className="text-foreground-light">Please select a workflow in Step 1.</p>
) : workflow === 'code-first' ? (
codeFirstAuthConfig
) : (
noCodeAuthConfig
)}
</div>
)
const frameworks = [
{
tooltip: 'ReactJS',
icon: '/docs/img/icons/react-icon',
href: '/guides/getting-started/quickstarts/reactjs',
},
{
tooltip: 'Next.js',
icon: '/docs/img/icons/nextjs-icon',
href: '/guides/getting-started/quickstarts/nextjs',
},
{
tooltip: 'RedwoodJS',
icon: '/docs/img/icons/redwoodjs-icon',
href: '/guides/getting-started/quickstarts/redwoodjs',
},
{
tooltip: 'Flutter',
icon: '/docs/img/icons/flutter-icon',
href: '/guides/getting-started/quickstarts/flutter',
},
{
tooltip: 'Android Kotlin',
icon: '/docs/img/icons/kotlin-icon',
href: '/guides/getting-started/quickstarts/kotlin',
},
{
tooltip: 'SvelteKit',
icon: '/docs/img/icons/svelte-icon',
href: '/guides/getting-started/quickstarts/sveltekit',
},
{
tooltip: 'SolidJS',
icon: '/docs/img/icons/solidjs-icon',
href: '/guides/getting-started/quickstarts/solidjs',
},
{
tooltip: 'Vue',
icon: '/docs/img/icons/vuejs-icon',
href: '/guides/getting-started/quickstarts/vue',
},
{
tooltip: 'Nuxt',
icon: '/docs/img/icons/nuxt-icon',
href: '/guides/getting-started/quickstarts/nuxtjs',
},
{
tooltip: 'refine',
icon: '/docs/img/icons/refine-icon',
href: '/guides/getting-started/quickstarts/refine',
},
]
const [selectedFramework, setSelectedFramework] = useState<string | null>('Next.js')
const isXs = useBreakpoint(639)
const iconSize = isXs ? 'sm' : 'lg'
const Step5 = (
<div>
<h2 className="text-3xl font-medium mb-2">Connecting to Your App</h2>
<p className="mb-4 text-foreground-light text-lg">
We have a quickstart for each of the following frameworks.
</p>
<div className="flex flex-wrap gap-2 my-8">
{frameworks.map((f) => (
<Button
type="text"
className="h-auto p-0"
key={f.tooltip}
onClick={() => setSelectedFramework(f.tooltip)}
>
<IconPanel
iconSize={iconSize}
hideArrow
className="pointer-events-none"
tooltip={f.tooltip}
icon={f.icon}
/>
</Button>
))}
</div>
{selectedFramework && connectToAppContent}
</div>
)
const Step6 = <ProductionChecklist />
const Step7 = (
<div>
<h2 className="text-3xl font-medium mb-2">Branching</h2>
{!workflow ? (
<p className="text-foreground-light">Please select a workflow in Step 1.</p>
) : workflow === 'code-first' ? (
<div>{codeFirstBranchingContent}</div>
) : (
<div>{noCodeBranchingContent}</div>
)}
</div>
)
const currentIndex = steps.findIndex((s) => s.id === currentStep)
return (
<div className="bg-alternative relative">
{workflow && (
<ToggleGroup
type="single"
className="fixed top-16 right-8 z-50"
value={workflow ?? ''}
onValueChange={(value) => {
if (value) setWorkflow(value as Workflow)
}}
>
<ToggleGroupItem value="code-first" aria-label="Code-first workflow">
<Code className="h-5 w-5" />
</ToggleGroupItem>
<ToggleGroupItem value="no-code" aria-label="No-code workflow">
<MousePointerClick className="h-5 w-5" />
</ToggleGroupItem>
</ToggleGroup>
)}
<Tabs value={currentStep} onValueChange={setCurrentStep} className="flex flex-col h-screen">
<div className="flex-grow p-4 md:p-8 overflow-y-auto">
<div className="max-w-3xl mx-auto py-8">
<TabsContent value="step1">{Step1}</TabsContent>
<TabsContent value="step2">{Step2}</TabsContent>
<TabsContent value="step3">{Step3}</TabsContent>
<TabsContent value="step4">{Step4}</TabsContent>
<TabsContent value="step5">{Step5}</TabsContent>
<TabsContent value="step6">{Step6}</TabsContent>
<TabsContent value="step7">{Step7}</TabsContent>
<div className="mt-8 flex justify-between">
<Button
size="small"
type="default"
onClick={handleBack}
disabled={currentIndex === 0}
>
Back
</Button>
<Button size="small" onClick={handleNext}>
{currentIndex === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
</div>
<TabsList className="w-full flex justify-center gap-x-8 border-t bg-surface-75 p-4 sticky bottom-0 rounded-none">
{steps.map((step) => (
<TabsTrigger
key={step.id}
value={step.id}
className="border-b-0 data-[state=active]:bg-surface-100 py-4 px-6 rounded-lg data-[state=active]:border-0"
>
{step.title}
</TabsTrigger>
))}
</TabsList>
</Tabs>
</div>
)
}
+26
View File
@@ -0,0 +1,26 @@
import {
CodeFirstSchemaContent,
NoCodeSchemaContent,
CodeFirstAuthConfig,
NoCodeAuthConfig,
ConnectToAppContent,
CreateProjectContent,
CodeFirstBranchingContent,
NoCodeBranchingContent,
} from './step-content'
import { WalkthroughClientPage } from './client-page'
export default function WalkthroughsPage() {
return (
<WalkthroughClientPage
codeFirstSchemaContent={<CodeFirstSchemaContent />}
noCodeSchemaContent={<NoCodeSchemaContent />}
codeFirstAuthConfig={<CodeFirstAuthConfig />}
noCodeAuthConfig={<NoCodeAuthConfig />}
connectToAppContent={<ConnectToAppContent />}
createProjectContent={<CreateProjectContent />}
codeFirstBranchingContent={<CodeFirstBranchingContent />}
noCodeBranchingContent={<NoCodeBranchingContent />}
/>
)
}
+443
View File
@@ -0,0 +1,443 @@
import { Card, CardHeader, CardTitle } from 'ui'
import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock'
import { Edit, Terminal, Sparkles, Users, AtSign, Github } from 'lucide-react'
import { Image } from 'ui'
import StepHikeCompact from '~/components/StepHikeCompact'
export async function CodeFirstSchemaContent() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
Use a declarative schema file to define your database structure. The Supabase CLI compares
this to your database state to generate migration files.
</p>
<StepHikeCompact>
<StepHikeCompact.Step step={1} title="Define your schema">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Create or edit a SQL file in the <code>supabase/schemas</code> directory to define
your tables, views, and functions.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="sql"
contents={`create table "employees" (
"id" integer not null,
"name" text
);`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2} title="Generate a migration">
<StepHikeCompact.Details>
<p className="text-foreground-light">
This command creates a new migration file with the SQL needed to update your database.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock lang="bash" contents={`supabase db diff -f <migration_name>`} />
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3} title="Deploy your changes">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Apply the migrations to your production database.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock lang="bash" contents={`supabase db push`} />
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
</div>
)
}
export function CreateProjectContent() {
return (
<div>
<h2 className="text-3xl font-medium mb-2">Create a new Supabase project</h2>
<p className="text-foreground-light text-lg mb-8">
Before you can start building, you need to create a project in the Supabase Dashboard.
</p>
<StepHikeCompact>
<StepHikeCompact.Step step={1} title="Go to the Supabase Dashboard">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Navigate to{' '}
<a
href="https://app.supabase.com"
target="_blank"
rel="noopener noreferrer"
className="text-brand underline"
>
app.supabase.com
</a>{' '}
to get started.
</p>
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2} title="Create a new project">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Click on "New project" and choose the organization you want to create the project in.
</p>
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3} title="Fill in project details">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Provide a name for your project, generate a secure database password, and choose the
region closest to your users.
</p>
</StepHikeCompact.Details>
</StepHikeCompact.Step>
</StepHikeCompact>
</div>
)
}
export async function CodeFirstAuthConfig() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
Manage your authentication settings by defining them in your{' '}
<code>supabase/config.toml</code> file. This allows you to keep your auth configuration in
version control.
</p>
<StepHikeCompact>
<StepHikeCompact.Step step={1} title="Configure Site URLs">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Set your application's site URL and any additional redirect URLs. This is crucial for
security and ensures that users are redirected to the correct location after
authentication.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="toml"
contents={`[auth]
site_url = "http://localhost:3000"
additional_redirect_urls = [
"https://example.com/welcome"
]`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2} title="Manage User Sign-ups">
<StepHikeCompact.Details>
<p className="text-foreground-light">
You can enable or disable new user sign-ups. For many applications, you might want to
disable sign-ups after an initial period.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="toml"
contents={`[auth]
disable_signup = false # set to true to disable new sign-ups`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3} title="Enable Social Providers">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Enable social providers like GitHub by adding their configuration. You'll need to get
the client ID and secret from the provider's developer console.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="toml"
contents={`[auth.external.github]
enabled = true
client_id = "your-github-client-id"
secret = "your-github-client-secret"
`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
</div>
)
}
export function NoCodeSchemaContent() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
The Dashboard provides several ways to modify your database schema
</p>
<div className="space-y-4">
<Card className="p-0 relative">
<Image
fill
alt="Diagram showing the state transitions of a signing key"
src={{
light: '/docs/img/walkthrough/schema-table.webp',
dark: '/docs/img/walkthrough/schema-table.webp',
}}
/>
<div className="p-4 flex items-start gap-4 border-t">
<Edit className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">Table Editor</h4>
<p className="text-foreground-light">
Visually create, edit, and delete tables and columns. This is the easiest way to get
started and manage your database for most use cases.
</p>
</div>
</div>
</Card>
<Card className="p-0 relative">
<Image
fill
alt="Diagram showing the state transitions of a signing key"
src={{
light: '/docs/img/walkthrough/schema-ai.webp',
dark: '/docs/img/walkthrough/schema-ai.webp',
}}
/>
<div className="p-4 flex items-start gap-4 border-t">
<Sparkles className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">AI Assistant</h4>
<p className="text-foreground-light">
Use the AI Assistant to generate SQL from natural language prompts. Describe what
you want to do, and the AI will generate the SQL for you to review and run.
</p>
</div>
</div>
</Card>
<Card className="p-0 relative">
<Image
fill
alt="Diagram showing the state transitions of a signing key"
src={{
light: '/docs/img/walkthrough/schema-sql.webp',
dark: '/docs/img/walkthrough/schema-sql.webp',
}}
/>
<div className="p-4 flex items-start gap-4 border-t">
<Terminal className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">SQL Editor</h4>
<p className="text-foreground-light">
For more complex needs, use the SQL Editor to run any SQL command. You can create
views, functions, and advanced policies. You can also save your favorite queries as
snippets.
</p>
</div>
</div>
</Card>
</div>
</div>
)
}
export function NoCodeAuthConfig() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
Configure authentication using the Supabase Dashboard. Navigate to the Authentication
section in the sidebar to get started.
</p>
<div className="space-y-4">
<Card className="p-4 flex items-start gap-4">
<Users className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">Enable user sign-ups</h4>
<p className="text-foreground-light">
In the Providers section, you can enable or disable sign-ups for different methods,
like email and password, or phone-based login.
</p>
</div>
</Card>
<Card className="p-4 flex items-start gap-4">
<AtSign className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">Set up email provider</h4>
<p className="text-foreground-light">
In the Settings section, configure your SMTP settings to customize the emails sent to
your users for confirmations, password resets, and more.
</p>
</div>
</Card>
<Card className="p-4 flex items-start gap-4">
<Github className="w-6 h-6 mt-1 text-foreground-light" />
<div>
<h4 className="font-medium">Configure Social Providers</h4>
<p className="text-foreground-light">
In the Providers section, you can easily enable social logins like Google, GitHub, and
more. Simply toggle the provider and add your Client ID and Secret.
</p>
</div>
</Card>
</div>
</div>
)
}
export async function ConnectToAppContent() {
return (
<div>
<StepHikeCompact>
<StepHikeCompact.Step step={1} title="Create a Next.js app">
<StepHikeCompact.Details>
<p className="text-foreground-light">
The quickest way to get started is with the `with-supabase` template, which
pre-configures Cookie-based Auth, TypeScript, and Tailwind CSS.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock lang="bash" contents={`npx create-next-app -e with-supabase`} />
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2} title="Declare Supabase Environment Variables">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Rename `.env.example` to `.env.local` and add your project's URL and anon key. You can
find these in your project's API settings.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="text"
contents={`NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3} title="Start the app and sign up">
<StepHikeCompact.Details>
<p className="text-foreground-light">
The template includes a full authentication flow. Start the app and navigate to the
login page to sign up.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock lang="bash" contents={`npm run dev`} />
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={4} title="Query data from your database">
<StepHikeCompact.Details>
<p className="text-foreground-light">
Once your app is set up, you can use the Supabase client to interact with your
database. Here's how you can fetch data inside a React Server Component.
</p>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<CodeBlock
lang="tsx"
contents={`import { createClient } from '@/utils/supabase/server'
export default async function Page() {
const supabase = createClient()
const { data: employees } = await supabase.from('employees').select()
return <pre>{JSON.stringify(employees, null, 2)}</pre>
}`}
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
</div>
)
}
export function CodeFirstBranchingContent() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
After launching your app, make follow-up changes—like schema or function updates—in a
branch. This lets you safely test and review updates before they reach production. In a
code-first workflow, connecting your Supabase project to GitHub enables automatic preview
branches for pull requests, so you can validate migrations and deployments before merging.
</p>
<ol className="prose text-sm">
<li>
<h4>Connect to a GitHub repository</h4>
<p>
In your project's settings, navigate to the Integrations page and connect your Supabase
project to a GitHub repository. This will allow Supabase to sync branches and run checks
on your pull requests.
</p>
</li>
<li>
<h4>Enable automatic branching</h4>
<p>
In the GitHub integration settings, enable "Automatic branching". Now, when you create a
new branch and push it to GitHub, a corresponding preview branch will be created on
Supabase.
</p>
</li>
<li>
<h4>Deploy to production</h4>
<p>
Enable the "Deploy to production" option in the integration settings. When you merge a
pull request into your main branch, the changes will be automatically deployed to your
production project.
</p>
</li>
<li>
<h4>Enable required checks</h4>
<p>
In your GitHub repository settings, make the Supabase integration a "required check".
This prevents merging pull requests that have failing migrations, keeping your
production database safe.
</p>
</li>
</ol>
</div>
)
}
export function NoCodeBranchingContent() {
return (
<div>
<p className="text-foreground-light text-lg mb-8">
Once your app is live, any follow-up changes—like editing tables or adding new
features—should ideally be made in a branch. In a no-code workflow, you can create and
manage branches directly from the Supabase Dashboard, allowing you to safely test and review
updates before merging them into production. This approach is especially useful for quick
testing and prototyping without needing a Git repository.
</p>
<ol className="prose text-sm">
<li>
<h4>Enable Branching 2.0</h4>
<p>
Branching 2.0 is currently in public alpha. You can enable it from the Feature Preview
section in your user menu.
</p>
</li>
<li>
<h4>Create a new branch</h4>
<p>
From the branch selector in the top menu bar of the Dashboard, you can create a new
preview branch.
</p>
</li>
<li>
<h4>Make changes to your branch</h4>
<p>
Using the branch selector, switch to your new branch. Any changes you make with the
Table Editor, SQL Editor, or other dashboard tools will only apply to the preview
branch.
</p>
</li>
<li>
<h4>Merge changes to production</h4>
<p>
When you're ready, create a merge request from the dashboard. This will allow you to
review your changes and merge them into your production project.
</p>
</li>
</ol>
</div>
)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB