Layouts
ใน Next.js App Router คุณสร้าง layout.tsx ไว้ข้างๆ หน้าและ React จะครอบ children ด้วย layout นั้นโดยอัตโนมัติ ใน Astro ไม่มีการครอบ layout อัตโนมัติ — คุณสร้าง layout component ใน src/layouts/ และ import ใช้อย่างชัดเจน ภายในแต่ละหน้า layout รับเนื้อหาของหน้าผ่าน <slot /> ซึ่งเทียบเท่ากับ children prop ของ React
Layout ต้องการ project หลายไฟล์เพื่อสังเกตผล — รัน example เหล่านี้ใน Astro project เต็มรูปแบบ (
npm create astro@latest) ในเครื่องของคุณ
การกำหนด layout
หัวข้อที่มีชื่อว่า “การกำหนด layout”// app/layout.tsx (Next.js App Router)export default function RootLayout({ children,}: { children: React.ReactNode;}) { return ( <html lang="en"> <head> <title>My Site</title> </head> <body> <nav>My Nav</nav> <main>{children}</main> <footer>My Footer</footer> </body> </html> );}---// src/layouts/Layout.astrointerface Props { title?: string;}const { title = 'My Site' } = Astro.props;---<html lang="en"> <head> <meta charset="utf-8" /> <title>{title}</title> </head> <body> <nav>My Nav</nav> <main> <slot /> <!-- เนื้อหาของหน้าจะแสดงที่นี่ --> </main> <footer>My Footer</footer> </body></html>การใช้ layout ในหน้า
หัวข้อที่มีชื่อว่า “การใช้ layout ในหน้า”// app/about/page.tsx (Next.js App Router)// layout.tsx ครอบโดยอัตโนมัติ — ไม่ต้อง importexport default function AboutPage() { return <h1>About</h1>;}
// -----------------------------------------// pages/_app.tsx (Next.js Pages Router)// import type { AppProps } from 'next/app';// export default function App({ Component, pageProps }: AppProps) {// return <Layout><Component {...pageProps} /></Layout>;// }---// src/pages/about.astro// Layout ต้อง import อย่างชัดเจนในทุกหน้าimport Layout from '../layouts/Layout.astro';---<Layout title="About"> <h1>About</h1> <p>Welcome to the about page.</p></Layout>Named slots
หัวข้อที่มีชื่อว่า “Named slots”Astro รองรับ named slot สำหรับการฉีดเนื้อหาเข้าไปยังพื้นที่เฉพาะของ layout — คล้ายกับ named children pattern ใน React (ใช้ render prop หรือ portal) แต่ built into ภาษา
// React named-area pattern (render props)function Layout({ nav, main }: { nav: React.ReactNode; main: React.ReactNode;}) { return ( <div> <aside>{nav}</aside> <main>{main}</main> </div> );}
// Usage<Layout nav={<NavLinks />} main={<ArticleContent />}/>---// src/layouts/TwoColumn.astro---<div> <aside> <slot name="sidebar" /> <!-- named slot --> </aside> <main> <slot /> <!-- default slot --> </main></div>
<!-- การใช้ในหน้า -->---import TwoColumn from '../layouts/TwoColumn.astro';---<TwoColumn> <nav slot="sidebar"> <a href="/a">Link A</a> </nav> <article>เนื้อหาหลักที่นี่</article></TwoColumn>File tree ของ project
หัวข้อที่มีชื่อว่า “File tree ของ project”flowchart TD src["src/"] --> layouts["layouts/"] src --> pages["pages/"] layouts --> layout["Layout.astro (base HTML shell: head, nav, footer)"] layouts --> blogLayout["BlogLayout.astro (extends Layout, adds sidebar)"] pages --> index["index.astro imports Layout from '../layouts/Layout.astro'"] pages --> about["about.astro imports Layout from '../layouts/Layout.astro'"] pages --> blog["blog/"] blog --> slug["[slug].astro imports BlogLayout from '../../layouts/BlogLayout.astro'"]