컨텐츠로 건너뛰기

레이아웃

레이아웃은 페이지 템플릿과 같은 재사용 가능한 UI 구조를 제공하는 데 사용되는 Astro 컴포넌트입니다.

우리는 일반적으로 머리글, 탐색 모음, 바닥글과 같이 페이지 전체에서 공유되는 공통 UI 요소를 제공하는 Astro 컴포넌트에 대해 “레이아웃”이라는 용어를 사용합니다. 일반적인 Astro 레이아웃 컴포넌트는 다음과 같은 Astro, Markdown, MDX 페이지를 제공합니다.

  • 페이지 셸(<html>, <head>, <body> 태그)
  • 개별 페이지 콘텐츠를 삽입해야 하는 위치를 지정하는 <slot />.

하지만 레이아웃 컴포넌트에는 특별한 것이 없습니다! 다른 Astro 컴포넌트처럼 props를 전달받고 다른 컴포넌트를 가져와 사용할 수 있습니다. 여기에는 UI 프레임워크 컴포넌트클라이언트 측 스크립트가 포함될 수 있습니다. 전체 페이지 셸을 제공할 필요도 없으며 대신 부분 UI 템플릿으로 사용할 수 있습니다.

그러나 레이아웃 컴포넌트에 페이지 셸이 포함되어 있는 경우 <html> 요소는 컴포넌트에 있는 다른 모든 요소의 상위 요소여야 합니다. 모든 <style> 또는 <script> 요소를 <html> 태그로 묶어야 합니다.

레이아웃 컴포넌트는 일반적으로 프로젝트의 src/layouts 디렉터리에 배치되지만 이는 필수 사항은 아닙니다. 프로젝트의 어느 곳에나 배치하도록 선택할 수 있습니다. 심지어 레이아웃 이름 앞에 _를 붙이면 레이아웃 컴포넌트와 페이지를 같은 위치에 배치할 수도 있습니다.

src/layouts/MySiteLayout.astro
---
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
const { title } = Astro.props;
---
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<BaseHead title={title}/>
</head>
<body>
<nav>
<a href="#"></a>
<a href="#">블로그</a>
<a href="#">연락처</a>
</nav>
<h1>{title}</h1>
<article>
<slot /> <!-- 콘텐츠가 여기에 삽입됩니다. -->
</article>
<Footer />
</body>
<style>
h1 {
font-size: 2rem;
}
</style>
</html>
src/pages/index.astro
---
import MySiteLayout from '../layouts/MySiteLayout.astro';
---
<MySiteLayout title="Home Page">
<p>레이아웃으로 감싼 페이지입니다!</p>
</MySiteLayout>
슬롯에 대해 자세히 알아보세요.

레이아웃에 TypeScript 사용

섹션 제목: 레이아웃에 TypeScript 사용

모든 Astro 레이아웃이 props의 타입을 제공하도록 수정되면 타입 안전 및 자동 완성 기능을 도입할 수 있습니다:

src/components/MyLayout.astro
---
interface Props {
title: string;
description: string;
publishDate: string;
viewCount: number;
}
const { title, description, publishDate, viewCount } = Astro.props;
---
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content={description}>
<title>{title}</title>
</head>
<body>
<header>
<p>Published on {publishDate}</p>
<p>Viewed by {viewCount} folks</p>
</header>
<main>
<slot />
</main>
</body>
</html>

페이지 레이아웃은 페이지 형식이 없는 개별 Markdown 페이지에 특히 유용합니다.

Astro는 특별한 layout 프런트매터 속성을 제공하는데, 이는 파일 기반 라우팅을 사용하는 src/pages/의 개별 .md 파일에서 페이지 레이아웃으로 사용할 .astro 컴포넌트를 지정하기 위한 것입니다. 이 컴포넌트를 사용하면 메타 태그(예: <meta charset="utf-8">)와 같은 <head> 콘텐츠와 Markdown 페이지를 위한 스타일을 제공할 수 있습니다. 기본적으로 이 지정된 컴포넌트는 Markdown 파일의 데이터에 자동으로 접근할 수 있습니다.

콘텐츠 컬렉션을 사용하여 콘텐츠를 쿼리하고 렌더링할 때는 이것이 특별한 속성으로 인식되지 않습니다.

src/pages/page.md
---
layout: ../layouts/BlogPostLayout.astro
title: "안녕하세요!"
author: "Matthew Phillips"
date: "09 Aug 2022"
---
모든 프런트매터 속성은 Astro 레이아웃 컴포넌트에 대한 props로 사용할 수 있습니다.
`layout` 속성은 Astro에서 제공하는 유일한 특수 속성입니다.
이는 `src/pages/` 디렉터리에 있는 Markdown 파일에서 사용할 수 있습니다.

Markdown 페이지의 일반적인 레이아웃은 다음과 같습니다.

  1. Markdown 페이지의 프런트매터 및 기타 데이터를 사용하기 위한 frontmatter prop.
  2. 페이지의 Markdown 콘텐츠가 렌더링되어야 하는 위치를 나타내는 기본 <slot />.
