Routing

Next.js 15 uses the App Router with file-based routing and React Server Components.

Route Structure

layout.tsx

Route Groups

Parentheses (main) create route groups without affecting URL structure:

Dynamic Routes

Single Dynamic Segment

Access params:

export default function Page({
  params,
}: {
  params: { id: string };
}) {
  return <div>User ID: {params.id}</div>;
}

Catch-all Segments

Access params:

export default function Page({
  params,
}: {
  params: { slug: string[] };
}) {
  return <div>Slug: {params.slug.join('/')}</div>;
}

Layouts

Layouts wrap pages and persist across route changes:

app/(main)/layout.tsx
import { Navbar } from '@/components/core/navbar';

export default function MainLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <Navbar />
      <main>{children}</main>
    </>
  );
}

Loading States

Create loading.tsx for automatic loading UI:

app/dashboard/loading.tsx
import { Skeleton } from '@shared/ui';

export default function Loading() {
  return <Skeleton variant="rectangular" height={400} />;
}

Error Handling

Create error.tsx for error boundaries:

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

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={reset}>Try again</button>
    </div>
  );
}
import Link from 'next/link';

<Link href="/dashboard">Dashboard</Link>

Programmatic Navigation

'use client';

import { useRouter } from 'next/navigation';

export function MyComponent() {
  const router = useRouter();

  const handleClick = () => {
    router.push('/dashboard');
  };

  return <button onClick={handleClick}>Go to Dashboard</button>;
}

Next: Learn about Styling with Emotion and Material-UI.