MyApp

Getting Started

IntroductionInstallationPull Updates
Architecture
Architecture OverviewProject StructureNaming ConventionsCode StyleRouting

Setup

IDEAI AgentsMCP ServersEnvironment Variables

Workflow

Git WorkflowBuild & DeployTroubleshooting

Authentication

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Payments

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Supabase

OverviewSetup & ConfigurationTroubleshooting

Database

Database SetupPrisma ORMUsage & IntegrationMigrationsTroubleshooting

Storage

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Emails

OverviewSetup and ConfigurationUsage and IntegrationTroubleshooting

SEO

OverviewConfiguration & Best PracticesCustomization & Optimization

UI

OverviewSetup and ConfigurationThemingTroubleshooting
MyApp
Architecture

Routing

Next.js App Router structure and navigation

Next.js 16 App Router uses file-based routing with powerful features like layouts, loading states, and Cache Components mode.

File-Based Routing

page.tsx
layout.tsx

URL Mapping:

  • app/page.tsx → /
  • app/blog/page.tsx → /blog
  • app/blog/[slug]/page.tsx → /blog/my-post

Special Files

FilePurpose
page.tsxRoute UI
layout.tsxShared wrapper
loading.tsxLoading state
error.tsxError boundary
not-found.tsx404 page
route.tsAPI endpoint

Route Groups

Use (name) to organize without affecting URLs.

Route groups structure
app/
├── (auth)/
│   ├── sign-in/page.tsx      → /sign-in
│   └── layout.tsx            (auth layout)
├── (base)/
│   ├── blog/page.tsx         → /blog
│   └── layout.tsx            (main layout)
└── layout.tsx                (root layout)

Route groups like (auth) don't appear in URLs. They're for organization and applying different layouts.

Layouts

Layouts wrap pages and persist across navigation.

app/layout.tsx
// app/layout.tsx (required)
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

// app/(base)/layout.tsx (nested)
export default function BaseLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <Navigation />
      <main>{children}</main>
      <Footer />
    </>
  );
}

Dynamic Routes

Single Segment

app/blog/[slug]/page.tsx
// app/blog/[slug]/page.tsx
export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await getPostBySlug(params.slug);
  return <article>{post.title}</article>;
}

// Generate static pages
export async function generateStaticParams() {
  const posts = await getAllPosts();
  return posts.map((post) => ({ slug: post.slug }));
}

Catch-All

app/docs/[...slug]/page.tsx
// app/docs/[...slug]/page.tsx
export default async function DocsPage({ params }: { params: { slug: string[] } }) {
  const page = await getDocPage(params.slug);
  return <article>{page.content}</article>;
}

Examples:

  • /docs/getting-started → slug = ["getting-started"]
  • /docs/core/installation → slug = ["core", "installation"]

Optional Catch-All

app/shop/[[...categories]]/page.tsx
// app/shop/[[...categories]]/page.tsx
export default function ShopPage({ params }: { params: { categories?: string[] } }) {
  const categories = params.categories || [];
  return <ProductList categories={categories} />;
}

Loading States

app/dashboard/loading.tsx
// app/dashboard/loading.tsx
export default function Loading() {
  return <div className="animate-spin">Loading...</div>;
}

Automatically wrapped in Suspense. Shows while page.tsx loads.

Error Boundaries

app/dashboard/error.tsx
// app/dashboard/error.tsx
'use client';

export default function Error({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <p>{error.message}</p>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

Navigation

Link Component

Link component usage
import Link from 'next/link';

<Link href="/blog">Blog</Link>
<Link href="/docs" prefetch={false}>Docs</Link>

useRouter Hook

useRouter hook
'use client';
import { useRouter } from 'next/navigation';

export function LoginForm() {
  const router = useRouter();
  
  const handleSubmit = async () => {
    await login();
    router.push('/dashboard');
  };
}

redirect Function

redirect function
import { redirect } from 'next/navigation';

export default async function ProfilePage() {
  const user = await getCurrentUser();
  if (!user) redirect('/sign-in');
  return <Profile user={user} />;
}

API Routes

app/api/users/route.ts
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest) {
  const users = await prisma.user.findMany();
  return NextResponse.json(users);
}

export async function POST(req: NextRequest) {
  const body = await req.json();
  const user = await prisma.user.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}

Dynamic API Routes

app/api/users/[id]/route.ts
// app/api/users/[id]/route.ts
export async function GET(
  req: NextRequest,
  { params }: { params: { id: string } }
) {
  const user = await prisma.user.findUnique({ where: { id: params.id } });
  if (!user) {
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  }
  return NextResponse.json(user);
}

Middleware

middleware.ts
// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isPublicRoute = createRouteMatcher(['/', '/sign-in(.*)', '/blog(.*)']);

export default clerkMiddleware(async (auth, req) => {
  if (!isPublicRoute(req)) {
    await auth.protect();
  }
});

Quick Reference

Dynamic Routes: [slug] (single), [...slug] (catch-all), [[...slug]] (optional)
Route Groups: (name) - organize without affecting URLs
Navigation: <Link> (client), router.push() (programmatic), redirect() (server)
Special Files: page.tsx, layout.tsx, loading.tsx, error.tsx, route.ts

How is this guide ?

Last updated on

Code Style

TypeScript patterns and component structure

IDE

VS Code configuration and recommended extensions

On this page

File-Based Routing
Special Files
Route Groups
Layouts
Dynamic Routes
Single Segment
Catch-All
Optional Catch-All
Loading States
Error Boundaries
Navigation
Link Component
useRouter Hook
redirect Function
API Routes
Dynamic API Routes
Middleware
Quick Reference