--- status: "published" label: "Loading data from the DB" order: 4 title: "Learn how to load data from the Supabase database" description: "In this page we learn how to load data from the Supabase database and display it in our Next.js application." --- Now that our database supports the data we need, we can start loading it into our application. We will use the `@makerkit/data-loader-supabase-nextjs` package to load data from the Supabase database. Please check the [documentation](https://github.com/makerkit/makerkit/tree/main/packages/data-loader/supabase/nextjs) for the `@makerkit/data-loader-supabase-nextjs` package to learn more about how to use it. This nifty package allows us to load data from the Supabase database and display it in our server components with support for pagination. In the snippet below, we will: 1. Load the user's workspace data from the database. This allows us to get the user's account ID without further round-trips because the workspace is loaded by the user layout. 2. Load the user's tasks from the database. 3. Display the tasks in a table. 4. Use a search input to filter the tasks by title. Let's take a look at the code: ```tsx import { use } from 'react'; import { ServerDataLoader } from '@makerkit/data-loader-supabase-nextjs'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { Button } from '@kit/ui/button'; import { Heading } from '@kit/ui/heading'; import { If } from '@kit/ui/if'; import { Input } from '@kit/ui/input'; import { PageBody } from '@kit/ui/page'; import { Trans } from '@kit/ui/trans'; import { getTranslations } from 'next-intl/server'; import { TasksTable } from './_components/tasks-table'; import { UserAccountHeader } from './_components/user-account-header'; import { loadUserWorkspace } from './_lib/server/load-user-workspace'; interface SearchParams { page?: string; query?: string; } export const generateMetadata = async () => { const t = await getTranslations('account'); const title = t('homePage'); return { title, }; }; async function UserHomePage(props: { searchParams: Promise }) { const client = getSupabaseServerClient(); const { user } = use(loadUserWorkspace()); const searchParams = await props.searchParams; const page = parseInt(searchParams.page ?? '1', 10); const query = searchParams.query ?? ''; return ( <> } description={} />
{(props) => { return (

); }}
); } export default UserHomePage; ``` Let's break this down a bit: 1. We import the necessary components and functions. 2. We define the `SearchParams` interface to type the search parameters. 3. We define the `generateMetadata` function to generate the page metadata. 4. We define the `UserHomePage` component that loads the user's workspace and tasks from the database. 5. We define the `ServerDataLoader` component that loads the tasks from the database. 6. We render the tasks in a table and provide a search input to filter the tasks by title. 7. We export the `UserHomePage` component. ### Displaying the tasks in a table Now, let's show the tasks table component: ```tsx 'use client'; import Link from 'next/link'; import { ColumnDef } from '@tanstack/react-table'; import { Pencil } from 'lucide-react'; import { useTranslations } from 'next-intl'; import { Button } from '@kit/ui/button'; import { DataTable } from '@kit/ui/enhanced-data-table'; import { Database } from '~/lib/database.types'; type Task = Database['public']['Tables']['tasks']['Row']; export function TasksTable(props: { data: Task[]; page: number; pageSize: number; pageCount: number; }) { const columns = useGetColumns(); return (
); } function useGetColumns(): ColumnDef[] { const t = useTranslations('tasks'); return [ { header: t('task'), cell: ({ row }) => ( {row.original.title} ), }, { header: t('createdAt'), accessorKey: 'created_at', }, { header: t('updatedAt'), accessorKey: 'updated_at', }, { header: '', id: 'actions', cell: ({ row }) => { const id = row.original.id; return (
); }, }, ]; } ``` In this snippet, we define the `TasksTable` component that renders the tasks in a table. We use the `DataTable` component from the `@kit/ui/enhanced-data-table` package to render the table. We also define the `useGetColumns` hook that returns the columns for the table. We use the `useTranslations` hook from `next-intl` to translate the column headers.