Next.js Lesson 4: Layouts & Loading States

▲ Next.js CourseLesson 4 of 12 · 33% complete

Layouts wrap pages and persist across navigation — the navbar and footer render once. Loading states show skeleton UIs while data loads.

Root Layout

// app/layout.tsx — wraps EVERY page
import type { Metadata } from "next";
import { Inter } from "next/font/google";

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

export const metadata: Metadata = {
  title: { template: "%s | My Site", default: "My Site" },
  description: "A Next.js website"
};

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

Nested Layouts

// app/dashboard/layout.tsx — only wraps /dashboard/* routes
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className="dashboard">
      <Sidebar />
      <div className="content">{children}</div>
    </div>
  );
}

// app/dashboard/page.tsx → uses BOTH RootLayout AND DashboardLayout

Loading UI

// app/blog/loading.tsx — shows while blog page loads
export default function BlogLoading() {
  return (
    <div className="skeleton-container">
      {[1,2,3].map(i => (
        <div key={i} className="skeleton-card">
          <div className="skeleton-title" />
          <div className="skeleton-text" />
        </div>
      ))}
    </div>
  );
}

// app/blog/error.tsx — shows on error
"use client";
export default function BlogError({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <div>
      <h2>Something went wrong: {error.message}</h2>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

🏋️ Practice Task

Create a dashboard section at /dashboard. Add a dashboard layout with a sidebar (links to /dashboard, /dashboard/profile, /dashboard/settings). Create loading.tsx for the dashboard that shows 3 skeleton cards. Create error.tsx with a retry button.

💡 Hint: Sidebar: Overview. DashboardLayout must be at app/dashboard/layout.tsx.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *