banner
xiaole

xiaole

前端工程师 | Trying To Do Better
tg_channel
twitter
github
email

How to use supabase in a Next.js project

What is supabase#

supabase is an open-source BaaS (Backend as a Service) project that serves as an alternative to Firebase. It provides stable, powerful, easy-to-use, and scalable backend functionality required by various modern applications. Supabase is built on PostgreSQL database and RESTful API, and it offers authentication, real-time data streaming, storage, and other common backend services.

You don't need to buy servers, just have a basic understanding of SQL statements and database knowledge to create a backend service. Of course, its functionality is very powerful, and this article only introduces how to use it in Next.js.

Using supabase#

Detailed reading of the official documentation is required for learning tasks.

According to the content in the section Use Supabase with NextJS of the official documentation, the usage steps are as follows:

Here I use supabase to store the number of views for a blog.

Creating a project and setting up tables and data#

Create a project through https://app.supabase.com/projects

new project

Create a table named "Views" in the SQL editor or the graphical interface of the Database.

database

Here, create the "Views" table using the graphical interface by clicking "New table" in the top right corner of the Database.

create table

The "slug" in the columns represents the title of the blog, and "count" represents the corresponding blog's view count.

Creating a Next.js project#

npx create-next-app@latest --typescript

image.png

Installing supabase-js#

npm install @supabase/supabase-js

Creating supabase#

Create a folder named "lib" in the root directory, and create a file named "supabase.ts" inside it.

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY as string;
export const supabase = createClient(supabaseUrl, supabaseKey);

The project_url and supabase_key can be found in the project's settings.

image.png

It is not recommended to expose the key, so it can be stored in env.local.

💡 tips: In Next.js, when using env.local, you need to add the prefix NEXT_PUBLIC, otherwise an error will occur.

CRUD#

Detailed commands can be found in the JavaScript documentation.

When opening a blog post page, you need to retrieve the view count of the current blog. You can use:

fetch(`/api/views`);

Create an index.ts file in the pages/api/views directory:

import { supabase } from '@/lib/supabase';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    let { data } = await supabase.from('Views').select('*');
    return res.status(200).json(data);
  } catch (e: any) {
    console.log(e);
    return res.status(500).json({ message: e.message });
  }
}

By writing SQL-like statements, you can retrieve all the data from the Views table.

You can also pass the slug as a parameter through a POST request to retrieve the corresponding data.

At the same time, when opening a blog post page, you also need to increment the view count of the current blog. You can use a POST request to pass the slug parameter:

fetch(`/api/views/${slug}`, {
	method: 'POST'
});

Create a file named [slug].ts in the pages/api/views directory:

import { supabase } from '@/lib/supabase';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    const slug = req.query?.slug as string;
    if (!slug) {
      return res.status(400).json({ message: 'Slug is required.' });
    }

    const { data } = await supabase
      .from('Views')
      .select('count')
      .eq('slug', slug);

    const views = !data?.length ? 0 : Number(data[0].count);

    if (req.method === 'POST') {
      if (views === 0) {
        await supabase.from('Views').insert({ count: views + 1, slug: slug });

        return res.status(200).json({
          total: views + 1
        });
      } else {
        await supabase
          .from('views')
          .update({ count: views + 1 })
          .eq('slug', slug);
        return res.status(200).json({
          total: views + 1
        });
      }
    }

    if (req.method === 'GET') {
      return res.status(200).json({ total: views });
    }
  } catch (e: any) {
    console.log(e);
    return res.status(500).json({ message: e.message });
  }
}

Use insert for creating and update for updating. This way, the view count can be stored in supabase.

Other features#

Supabase also supports bucket storage. In my project, I store the og image in supabase.

image.png

I will continue using supabase in the upcoming projects as a replacement for Firebase.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.