• 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

Adding pages to the application of your Makerkit Next.js Supabase project

Learn how to add new pages to the application of your Makerkit Next.js Supabase project.

To add a new page to the application site of your Next.js project, you can create a new page in the src/app/dashboard directory.

By "application", we mean the private pages of your project behind the authentication wall, such as the dashboard, the settings page, etc.

The vast majority of the "private" pages of your application will be located in the src/app/dashboard/[organization] directory. This directory contains the pages that are only accessible to authenticated users, and that are related to a specific organization.

Layout and Sidebar

Pages created within the directory src/app/dashboard/[organization] will inherit the layout of the directory and will be displayed together with the Sidebar menu.

Example - Creating a new page

For example, let's create a Tasks application located at src/app/dashboard/[organization]/tasks. We will then create a new page at src/app/dashboard/[organization]/tasks/page.tsx.

src/app/dashboard/[organization]/tasks/page.tsx
import {
RectangleStackIcon,
} from '@heroicons/react/24/outline';
import Trans from '~/core/ui/Trans';
import { withI18n } from '~/i18n/with-i18n';
import AppHeader from '~/app/dashboard/[organization]/components/AppHeader';
import AppContainer from '~/app/dashboard/[organization]/components/AppContainer';
interface TasksPageParams {
params: {
organization: string;
};
}
// we will implement this function later
async function loadTasksData({ organizationUid }: { organizationUid: string}) {
// ...
}
async function TasksPage({ params }: TasksPageParams) {
const { tasks } = await loadTasksData({
organizationUid: params.organization,
});
return (
<>
<AppHeader>
<span className={'flex space-x-2'}>
<RectangleStackIcon className="w-6" />
<span>
<Trans i18nKey={'common:tasksTabLabel'} />
</span>
</span>
</AppHeader>
<AppContainer>
{/* ... */}
</AppContainer>
</>
);
}
export default withI18n(
TasksPage
);

Let's break down what we did here:

  1. We created a new page at src/app/dashboard/[organization]/tasks/page.tsx. This page will be accessible at /dashboard/[organization]/tasks.
  2. We created a loadTasksData function that will be used to load the data of the page. This is only a mock function for now, we will implement it later.
  3. We created a TasksPage component that will be used to render the page. This component is a Next.js Server Page component, so it must be exported as default.
  4. We wrapped the TasksPage component with the withI18n HOC. This HOC will ensure translations are loaded and available in the component.

Translations

Always add the withI18n HOC to your pages to ensure translations are loaded and available in the component when using Server Components (pages or layouts).

Layout

Layout-wise, we added the following components:

  1. An AppHeader component that will be used to render the header of the page. This component is located at src/app/dashboard/[organization]/components/AppHeader.tsx.
  2. An AppContainer component that will be used to render the content of the page. This component is located at src/app/dashboard/[organization]/components/AppContainer.tsx.

You can omit these components if you don't need them.

Page Parameters

Because the TasksPage component is located at src/app/dashboard/[organization]/tasks/page.tsx, it will receive the following parameters:

tsx
interface TasksPageParams {
params: {
organization: string;
};
}

This means we can access the parameter organization in the TasksPage component:

tsx
async function TasksPage({ params }: TasksPageParams) {
const { tasks } = await loadTasksData({
organizationUid: params.organization,
});
return (
<>
{/* ... */}
</>
);
}

The organization parameter is the organization UID of the organization the user is currently viewing. You can use this parameter to fetch the data related to the organization.

Building pages outside of the organization context

If you need to build a page that is not related to a specific organization, you can create it in the src/app/dashboard directory.

On this page
  1. Building pages outside of the organization context