Next.js + Supabase is a powerful combination for building full-stack apps. Here's how to leverage both effectively.
Project Setup
npx create-next-app@latest my-app
cd my-app
npm install @supabase/supabase-js @supabase/ssr
Server-Side Authentication
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function createClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
},
}
);
}
Protected Routes with Middleware
import { createServerClient } from '@supabase/ssr';
import { NextResponse } from 'next/server';
export async function middleware(request) {
const supabase = createServerClient(/* ... */);
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*'],
};
Real-Time Subscriptions
'use client';
export function Messages() {
const [messages, setMessages] = useState([]);
useEffect(() => {
const channel = supabase
.channel('messages')
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages' },
(payload) => setMessages((prev) => [...prev, payload.new])
)
.subscribe();
return () => supabase.removeChannel(channel);
}, []);
return <MessageList messages={messages} />;
}
Row Level Security
-- Users can only read their own data
CREATE POLICY "Users can read own data"
ON profiles FOR SELECT
USING (auth.uid() = user_id);
This stack provides a complete backend without managing servers!
Posted onnextjswith tags: