Private page

Create protected pages that require authentication. This tutorial shows you how to create private pages in Next.js.

Protect a page with middleware

Use Next.js middleware to protect routes:

middleware.ts
1import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs';
2import { NextResponse } from 'next/server';
3import type { NextRequest } from 'next/server';
4
5export async function middleware(req: NextRequest) {
6  const res = NextResponse.next();
7  const supabase = createMiddlewareClient({ req, res });
8
9  const {
10    data: { session },
11  } = await supabase.auth.getSession();
12
13  // Protect dashboard routes
14  if (!session && req.nextUrl.pathname.startsWith('/dashboard')) {
15    return NextResponse.redirect(new URL('/login', req.url));
16  }
17
18  return res;
19}
20
21export const config = {
22  matcher: ['/dashboard/:path*'],
23};

Protect a page with server component

app/dashboard/page.tsx
1import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
2import { cookies } from 'next/headers';
3import { redirect } from 'next/navigation';
4
5export default async function DashboardPage() {
6  const supabase = createServerComponentClient({ cookies });
7  const {
8    data: { session },
9  } = await supabase.auth.getSession();
10
11  if (!session) {
12    redirect('/login');
13  }
14
15  return (
16    <div>
17      <h1>Welcome to your dashboard, {session.user.email}!</h1>
18    </div>
19  );
20}

Protect API routes

app/api/protected/route.ts
1import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
2import { cookies } from 'next/headers';
3import { NextRequest, NextResponse } from 'next/server';
4
5export async function GET(request: NextRequest) {
6  const supabase = createRouteHandlerClient({ cookies });
7  const {
8    data: { session },
9  } = await supabase.auth.getSession();
10
11  if (!session) {
12    return NextResponse.json(
13      { error: 'Unauthorized' },
14      { status: 401 }
15    );
16  }
17
18  // Your protected API logic here
19  return NextResponse.json({ data: 'Protected data' });
20}