Gatsby는 사이트 내에서 마크다운 파일로 페이지 생성을 할 수 있다. 마크다운 파일을 읽고 이해하기 위해 플러그인을 추가하고, 그 파일로부터 페이지를 자동 생성한다.
파일 시스템으로부터 Gatsby로 파일 읽어오기
아래 플러그인을 사용해 파일을 읽고 Gatsby가 GraphQL 데이터 레이어에 파일 노드를 생성하도록 할 수 있다.
npm install gatsby-source-filesystem
개츠비 설정 파일인 gatsby-config.js
를 열어 gatsby-source-filesystem
플러그인을 추가한다. path
옵션은 파일을 검색할 디렉토리를 설정하는 방법이다.
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content`,
path: `${__dirname}/src/content`,
},
},
],
}
Gatsby의 src
디렉토리 내에 content
라는 이름의 폴더를 생성하고, 그 안에 post-1.md
라는 이름의 마크다운 파일을 만든다. 마크다운 파일을 생성할 때, 그 안에 특정 페이지와 관련된 추가 데이터를 제공하는 데 사용되는 키/값 쌍을 포함할 수 있다. 이 데이터를 frontmatter
라고 하며, 블록의 시작과 끝은 세 개의 대시(- - -)로 감싼다. 이 단계에서 중요한 것은 키 쌍(key pair)인 slug이다. 키 slug에 할당된 값은 글의 최종 URL에 사용된다. 위의 단계를 완료하면 파일 시스템에서 마크다운 파일을 소스로 사용하게 된다. 그리고 마크다운을 HTML로, YAML frontmatter를 JSON으로 변환할 수 있다.
// src/content/post-1.md
---
slug: "/1"
date: "2019-01-23"
page: "1"
title: "구글 신은 알고 있다"
description: "우리는 다음 달에나 만날 생각이었다."
---
마크다운을 HTML 및 frontmatter 데이터 형식으로 변형
마크다운 파일을 인식하고 내용을 읽기 위해 gatsby-transformer-remark
플러그인을 사용해야 한다. 이 플러그인은 마크다운 파일의 메타데이터 부분을 frontmatter로, 내용 부분을 HTML로 변환한다.
npm install gatsby-transformer-remark
다음 코드를 gatsby-config.js
의 이전 부분에 추가한다.
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content`,
path: `${__dirname}/src/content`,
},
},
`gatsby-transformer-remark`,
],
}
마크다운 파일에 대한 라우트 컴포넌트 컬렉션 만들기
파일 시스템 경로 API를 사용해 컬렉션 경로를 생성한다. 경로에 맞게 정해진 파일명으로 코드를 작성하고, 원하는 정보를 마크다운에서 적절히 가져와 컴포넌트에 표시한다. 아래 코드는 frontmatter
에서 제목, 작성일, 번호(업로드 순)를 활용했다. 이 작업을 마치고 나면 쿼리의 결과가 Gatsby에 의해 각각의 컴포넌트에 props
로 전달되는데, markdownRemark
파일은 마크다운의 모든 세부 정보를 가지고 있다.
// src/pages/posts/{markdownRemark.frontmatter__slug}.jsx
import { graphql } from "gatsby";
import * as React from "react";
// ...
interface Post {
node: {
frontmatter: {
slug: string;
title: string;
page: number;
};
};
}
interface BlogPostTemplateProps {
data: {
markdownRemark: {
html: string;
frontmatter: {
date: string;
slug: string;
title: string;
page: any;
description: string;
};
};
allMarkdownRemark: {
edges: Post[];
};
};
}
export default function BlogPostTemplate({ data }: BlogPostTemplateProps) {
const { markdownRemark, allMarkdownRemark } = data;
const { frontmatter, html } = markdownRemark;
// ...
return (
<React.Fragment>
// ...
<Layout page={<PageNumber page={frontmatter.page} />} info={<PostInfo date={frontmatter.date} prev={PrevPost} next={NextPost} />}>
<HomePage
content={<div className="content-text" dangerouslySetInnerHTML={{ __html: html }} />}
title={frontmatter.title}
line={<div className="mobile-line"></div>}
prev={PrevPost}
middle={<div className="mobile-middle">작성일: {frontmatter.date}</div>}
next={NextPost}
/>
</Layout>
</React.Fragment>
);
}
export const pageQuery = graphql`
query ($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
date(formatString: "YYYY년 M월 D일")
slug
title
page
description
}
}
allMarkdownRemark {
edges {
node {
id
frontmatter {
title
date(formatString: "DD MMMM, YYYY")
page
slug
}
}
}
}
}
`;
아래 링크에 관련 정보가 자세히 설명되어 있다. Gatsby는 아직 한국어를 지원하지 않아 조금 아쉽다.