content-collections
콘텐츠 콜렉션(Content Collections)
콘텐츠 콜렉션은 문서를 정리하고 조회할 수 있게 해 주는 Astro의 기능이에요. 에디터에서 인텔리센스와 타입 체크를 켜 주고, 모든 콘텐츠에 자동으로 TypeScript 타입 안전성을 제공해 줘요. 블로그 글이나 상품처럼 구조가 같은 문서를 여러 개 다룰 때 특히 유용해요.
출처: 공식문서
본문
빌드 시점 콘텐츠 콜렉션 정의
빌드 시점 콜렉션 항목에서 페이지 라우트를 생성할 수 있어요. 완전히 정적인 프리렌더(pre-rendered) 사이트를 만든다면 빌드 시점에 페이지를 만들면 되고, 페이지가 처음 요청될 때까지 빌드를 미루고 싶다면 빌드 시점 콜렉션을 주문형(on demand)으로 렌더링할 수도 있어요.
빌드 시점 콜렉션 로더
file() 로더
file() 로더로 단일 JSON·YAML·TOML 파일을 콜렉션 항목으로 파싱하는 기능은 내장돼 있어요(중첩 JSON 문서는 제외). .csv처럼 지원되지 않는 파일 형식을 로드하려면 직접 파서(parser) 함수를 만들어야 해요.
중첩 .json 문서
parser() 인자로 중첩 JSON 문서에서 하나의 콜렉션을 로드할 수 있어요. 예를 들어 이 JSON 파일은 여러 콜렉션을 담고 있어요.
{"dogs": [{}], "cats": [{}]}
loader: file("src/data/pets.json", { parser: (text) => JSON.parse(text).cats })
});
커스텀 빌드 시점 로더
Astro integration이나 Vite 플러그인을 만들 때처럼, 로더를 npm 패키지로 배포해 다른 사람들의 프로젝트에서도 쓰게 할 수 있어요.
콜렉션 스키마 정의
콜렉션에 스키마를 정의하면 콜렉션을 조회할 때 완전한 TypeScript 지원(속성 자동완성과 타입 체킹)이 생겨요.
import { defineCollection } from "astro:content";
import { z } from "astro/zod";
import { glob, file } from "astro/loaders";
const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
...
}),
});
빌드 시점 콜렉션 조회
조회 결과는 고유한 id, 정의된 모든 속성을 담은 data 객체, 그리고 Markdown·MDX·Markdoc 문서의 원본(컴파일되지 않은) 본문을 담는 body를 반환해요.
본문 콘텐츠 렌더링
조회한 후에는 astro:content의 render() 함수로 Markdown·MDX 항목을 HTML로 렌더링할 수 있어요. 이 함수를 호출하면 <Content /> 컴포넌트와 렌더링된 모든 제목 목록을 포함한 HTML 콘텐츠에 접근할 수 있어요.
콘텐츠에서 라우트 생성
콘텐츠 콜렉션은 src/pages/ 폴더 밖에 저장돼요. 그래서 기본적으로 Astro의 파일 기반 라우팅이 콜렉션 항목에 대해 페이지나 라우트를 만들지 않아요. 필요한 페이지를 직접 만들어야 해요.
src/pages/blog/[...id].astro에서 Astro.params.id로 각 페이지에 맞는 항목을 가져올 수 있어요.
정적 출력으로 빌드(기본값)
정적 웹사이트(기본 동작)를 빌드 시점 콜렉션으로 만든다면, getStaticPaths() 함수로 단일 페이지 컴포넌트(예: src/pages/[id].astro)에서 여러 페이지를 만들어요.
getStaticPaths() 안에서 getCollection()을 호출해 콜렉션 데이터를 정적 라우트 빌드에 쓰면 돼요. 그다음 각 콘텐츠 항목의 id 속성으로 개별 URL 경로를 만들어요. 각 페이지는 페이지 템플릿에서 쓸 수 있도록 콜렉션 항목 전체를 prop으로 받아요.
이렇게 하면 blog 콜렉션의 모든 항목에 대한 페이지 라우트가 생겨요. 예를 들어 src/blog/hello-world.md 항목은 id가 hello-world이고, 최종 URL은 /posts/hello-world/가 돼요.
커스텀 슬러그에
/문자가 포함돼 여러 경로 세그먼트를 가진 URL을 만들려면, 이 동적 라우팅 페이지의.astro파일명에 rest 파라미터(예:[...id])를 써야 해요.
요청 시점에 주문형 라우트 빌드
주문형 렌더링용 어댑터를 설치했다면, 요청 시점에 동적 페이지 라우트를 생성할 수 있어요. 먼저 Astro.request나 Astro.params로 요청을 살펴보고 슬러그를 찾은 뒤, 콘텐츠 콜렉션 헬퍼 함수 중 하나로 그 항목을 가져와요.
getEntry()— 최초 요청 시 한 번 생성되는 빌드 시점 콜렉션 페이지용getLiveEntry()— 매 요청마다 데이터를 (재)가져오는 라이브 콜렉션 페이지용
라이브 콜렉션(Live content collections)
라이브 콜렉션 항목에서 주문형으로 페이지 라우트를 생성할 수 있어요. 빌드 시점 콜렉션처럼 사이트 재빌드 없이, 매 요청 시점에 런타임에서 새 데이터를 가져와요.
라이브 데이터 접근
라이브 로더가 rendered 속성을 반환하면, render() 함수와 <Content /> 컴포넌트를 빌드 시점 콜렉션과 같은 방법으로 페이지에서 콘텐츠를 직접 렌더링할 수 있어요.
라이브 데이터 캐싱
참고: [email protected]부터 추가됐어요.
라이브 로더가 캐시 힌트를 제공하면 getLiveEntry()와 getLiveCollection()이 cacheHint 객체를 반환해요. 이 객체로 헤더를 수동으로 설정하지 않고도 라우트의 캐싱 동작을 제어할 수 있어요.
콜렉션 전체를 getLiveCollection()으로 가져올 때는 콜렉션 응답과 모든 개별 항목의 캐시 힌트를 병합해요. 태그는 누적되고, 가장 최근의 lastModified가 이겨요.
더 알아보기
- 콘텐츠 로더 API — 커스텀 로더 만들기
- 라우팅 — 콜렉션으로 동적 라우트 생성하기
- 콘텐츠 타입 참조 —
CollectionEntry가 반환하는 속성 전체 보기