Building a backend without the hassle: how Supabase makes developers’ lives easier

calendar icon
14 Feb
scroll

Starting a new web application is always an exciting experience. But before writing a single line of code, the question of how to set up the backend inevitably arises. Servers, databases, and authentication are things that take time and often slow down development, but they can all be managed with a single tool — Supabase.

Supabase is a platform that provides everything needed for backend development. It offers a PostgreSQL database, authentication, file storage, and server-side functions — all gathered in one place and set up for immediate use. There’s no need to stare at the screen for hours configuring infrastructure, and in this article, we’ll explain how to do it efficiently with the help of Supabase.

Why is Supabase the solution you need?

When first getting into web development, backend setup might seem complicated and time-consuming. It often looks like something that requires deep expertise and complex queries just to manage users and data. But Supabase completely changes that perspective. Instead of spending days on manual configurations and server setups, developers can start implementing application logic right away. 

That’s possible because this platform provides fully equipped tools out of the box, streamlining the entire process. On top of that, Supabase offers a comprehensive set of documentation that’s freely available to all users. And in the following sections, we’ll focus specifically on how to use Supabase with Next.js, covering key aspects to help you get the most out of both platforms.

Supabase for the backend and Next.js for the frontend work together to create full-stack applications with ease.

Steps to create a project with Supabase and Next.js

Building a fully functional web application efficiently starts with establishing a solid backend. And the first step in this process is to create a project in Supabase, which takes just a few minutes. To do this, follow these instructions:

  1. Go to the Supabase Dashboard and sign up or log in to your account.
  2. Click the “New Project” button, enter a project name, and select a region. Supabase will automatically set up a PostgreSQL database for your project.
  3. Once created, navigate to Project Settings → API to find your Project URL and Project API Anon Key. These credentials will be needed to connect your application to Supabase.

With the Supabase project ready, the next task is to prepare a Next.js application. Rather than building everything from scratch, you can use a pre-configured Supabase template that makes the process much easier. This template includes:

  • A pre-configured Supabase client for working with the database, authentication, and storage.
  • A sample login page for handling user authentication.
  • A basic Supabase configuration file tailored for Next.js.

To create a new Next.js project with Supabase, run the command below:

npx create-next-app -e with-supabase my-supabase-project

This step generates a Next.js project with Supabase pre-integrated, allowing you to start development immediately. All that’s left is to add your Supabase credentials. Open the .env file in the project directory and insert the following values:

NEXT_PUBLIC_SUPABASE_URL=<Project URL>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<Project API Anon Key>

At this point, the project is fully set up and ready for development. With Supabase handling the backend and Next.js powering the frontend, you can start building features without worrying about infrastructure deployment. 

A great development experience starts with the right tools.

Supabase features that simplify backend development

Now that the setup is complete, we can put the backend to work. Handling users, managing data, and storing files are essential parts of any modern project, and doing it with Supabase can make all the difference. Let’s explore how its features help streamline development and keep the focus on building great products.

User authentication

In many applications, user authentication is one of the first features to implement, especially when dealing with sensitive data. To make this clearer, let’s say we’re building a task management app. The process of managing users, including sign-ups, logins, and password resets, can be complex — but with Supabase, this functionality is already built and ready to use. 

Supabase’s authentication features are integrated into the Next.js template, meaning no extra configuration is required.

The template comes with several key features already set up:

  • Registration (signUpAction): Handles new user registrations, creates accounts in Supabase, and sends confirmation emails to activate the account.
  • Login (signInAction): Authenticates the user with their email and password, allowing them to securely access the app.
  • Password Recovery (forgotPasswordAction): Sends a link to reset the password to the user’s provided email address.
  • Password Reset (resetPasswordAction): Updates the user’s password after verifying the input values.
  • Sign Out (signOutAction): Logs the user out of the system, securely ending their session.
  • Get Current User (getCurrentUser): Checks if the user is logged in and redirects them to the login page if needed.

Additionally, the necessary middlewares are in place to manage and store the session. All of these actions are handled securely through Supabase’s authentication methods and powered by server-side Next.js functions, guaranteeing both security and ease of use.

Working with the database

Once the user is authenticated, the next thing to do is provide access to their data. For this, we need to create a todos table in Supabase, where each task will have properties like id, title, is_completed, created_at, and user_id. To restrict users to seeing only their own tasks, we can implement Row Level Security (RLS), which controls data access at the individual row level.

This feature allows us to define which users or groups can view or modify certain rows within a table. Unlike traditional security rules that apply to the entire table, RLS ensures that each user only interacts with their relevant data. For instance, in our tasks table, we can confirm that even if multiple users are accessing the same table, they will be limited to their personal tasks.

