Shared Layouts và Dynamic Metadata

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 11 tháng 4, 2025

Trong App Router của Next.js 13+, hệ thống layout trở nên cực kỳ mạnh mẽ với khả năng reuse nhiều cấp, tách biệt UI thành từng phần như Header, Sidebar, Footer theo route.

Bên cạnh đó, Next.js còn hỗ trợ metadata động để cải thiện SEO cho từng trang, sử dụng hàm generateMetadata.

  • Tạo layout nhiều cấp cho các nhóm trang (dashboard, auth, blog…)
  • Hiểu tư duy slot layout tương tự <Outlet /> trong React Router
  • Tạo tiêu đề, mô tả động theo từng route
  • Áp dụng metadata để cải thiện hiển thị khi chia sẻ trên mạng xã hội

Shared Layouts và Dynamic Metadata

1. Tạo layout dùng chung nhiều cấp

Cấu trúc mẫu:

app/
├── layout.tsx                  // Layout chung toàn bộ app
├── page.tsx
├── (dashboard)/
│   ├── layout.tsx             // Layout riêng cho dashboard
│   ├── page.tsx
│   └── analytics/
│       └── page.tsx
└── (auth)/
    ├── layout.tsx             // Layout riêng cho login/register
    └── login/
        └── page.tsx

Tên thư mục có dấu ngoặc (dashboard) chỉ là một grouping – không ảnh hưởng tới URL.

2. Dùng slot layout (children – tương tự <Outlet />)

// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Header />
        {children}
        <Footer />
      </body>
    </html>
  );
}
// app/(dashboard)/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex">
      <Sidebar />
      <main className="flex-1 p-4">{children}</main>
    </div>
  );
}

Các layout này không re-render lại khi route con thay đổi, giúp giữ nguyên layout gốc mà chỉ thay phần nội dung.

3. Tạo metadata động với generateMetadata

// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: { params: { slug: string } }) {
  const post = await fetchPostBySlug(params.slug);

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [`https://yourcdn.com/${post.image}`],
    },
  };
}
  • generateMetadata() là hàm async chạy trước render
  • Metadata được inject tự động vào <head> của HTML

4. Áp dụng SEO cơ bản

  • Metadata được dùng để cải thiện SEO và preview khi chia sẻ lên Facebook, Zalo, Twitter...
  • Với generateMetadata, bạn có thể cấu hình:
    • title, description
    • keywords, author, robots
    • openGraph, twitter, themeColor,...

Kết luận

Hệ thống layout mới của Next.js 13 giúp bạn xây dựng các phần UI có cấu trúc rõ ràng, dễ reuse và tách biệt theo tính năng. Đồng thời, metadata động giúp bạn nâng cao SEO và cải thiện hiển thị khi người dùng chia sẻ đường dẫn.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