#nextjs #layouts #templates #structure

Day 3 — Pages, Layouts & Templates: Mastering Structure

🧭 Day 3 — Pages, Layouts & Templates: Mastering Structure

Zero to Hero — Hands-on Next.js Tutorial

Yesterday, we learned that folders = routes. Today, we learn what goes inside those folders.

Next.js gives you special files to define UI: page.tsx, layout.tsx, template.tsx, loading.tsx, error.tsx.


🟦 1. The Hierarchy

When you visit /dashboard/settings, Next.js renders component in this order (nested):

  1. app/layout.tsx (Root Layout)
  2. app/dashboard/layout.tsx (Dashboard Layout)
  3. app/dashboard/settings/page.tsx (The Page)

Visual:

[ Root Layout [ Dashboard Layout [ Settings Page ] ] ]

🟩 2. Layouts (layout.tsx)

A Layout is UI that is shared between multiple routes. On navigation, layouts preserve state, remain interactive, and do not re-render.

Example: A Dashboard Sidebar

Create src/app/dashboard/layout.tsx:

export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section className="flex">
      {/* Sidebar - Persistent! */}
      <nav className="w-64 bg-gray-100 p-4 h-screen">
        <h2>My Dashboard</h2>
      </nav>
 
      {/* Page Content - Changes on navigation */}
      <div className="flex-1 p-8">
        {children}
      </div>
    </section>
  )
}

Now, any page inside /dashboard/* will automatically have this sidebar!


🟧 3. Templates (template.tsx)

Templates are similar to layouts in that they wrap each child layout or page. Difference: Templates create a new instance for each of their children on navigation.

Use Templates when you need to:

  • Enter/Exit animations (Framer Motion).
  • Reset state (e.g., a feedback form).
  • Log page views (useEffect).
// src/app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {
  return <div className="animate-fade-in">{children}</div>
}

🟥 4. Root Layout (app/layout.tsx)

This is the top-most layout. It must contain <html> and <body> tags.

import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Next Hero App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

Every Next.js app has at least one Root Layout.


🧪 Challenge: Day 3

  1. Create a layout.tsx inside your /blog folder.
  2. Add a header inside it that says “My Tech Blog” (purple background, white text).
  3. Navigate between /blog/1 and /blog/2.
  4. Notice how the “My Tech Blog” header stays static and doesn’t flicker? That’s the power of Layouts.

See you tomorrow for Navigation & Linking! 🔗