Paths Configuration in the Next.js Supabase SaaS Kit

Configure route paths for authentication, personal accounts, and team accounts in the Next.js Supabase SaaS Kit. Centralized path management for consistent navigation.

The paths configuration at apps/web/config/paths.config.ts centralizes all route definitions. Instead of scattering magic strings throughout your codebase, reference paths from this single configuration file.

Default Paths

Authentication Paths

Path KeyDefault ValueDescription
auth.signIn/auth/sign-inSign in page
auth.signUp/auth/sign-upSign up page
auth.verifyMfa/auth/verifyMFA verification
auth.callback/auth/callbackOAuth callback handler
auth.passwordReset/auth/password-resetPassword reset request
auth.passwordUpdate/update-passwordPassword update completion

Personal Account Paths

Path KeyDefault ValueDescription
app.home/homePersonal dashboard
app.personalAccountSettings/home/settingsProfile settings
app.personalAccountBilling/home/billingBilling management
app.personalAccountBillingReturn/home/billing/returnBilling portal return

Team Account Paths

Path KeyDefault ValueDescription
app.accountHome/home/[account]Team dashboard
app.accountSettings/home/[account]/settingsTeam settings
app.accountBilling/home/[account]/billingTeam billing
app.accountMembers/home/[account]/membersTeam members
app.accountBillingReturn/home/[account]/billing/returnTeam billing return
app.joinTeam/joinTeam invitation acceptance

Configuration File

import { z } from 'zod';
const PathsSchema = z.object({
auth: z.object({
signIn: z.string().min(1),
signUp: z.string().min(1),
verifyMfa: z.string().min(1),
callback: z.string().min(1),
passwordReset: z.string().min(1),
passwordUpdate: z.string().min(1),
}),
app: z.object({
home: z.string().min(1),
personalAccountSettings: z.string().min(1),
personalAccountBilling: z.string().min(1),
personalAccountBillingReturn: z.string().min(1),
accountHome: z.string().min(1),
accountSettings: z.string().min(1),
accountBilling: z.string().min(1),
accountMembers: z.string().min(1),
accountBillingReturn: z.string().min(1),
joinTeam: z.string().min(1),
}),
});
const pathsConfig = PathsSchema.parse({
auth: {
signIn: '/auth/sign-in',
signUp: '/auth/sign-up',
verifyMfa: '/auth/verify',
callback: '/auth/callback',
passwordReset: '/auth/password-reset',
passwordUpdate: '/update-password',
},
app: {
home: '/home',
personalAccountSettings: '/home/settings',
personalAccountBilling: '/home/billing',
personalAccountBillingReturn: '/home/billing/return',
accountHome: '/home/[account]',
accountSettings: `/home/[account]/settings`,
accountBilling: `/home/[account]/billing`,
accountMembers: `/home/[account]/members`,
accountBillingReturn: `/home/[account]/billing/return`,
joinTeam: '/join',
},
});
export default pathsConfig;

Using Paths in Code

In Server Components and Actions

import pathsConfig from '~/config/paths.config';
import { redirect } from 'next/navigation';
// Redirect to sign in
redirect(pathsConfig.auth.signIn);
// Redirect to team dashboard
const teamSlug = 'acme-corp';
redirect(pathsConfig.app.accountHome.replace('[account]', teamSlug));

In Client Components

import pathsConfig from '~/config/paths.config';
import Link from 'next/link';
function Navigation() {
return (
<nav>
<Link href={pathsConfig.app.home}>Dashboard</Link>
<Link href={pathsConfig.app.personalAccountSettings}>Settings</Link>
</nav>
);
}

Dynamic Team Paths

Team account paths contain [account] as a placeholder. Replace it with the actual team slug:

import pathsConfig from '~/config/paths.config';
function getTeamPaths(teamSlug: string) {
return {
dashboard: pathsConfig.app.accountHome.replace('[account]', teamSlug),
settings: pathsConfig.app.accountSettings.replace('[account]', teamSlug),
billing: pathsConfig.app.accountBilling.replace('[account]', teamSlug),
members: pathsConfig.app.accountMembers.replace('[account]', teamSlug),
};
}
// Usage
const paths = getTeamPaths('acme-corp');
// paths.dashboard = '/home/acme-corp'
// paths.settings = '/home/acme-corp/settings'

Adding Custom Paths

Extend the schema when adding new routes to your application:

const PathsSchema = z.object({
auth: z.object({
// ... existing auth paths
}),
app: z.object({
// ... existing app paths
// Add your custom paths
projects: z.string().min(1),
projectDetail: z.string().min(1),
}),
});
const pathsConfig = PathsSchema.parse({
auth: {
// ... existing values
},
app: {
// ... existing values
projects: '/home/[account]/projects',
projectDetail: '/home/[account]/projects/[projectId]',
},
});

Then use the new paths:

const projectsPath = pathsConfig.app.projects
.replace('[account]', teamSlug);
const projectDetailPath = pathsConfig.app.projectDetail
.replace('[account]', teamSlug)
.replace('[projectId]', projectId);

Path Conventions

Follow these conventions when adding paths:

  1. Use lowercase with hyphens: /home/my-projects not /home/myProjects
  2. Use brackets for dynamic segments: [account], [projectId]
  3. Keep paths shallow: Avoid deeply nested routes when possible
  4. Group related paths: Put team-related paths under app.account*

Common Pitfalls

  1. Forgetting to replace dynamic segments: Always replace [account] with the actual slug before using team paths in redirects or links.
  2. Hardcoding paths: Don't use string literals like '/home/settings'. Always import from pathsConfig for consistency.
  3. Missing trailing slash consistency: The kit doesn't use trailing slashes. Keep this consistent in your custom paths.