src/layouts/BlogPostLayout.astro
---
// 1. 프런트매터 prop을 통해 프런트매터 및 기타 데이터를 사용할 수 있습니다.
const { frontmatter } = Astro.props;
---
<html>
<head>
<!-- 여기에 스타일, 메타 태그 등 다른 Head 요소를 추가하세요. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<title>{frontmatter.title}</title>
</head>
<body>
<!-- 일반적인 머리글 및 바닥글과 같은 다른 UI 컴포넌트를 여기에 추가합니다. -->
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<!-- 2. 렌더링된 HTML은 기본 슬롯으로 전달됩니다. -->
<slot />
<p>작성: {frontmatter.date}</p>
</body>
</html>

MarkdownLayoutProps 도우미를 사용하여 레이아웃의 Props 타입을 설정할 수 있습니다.

src/layouts/BlogPostLayout.astro
---
import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{
// 여기서 프런트매터 props를 정의하세요.
title: string;
author: string;
date: string;
}>;
// 이제 'frontmatter', 'url' 및 기타 Markdown 레이아웃 속성에 타입 안전성을 적용하여 사용할 수 있습니다.
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta charset="utf-8">
<link rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title} - {frontmatter.author}</h1>
<slot />
<p>작성: {frontmatter.date}</p>
</body>
</html>

Markdown 레이아웃은 Astro.props를 통해 다음 정보를 사용할 수 있습니다.

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

수동으로 레이아웃 가져오기 (MDX)

섹션 제목: 수동으로 레이아웃 가져오기 (MDX)

또한 같은 방식으로, MDX 파일의 프런트매터에 있는 특수 Markdown layout 속성을 사용하여 frontmatterheadings props를 지정된 레이아웃 컴포넌트에 직접 전달할 수도 있습니다.

프런트매터에 존재하지 않거나 존재할 수 없는 정보를 MDX 레이아웃에 전달하려면 대신 <Layout /> 컴포넌트를 가져와 사용할 수 있습니다. 이는 다른 Astro 컴포넌트처럼 작동하며 props를 자동으로 받지 않습니다. 필요한 props는 직접 전달하세요:

src/pages/posts/first-post.mdx
---
layout: ../../layouts/BaseLayout.astro
title: '나의 첫 MDX 게시물'
publishDate: '21 September 2022'
---
import BaseLayout from '../../layouts/BaseLayout.astro';
export function fancyJsHelper() {
return "YAML로 시도해 보세요!";
}
<BaseLayout title={frontmatter.title} fancyJsHelper={fancyJsHelper}>
MDX를 사용하는 새 Astro 블로그에 오신 것을 환영합니다!
</BaseLayout>

그러면 레이아웃의 Astro.props를 통해 값을 사용할 수 있으며 MDX 콘텐츠는 <slot /> 컴포넌트가 작성된 페이지에 삽입됩니다.

src/layouts/BaseLayout.astro
---
const { title, fancyJsHelper } = Astro.props;
---
<html>
<head>
<!-- -->
<meta charset="utf-8">
</head>
<body>
<!-- -->
<h1>{title}</h1>
<slot /> <!-- 콘텐츠는 여기에 삽입됩니다. -->
<p>{fancyJsHelper()}</p>
<!-- -->
</body>
</html>

어떤 레이아웃을 사용할 때(프런트매터 layout 속성을 통해서든 레이아웃을 가져오든), 레이아웃에 <meta charset="utf-8"> 태그를 반드시 포함해야 합니다. Astro가 더 이상 MDX 페이지에 이를 자동으로 추가하지 않기 때문입니다.

Markdown/MDX 가이드에서 Astro의 Markdown 및 MDX 지원에 대해 자세히 알아보세요.

레이아웃 컴포넌트는 HTML의 전체 페이지를 포함할 필요가 없습니다. 레이아웃을 더 작은 컴포넌트로 나누고 레이아웃 컴포넌트를 결합하여 더욱 유연한 페이지 템플릿을 만들 수 있습니다. 이 패턴은 여러 레이아웃에서 일부 코드를 공유하려는 경우에 유용합니다.

예를 들어, BlogPostLayout.astro 레이아웃 컴포넌트는 게시물의 제목, 날짜, 작성자의 스타일을 지정할 수 있습니다. 그리고 사이트 전체 BaseLayout.astro가 탐색, 바닥글, SEO 메타 태그, 전역 스타일, 글꼴과 같은 페이지 템플릿의 나머지 부분을 처리할 수 있습니다. 또한, 다른 중첩 컴포넌트와 마찬가지로 게시물에서 받은 props를 다른 레이아웃으로 전달할 수도 있습니다.

src/layouts/BlogPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout url={frontmatter.url}>
<h1>{frontmatter.title}</h1>
<h2>게시물 작성자: {frontmatter.author}</h2>
<slot />
</BaseLayout>
기여하기

여러분의 생각을 들려주세요!

GitHub Issue 생성

우리에게 가장 빨리 문제를 알려줄 수 있어요.

커뮤니티