메인 브랜치에 CMS 변경 테스트용 브랜치를 성공적으로 머지 시켰다! 이제 Netlify CMS는 안녕~! 어제에 이어 변경한 과정을 기록해 보겠다.
3. index.js 수정
index.js는 블로그의 메인 화면으로, 작성일을 기준으로 최신 ~ 오래된 포스트 순으로 정렬하여 리스트를 뿌려야 하는 곳이다. 먼저 index.js의 쿼리를 변경하여 Contentful에 등록한 블로그 포스트 목록을 가져오자.
여기서 조금 신경써야할 점은 포스트의 date와 관련된 것이다. date를 Content Model에 추가했다면 내가 지정한 date와, 게시글이 마지막으로 업데이트된 시점(updatedAt), 게시글이 생성된 시점(CreatedAt)이 각각 별개로 저장되었을 것이다.
내가 정한 date와 작성한 날짜(CreatedAt)가 일치할 경우 리스트를 sort하지 않아도 배열의 순서가 최신 ~ 오래된 포스트 순으로 예쁘게 정리되지만, 지정한 date와 CreatedAt가 불일치하는 경우-예를 들어 A라는 글의 date를 3월 2일로 설정했지만 실제로 3월 11일에 작성한 경우-에는 배열의 순서를 date를 기준으로 sort해야 한다.
(sort: { fields: date, order: DESC })를 추가하여 date 순으로 정렬해주자.
const BlogIndex = ({ data, location }) => {
const posts = data.allContentfulVtMorgonBlog.edges // 변경
}
export const pageQuery = graphql`
query {
site {
siteMetadata {
title
}
}
// date를 기준으로 내림차순(DESC)한 데이터를 가져옴
allContentfulVtMorgonBlog(sort: { fields: date, order: DESC }) {
edges {
node {
id
title
slug
description
date(formatString: "YYYY, MMMM DD")
tags
blogContent {
childMarkdownRemark {
html
}
}
}
}
}
}
`
포스트가 date를 기준으로 예쁘게 정렬된 것을 확인했다면 나머지 부분을 위의 쿼리에 맞추어 변경한다.
const BlogIndex = ({ data, location }) => {
const posts = data.allContentfulVtMorgonBlog.edges // 변경
// ... 중략
return (
// ... 중략
return (
<li key={index}>
<article
className="post-list-item"
itemScope
itemType="http://schema.org/Article"
>
<header>
{post.node.tags && post.node.tags !== null ? (
<ol className="categories">
{post.node.tags.map((tag, index) => {
return (
<li className="categories-item" key={index}>
{tag}
</li>
)
})}
</ol>
) : null}
<h2>
<Link to={post.node.slug} itemProp="url">
<span itemProp="headline">{title}</span>
</Link>
</h2>
<small>{post.node.date}</small>
</header>
<section>
<p
dangerouslySetInnerHTML={{
__html: post.node.description || post.excerpt,
}}
itemProp="description"
/>
</section>
</article>
</li>
)
})}
</ol>
</Layout>
)
}
4. blog-post.js 수정
포스트 템플릿(blog-post)은 gatsby-node에서 넘겨 받는 각각의 id와 slug값에 매칭(equal)하는 데이터를 사용하므로 모든 포스트 데이터(allContentfulVtMorgonBlog)가 필요하지 않다.
대신, 넘겨 받은 $id에 해당하는 contentfulVtMorgonBlog의 데이터를 가져와 사용할 수 있다.
query BlogPostBySlug($id: String!) {
// ... 중략
contentfulVtMorgonBlog(id: { eq: $id }) {
id
title
slug
description
date(formatString: "YYYY, MMMM DD")
tags
blogContent {
childMarkdownRemark {
html
}
}
}http://localhost:8000/___graphql에서 확인하면 좀 더 쉽게 이해할 수 있다.
임의의 id값을 넣어보자. 해당 id에 매칭되는 데이터가 출력되는 것을 확인할 수 있다. 데이터를 무사히 가져왔다면 마찬가지로 나머지 부분을 위의 쿼리에 맞추어 변경한다.
이제 블로그 하단에 있는 이전글, 다음글(= 포스트 네이게이션)을 만들어보자.
포스트 네이게이션을 구현하려면 gatsby-node.js에서 각 아이템의 index값을 기준으로 이전, 다음 게시글의 정보를 넘겨 받아야한다.
gatsby-node.js로부터 생성하는 페이지에 원하는 값을 전달하고 싶다면 createPage 내부 context에 값을 추가하면 된다. 아래와 같이 index를 이용하여 prev, next를 구한 뒤, context에 추가하자.

나같은 경우 배열을 date를 기준으로 내림차순했기 때문에 이전 게시글( relatively old)은 기준이 되는 글의 인덱스 값에서 +1, 다음 게시글( relatively recent)은 기준이 되는 글의 인덱스 값에서 -1 하여 구했다.
// gatsby-node.js
exports.createPages = async ({ graphql, actions, reporter }) => {
// ... 중략
const result = await graphql(
// ... 중략
const posts = result.data.allContentfulVtMorgonBlog.edges // 변경
if (posts.length > 0) {
posts.forEach((post, index) => {
createPage({
path: post.node.slug,
component: blogPost,
// context에 추가한 값은 blogPost에서 받아서 사용할 수 있다.
// index 값을 context에 추가 : prev, next 값을 가져오기 위함.
context: {
id: post.node.id,
prev: index === posts.length - 1 ? null : posts[index + 1].node,
next: index === 0 ? null : posts[index - 1].node,
},
})
})
}
}
이후 블로그 포스트 컴포넌트에서 pageContext를 props에 추가한 뒤, 값이 제대로 전달되었는지 console에 찍어본다.
// blog-post.js
const BlogPostTemplate = ({ data, location, pageContext }) => {
console.log(pageContext);
// ~~~ 코드 ~~~
}문제 없이 진행했다면 context로 전달한 id와 prev, next 값이 출력될 것이다. 이제 이 값을 이용하여 포스트 네이게이션을 구현하는 작업을 진행하면 된다.
// blog-post.js
const BlogPostTemplate = ({ data, location, pageContext }) => {
const post = data.contentfulVtMorgonBlog
const siteTitle = data.site.siteMetadata?.title || `Title`
const { prev, next } = pageContext
return (
// ...중략
<Layout>
<nav className="blog-post-nav">
<ul
style={{
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
}}
>
<li>
{previous && (
<Link to={previous.slug} rel="prev">
← {previous.title}
</Link>
)}
</li>
<li>
{next && (
<Link to={next.slug} rel="next">
{next.title} →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
// Query
export const pageQuery = graphql`
query BlogPostBySlug($id: String!) {
site {
siteMetadata {
title
}
}
contentfulVtMorgonBlog(id: { eq: $id }) {
id
title
slug
description
date(formatString: "YYYY, MMMM DD")
tags
blogContent {
childMarkdownRemark {
html
}
}
}
}
`
5. 배포 설정
이제 큰 작업은 마무리 되었다. 마지막으로 Netlify와 Contentful을 연결하여 게시글을 발행시 자동으로 배포 되도록 설정하면 완성이다!
넷리파이 블로그를 참고하면 간단한 방법으로 Netlify와 Contentful을 연결할 수 있다.
[1]편에서 환경변수에 등록했던 API Key값들을 Netlify에 추가하는 것도 잊지말자. Git에 환경변수 파일이 올라가지 않았기 때문에 따로 설정을 해주지 않으면 Key값이 없어 빌드 에러가 난다. Site Settings => Build & Deploy => environment에 필요한 값을 추가한다.
올바른 Key값을 추가했다면 성공적으로 빌드 & 배포될 것이다.
6. 완성✨
미루고 있던 작업이라 끝내고 나니 후련하다!! 물론 완벽하게 끝낸 것은 아니라서 조금씩 손을 더 봐야할 부분이 남아있다. 이번에 수정 작업을 진행하면서 gatsby에 대한 이해가 부족하다는 것을 느꼈다. 스타터 테마로 시작해서 그런가… 다음에 한번 처음부터 만들어봐도 재밌을 것 같다.
오늘도 공식문서를 자주 읽는 습관을 가져야겠다고 다짐한다.