• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License
  • Global Configuration
    • Environment Variables
    • Feature Flags
  • Server Actions
    • Sending CSRF Token to Actions
    • Server Actions Error Handling
  • The Makerkit SDK
    • User SDK
    • Organization SDK
    • Organization Subscription SDK
    • Data Loader SDK
  • Architecture and Folder Structure
    • Structure your Application
    • Data Model
    • Adding API Routes
    • Change Authentication strategy
    • Fetching the signed in User
    • Reading Records from Postgres
    • Creating a Record
    • Seeding Local Data
    • Introduction
    • Configuring Plans
    • Project Configuration
    • Updating the Navigation menu
    • Adding a new translation string
    • Supabase is not starting
    • Calling API Routes from the client
    • Adding Pages
    • Updating the Sidebar menu
    • Setup oAuth
    • Fetching the selected Organization
    • Resetting the local DB
    • Running the Stripe Webhook locally
    • Branding
    • Setting a Default Language
    • Supabase is not stopping
    • Dark Theme
    • Theming
    • API Routes vs Server Actions
    • Generating Database Types
    • Updating the Logo
    • Adding a new language in the Next.js Supabase SaaS Kit
    • Tables/Functions not found
    • Updating the Fonts
    • Adding Pages
    • Adding a new translation file
    • Contentlayer gets stuck
    • Guarding Pages
    • Using Lemon Squeezy instead of Stripe
    • Updating the Favicons
    • Using the Language Switcher
    • Dynamic server usage error
    • Environment variables
    • Detect current Locale
    • 403 error with API/Actions
    • Setting up Emails
This documentation is for a legacy version of Next.js and Supabase. For the latest version, please visit the Next.js and Supabase V2 documentation

Reading Records from Postgres | Next.js Supabase Kit

Learn how to read records from Supabase using Next.js Supabase application

In Makerkit, we define all the queries in their own file (depending on their feature) named queries.ts.

Assuming we have a table named tasks with the following schema:

sql
create table tasks (
id serial primary key,
name text,
organization_id integer references organizations not null,
due_date timestamp,
description text,
done boolean default false
);

We can define a query to read a single task from the table:

tsx
import type { SupabaseClient } from '@supabase/supabase-js';
import type { Database } from '~/database.types';
export function getTask(client: SupabaseClient<Database>, id: number) {
return client
.from('tasks')
.select(
`
id,
name,
organizationId: organization_id,
dueDate: due_date,
description,
done
`,
)
.eq('id', id)
.single();
}

The single modifier will return a single record from the database. If no record is found, it will throw an error. If you want to return null instead, you can use the maybeSingle modifier.

Usage

You can now use the function above anywhere in the following layers:

  1. API routes
  2. React Server Components
  3. React Client Components
  4. Server Actions

In fact, we can import the Supabase client both on the browser and on the client.

Backend

Assuming we want to read a task from a Server component, such as the Task page, we can do the following:

tsx
interface Context {
params: {
task: string;
};
}
const TaskPage = async ({ params }: Context) => {
const data = await loadTaskData(params.task);
const task = data.task;
return (
<>
<h1>{task.name}</h1>
<p>{task.description}</p>
</>
);
};
async function loadTaskData(taskId: string) {
const client = getSupabaseServerComponentClient();
const { data: task } = await getTask(client, Number(taskId));
if (!task) {
redirect('/dashboard');
}
return {
task,
};
}
export default TaskPage;

Frontend

You can also choose to read the task from the frontend. This is useful if you want to use the data in a React component.

To do so, we use the Supabase Web SDK client using the hook useSupabase and combine it with SWR to fetch the data.

This is useful because you can fetch data directly from the client, which is extremely useful in scenarios such as loading data on-demand resulting from user interactions (click a table row, opening a modal, etc.)

tsx
import useSWR from "swr";
function useFetchTask({id}: {id: number}) {
const supabase = useSupabase();
const key = ['tasks', id];
return useSWR([key], async () => {
return getTask(supabase, id);
});
}

We can then use the hook in a React component:

tsx
function TaskComponent({ id }: { id: number }) {
const { data: task, isLoading, error } = useFetchTask({ id });
if (isLoading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<>
<h1>{task.name}</h1>
<p>{task.description}</p>
</>
);
}
On this page
  1. Usage
    1. Backend
    2. Frontend