How to Use Supabase Database in a Simple Way with Next.js

How to Use Supabase Database in a Simple Way with Next.js

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

  1. Go to Supabase Dashboard and create a new project.

  2. Once your project is created, go to the Table Editor and create a new table.

  3. Add some sample rows to the table.
    Example: If your table name is notes, you can add columns like title and description.

  4. 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.