ignitionstack.pro uses Supabase as the complete backend solution, providing:
Go to supabase.com , create a project, and get your credentials from Settings → API:
# .env
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-keyImportant:
NEXT_PUBLIC_* are public variables (client-side)SUPABASE_SERVICE_ROLE_KEY is private (server-side only).env to Gitsrc/app/lib/supabase/
├── client.ts # For Client Components
├── server.ts # For Server Components/Actions
├── middleware.ts # For Middleware
├── helpers.ts # Utilities (upload, etc.)
└── index.ts # Barrel export'use client'
import { createClient } from '@/lib/supabase/client'
export function MyClientComponent() {
const supabase = createClient()
// Use supabase client...
}import { createClient } from '@/lib/supabase/server'
export default async function MyServerComponent() {
const supabase = await createClient()
const { data } = await supabase
.from('posts')
.select('*')
.eq('published', true)
return <div>{/* render data */}</div>
}'use server'
import { createClient } from '@/lib/supabase/server'
import { revalidatePath } from 'next/cache'
export async function createPost(formData: FormData) {
const supabase = await createClient()
const { data, error } = await supabase
.from('posts')
.insert({
title: formData.get('title'),
content: formData.get('content'),
})
if (error) throw new Error(error.message)
revalidatePath('/blog')
return data
}'use server'
import { createAdminClient } from '@/lib/supabase/server'
export async function adminDeleteUser(userId: string) {
// Bypasses Row Level Security - use with care!
const supabase = createAdminClient()
const { error } = await supabase
.from('users')
.delete()
.eq('id', userId)
if (error) throw error
}