As we know the steps, let’s take a look at the actual SQL code to create the table and set up RLS. Here’s how you can do it:

  1. In the left sidebar, select SQL Editor.
  2. Paste the following SQL code into the editor:
-- Створення таблиці todos
CREATE TABLE public.todos (
  id SERIAL PRIMARY KEY,
  title TEXT NOT NULL,
  is_completed BOOLEAN DEFAULT FALSE,
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE
  created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP

);

-- Ввімкнення Row Level Security (RLS)
ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY;

-- Створення політики безпеки для перегляду задач
CREATE POLICY "Users can view their todos" ON public.todos
FOR SELECT USING (auth.uid() = user_id);
  1. Click Run to execute the SQL query and create the table with RLS enabled.

Now, we have a todos table where each user can only view and interact with their own tasks. Thanks to RLS, if a user queries the table, they will only retrieve tasks associated with their user ID. This provides secure and isolated access to user data, maintaining privacy. 

With the todos table set up and RLS in place, we can write a function to fetch all tasks securely for the logged-in user. The function uses Supabase’s server-side client to query the database securely:

export type TTodo = {
 id: string;
 title: string;
 is_completed: boolean;
 created_at: string;
 user_id: string;
}

export const getAllTodos = async () => {
 const supabase = await createClient();
 const { data, error } = await supabase.from('todos').select();

 if (error) {
   console.error(error.message);
   return [];
 }

 return data as TTodo[];
}
Even though the query fetches all tasks, the user will only see their own tasks.

Creating the server client

The createClient function is key here as it facilitates secure interaction with the database and authentication services. The code looks like the following:

import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";

export const createClient = async () => {
 const cookieStore = await 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 (error) {
           console.log(error);
           throw new Error("Failed to set cookies");
         }
       },
     },
   },
 );
};

This function sets up Supabase’s server client using createServerClient from the @supabase/ssr library, which is essential for making secure requests on the server side. Additionally, it handles cookies, which ensures the user remains authenticated across multiple requests. These cookies are managed using two methods, each with its specific function:

  • getAll — retrieves all cookies for the current session using the cookieStore.getAll() method. This allows the Supabase client to access cookies that have been sent along with the request, enabling smooth session management.
  • setAll — sets new cookies by calling the cookieStore.set(name, value, options) method. This allows setting the name, value, and optional parameters for each cookie, supporting proper session persistence across requests.

As shown, even though the getAllTodos function fetches all tasks, the logged-in user only sees their own tasks due to the security policies we’ve defined. This means no additional code is needed to filter out tasks from other users, and the entire process is handled securely and efficiently.

By following a similar approach, you can also easily create functions to add, update, or delete tasks, letting the user interact only with their own data.

File storage

Supabase also makes it easy to upload and store files, which is crucial for many applications. For instance, imagine a task management app where users can add images related to their tasks. Supabase provides a straightforward way to manage file storage through its Storage feature, handling file uploads, storage, and access all in one place.

Here’s an example of a function that allows users to upload files:

export const uploadFile = async (file: File | null) => {
  if (!file) return;

 const supabase = await createClient();
 const { data, error } = await supabase.storage
   .from('images')
   .upload(`public/${file.name}`, file);

 if (error) console.error('Error uploading file:', error);
 else console.log('Failed to upload file:', data);
};

With this function, users can upload files to a designated storage bucket in Supabase. Once the file is transferred, the platform secures it, making it available for access whenever needed. In this case, files are saved to the images bucket under the public/ directory, making them publicly accessible.

It’s all in your hands now

Well, we hope this article has been both helpful and practical for you. From everything we’ve covered, it’s clear that Supabase is an excellent tool for developers looking to build powerful backends. We’ve seen how its built-in features like authentication, database management, and file storage can save you a lot of time. Now that you have a good understanding of what it offers, it’s time to bring Supabase into your projects and build faster, smarter, and with fewer headaches. To help you get started, we’ve created a Next.js project with Supabase — explore it in our GitHub repository.

Writing team:
Iryna
Technical writer
Olena
Copywriter
Have a project
in your mind?
Let’s communicate.
Get expert estimation
Get expert estimation
expert postexpert photo

Frequently Asked Questions

copy iconcopy icon
Ready to discuss
your project with us?
Let’s talk about how we can craft a user experience that not only looks great but drives real growth for your product.
Book a call
Book a call
4.9 AVG. SCORE
Based on 80+ reviews
TOP RATED COMPANY
with 100% Job Success
FEATURED Web Design
AgencY IN UAE
TOP DESIGN AGENCY
WORLDWIDE