layouts

레이아웃(Layout)

레이아웃은 재사용할 수 있는 UI 구조(예: 페이지 템플릿)를 제공하는 Astro 컴포넌트예요. 보통은 헤더·내비게이션 바·푸터처럼 여러 페이지가 공유하는 UI 요소를 묶는 컴포넌트를 '레이아웃'이라 불러요. 한 번 만들어 두면 페이지마다 같은 HTML 뼈대를 반복해서 쓰지 않아도 돼요.

출처: 공식문서

본문

일반적인 Astro 레이아웃 컴포넌트는 Astro·Markdown·MDX 페이지에 다음 두 가지를 제공해요.

  • 페이지 셸(<html>, <head>, <body> 태그)
  • 각 페이지 콘텐츠를 주입할 위치를 정하는 <slot />

레이아웃 컴포넌트는 특별한 게 아니에요. 다른 Astro 컴포넌트처럼 props를 받고 다른 컴포넌트를 import해 쓸 수 있어요. UI 프레임워크 컴포넌트나 클라이언트 스크립트도 포함할 수 있고요. 페이지 셸 전체를 갖추지 않아도 되며, 부분 UI 템플릿으로만 쓰일 수도 있어요.

다만 레이아웃 컴포넌트에 페이지 셸이 있다면, 그 컴포넌트의 <html> 요소가 다른 모든 요소의 부모여야 해요.

레이아웃 컴포넌트는 보통 프로젝트의 src/layouts 폴더에 두지만 필수는 아니에요. 프로젝트 어디든 둘 수 있고, 레이아웃 이름 앞에 _를 붙여 페이지 옆에 함께 두는 방식(colocate)도 써요.

샘플 레이아웃

---
import MySiteLayout from '../layouts/MySiteLayout.astro';
---
<MySiteLayout title="Home Page">
  <p>My page content, wrapped in a layout!</p>
</MySiteLayout>

MySiteLayout 컴포넌트는 <html>, <head>, <body> 태그와 <slot />을 갖추고 있고, 그 <slot /> 위치에 페이지 콘텐츠가 주입돼요.

Markdown 레이아웃

Astro는 src/pages/ 안에 있는 개별 .md 파일이 파일 기반 라우팅으로 쓸 때, 어떤 .astro 컴포넌트를 페이지 레이아웃으로 쓸지 지정하는 특별한 layout frontmatter 속성을 제공해요.

---
layout: ../layouts/BlogPostLayout.astro
title: "Hello, World!"
author: "Matthew Phillips"
date: "09 Aug 2022"
---
All frontmatter properties are available as props to an Astro layout component.

The `layout` property is the only special one provided by Astro.

layout 속성은 콘텐츠 콜렉션으로 콘텐츠를 조회·렌더링할 때는 특별한 속성으로 인식되지 않아요.

전형적인 Markdown 페이지 레이아웃은 다음을 포함해요.

  1. Markdown 페이지의 frontmatter와 기타 데이터에 접근하는 frontmatter prop
  2. 페이지의 Markdown 콘텐츠가 렌더링될 위치를 나타내는 기본 <slot />

Markdown 레이아웃 Props

  • file — 이 파일의 절대 경로 (예: /home/user/projects/.../file.md)
  • url — 페이지의 URL (예: /en/guides/markdown-content)
  • frontmatter — Markdown 또는 MDX 문서의 모든 frontmatter
    • frontmatter.file — 최상위 file 속성과 동일
    • frontmatter.url — 최상위 url 속성과 동일
  • headings — Markdown 또는 MDX 문서의 제목(h1 -> h6) 목록과 관련 메타데이터. 이 목록은 { depth: number; slug: string; text: string }[] 타입을 따라요.
  • rawContent() — 원본 Markdown 문서를 문자열로 반환하는 함수
  • compiledContent() — Markdown 문서를 HTML 문자열로 컴파일해 반환하는 비동기 함수

레이아웃 중첩(Nesting Layouts)

한 레이아웃을 다른 레이아웃 안에 중첩할 수도 있어요. 예를 들어 BlogPostLayout.astro가 글의 제목·날짜·작성자를 스타일링하고, 사이트 전체 BaseLayout.astro가 내비게이션·푸터·SEO 메타 태그·전역 스타일·폰트 등 나머지 페이지 템플릿을 처리하는 식이에요.

---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout url={frontmatter.url}>
  <h1>{frontmatter.title}</h1>
  <h2>Post author: {frontmatter.author}</h2>
  <slot />
</BaseLayout>

더 알아보기