NelsonLabs
Next.js Complete Guide/Pages & Routing

Pages & Routing

In Next.js, your website's URL structure is determined entirely by how you organise files inside the app/ folder. This is called file-based routing — and it's one of Next.js's most powerful features because there's zero configuration required.

How files map to URLs

File location → URL
text
app/page.jsx               →  /                  (homepage)
app/about/page.jsx         →  /about
app/courses/page.jsx       →  /courses
app/blog/page.jsx          →  /blog
app/blog/post/page.jsx     →  /blog/post

ANALOGY

Real-world analogy: A building's address. Think of your app/ folder like a building. The building's address is your domain (e.g. nelsonlabs.com). Each floor is a folder. Each room is a page. If you want a room at /courses/nextjs, you create the folder app/courses/nextjs/ and put a page.jsx file inside it. The folder structure is the address.

Creating a page

app/about/page.jsx — accessible at /about
jsx
// Every page file exports a default function (the component to render)
export default function AboutPage() {
  return (
    <main>
      <h1>About NelsonLabs</h1>
      <p>Free courses. Real examples. Zero fluff.</p>
    </main>
  );
}

// Add metadata (controls <title> and <meta description> in the browser tab)
export const metadata = {
  title: "About — NelsonLabs",
  description: "Learn about the NelsonLabs platform.",
};

Dynamic routes — URL parameters

Sometimes your URL has a variable part — like /courses/nextjs or /blog/my-post. The part that changes is called a dynamic segment. In Next.js, you create these by wrapping a folder name in square brackets.

Square brackets = dynamic segment
text
app/courses/[slug]/page.jsx   →  /courses/nextjs
                                  →  /courses/react
                                  →  /courses/html-basics
                                  (same file handles all of these!)

app/blog/[id]/page.jsx        →  /blog/1,  /blog/42,  /blog/999
app/courses/[slug]/page.jsx — handles any course
jsx
// The "params" object contains whatever was in the URL
export default async function CoursePage({ params }) {
  const { slug } = await params;
  // If URL is /courses/nextjs  → slug = "nextjs"
  // If URL is /courses/react   → slug = "react"

  return (
    <div>
      <h1>Course: {slug}</h1>
    </div>
  );
}

Navigating between pages

Use <Link> for internal navigation — never plain <a>
jsx
import Link from "next/link";

export default function Navbar() {
  return (
    <nav>
      {/* Link prefetches the destination page in the background */}
      {/* This makes navigation feel instant */}
      <Link href="/">Home</Link>
      <Link href="/courses">Courses</Link>
      <Link href="/courses/nextjs">Next.js Guide</Link>

      {/* Use a regular <a> tag ONLY for external websites */}
      <a href="https://github.com" target="_blank">GitHub</a>
    </nav>
  );
}

Redirect programmatically (after form submit, after login, etc.)

Navigating with code — not a link click
jsx
"use client";
import { useRouter } from "next/navigation";

export default function LoginButton() {
  const router = useRouter();

  function handleLogin() {
    // ... login logic here ...
    router.push("/dashboard");    // Navigate to /dashboard
    router.replace("/dashboard"); // Navigate without adding to browser history
    router.back();                // Go back (same as browser back button)
  }

  return <button onClick={handleLogin}>Log In</button>;
}

The Layout system

A layout wraps all pages inside it and persists across navigation. This is perfect for your navbar, footer, and sidebar — you define them once in layout.jsx and they automatically appear on every page.

app/layout.jsx — the root layout
jsx
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <header>
          <nav>My Navbar</nav>
        </header>

        <main>
          {children}   {/* ← This is where each page renders */}
        </main>

        <footer>© 2025 NelsonLabs</footer>
      </body>
    </html>
  );
}