If you are looking for a super easy way to connect your Next.js project with a database, Supabase is one of the best choices.
In this guide, I’ll show you step-by-step how you can set up Supabase, create a table, and fetch the data easily in your Next.js app.
Step 1: Set up a Supabase Project
-
Go to Supabase Dashboard and create a new project.
-
Once your project is created, go to the Table Editor and create a new table.
-
Add some sample rows to the table.
Example: If your table name isnotes, you can add columns liketitleanddescription. -
Important:
Set the Auth Policy for the table:-
Go to Authentication > Policies.
-
Create a policy that “Enables read access for all users”.
-
Without this, you won’t be able to fetch data publicly.
-
Step 2: Set up Supabase in Next.js Project
First, install the Supabase client library:
npm install --save @supabase/supabase-js
npm install @supabase/ssr
1. utils/supabase/client.ts
import { createBrowserClient } from "@supabase/ssr";
export const createClient = () =>
createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);
2. utils/supabase/middleware.ts
import { createServerClient } from "@supabase/ssr";
import { NextRequest, NextResponse } from "next/server";
export const createClient = (request: NextRequest) => {
let supabaseResponse = NextResponse.next({ request: { headers: request.headers } });
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value));
supabaseResponse = NextResponse.next({ request });
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
);
},
},
}
);
return supabaseResponse;
};
3. utils/supabase/server.ts
import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
export const createClient = (cookieStore: ReturnType<typeof cookies>) => {
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options));
} catch {
// Safe to ignore if called from a Server Component
}
},
},
}
);
};
Fetch Data in Your Next.js Page | Server side
Now, in your page file (example: app/page.tsx), you can fetch data like this:
import { createClient } from '@/utils/supabase/server';
import { cookies } from 'next/headers';
export default async function Page() {
const cookieStore = cookies();
const supabase = createClient(cookieStore);
const { data: notes, error } = await supabase.from('notes').select('*');
return (
<div className='container mx-auto p-4'>
{notes?.map((item, index) => (
<div key={index} className='bg-white p-4 rounded-md shadow-md mb-1.5'>
<h2 className='text-2xl font-bold'>{item.title}</h2>
<p className='text-gray-500'>{item.description}</p>
</div>
))}
</div>
);
}
For client side we can use like this
"use client";
import { useState, useEffect } from "react";
import { createClient } from "@/utils//supabase/client";
const supabase = createClient();
export default function Page() {
const [notes, setNotes] = useState([]);
useEffect(() => {
async function fetchNotes() {
const { data, error } = await supabase.from("notes").select("*");
if (error) {
console.error(error);
} else {
setNotes(data);
}
}
fetchNotes();
}, []);
return (
<div className="container mx-auto p-4">
{notes?.map((item, index) => (
<div key={index} className="bg-white p-4 rounded-md shadow-md mb-1.5">
<h2 className="text-2xl font-bold">{item.title}</h2>
<p className="text-gray-500">{item.description}</p>
</div>
))}
</div>
);
}
Final Result
When you visit your page, it will fetch all notes from your Supabase table and display them beautifully.
✅ No authentication needed (because of the public read policy).
✅ Fully server-side rendered data fetching.
✅ Easy to scale later if you want to add login, create, update, or delete features.
Conclusion
Supabase makes it extremely easy to connect a full-featured database to your Next.js app.
By following these simple steps, you can quickly create dynamic apps without worrying too much about backend complexity.