Gatsby 블로그 게시글 목록에 섬네일 추가하기

2024년 10월 1일 오전 2시 21분 KST

요즘 블로그를 꾸미는 일에 맛들렸습니다. 이 블로그도 뭔가 재귀함수처럼 블로그를 만드는 글을 올리는 블로그가 되어가고 있는데, 어쨌든 좋은 것 같습니다. 무언가 해결한 경험을 휘발성으로 날리는 것보다는 글로 정리하는 것이 미래의 저에게도 좋고, 누군가에게도 도움이 되겠지요. Gatsby 프레임워크가 React 기반이다 보니 커스터마이징하는 것도 용이하고, React와 JavaScript를 이해하는 데에도 좋은 경험이 되는 것 같습니다.

이번에는 저의 gatsby-starter-blog로 만든 블로그의 게시글 목록에 섬네일을 추가해보려고 합니다. 글 목록에 텍스트만 있기 보다는 기본 이미지 한 장이라도 있는 게 조금 더 다채롭게 보일 것 같았기 때문입니다. 글에 대한 단서 하나를 더 제공하는 셈이기도 하니, 제 블로그를 방문해 주신 분들이 게시글을 클릭할 확률도 조금 올라가겠죠.

1. 마크다운 문서의 프런트매터에 섬네일 값 추가

우선 섬네일을 추가하기 전에 섬네일 이미지의 경로를 지정해야 합니다. 저는 마크다운 문서의 프런트매터1번 각주로 이동thumb이라는 키를, 섬네일 이미지의 파일 경로를 값으로 지정하겠습니다. 그렇게 하면 프런트매터는 다음과 같은 형태를 띄게 될 것입니다.

---
title: 국방모바일보안과 iPhone 16의 카메라 제어 버튼
date: 2024-09-24T02:00:00
tags:
  - iPhone-16
  - 카메라-제어-버튼
  - 국방모바일보안
thumb: iphone-16-pro-product-box.jpeg
description: 국방모바일보안 애플리케이션으로 카메라가 제한되었다가 해제되었을 때 카메라 제어 버튼이 작동하지 않는 문제를 해결합니다.
---

저의 경우 thumb 키의 값인 파일 경로는 마크다운 문서와 같은 경로에 위치하므로, 파일 경로는 즉 파일 명이 되겠습니다.

2. 패키지 설치

저는 섬네일 기능을 위해 따로 패키지들을 설치하지 않았던 것 같습니다. 아래 패키지들은 gatsby-starter-blog에 포함되어 있겠지만, 혹시 플러그인이 설치되어 있지 않았을 경우 아래 명령어로 패키지들을 설치할 수 있습니다.

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp

그리고 gatsby-config.js 파일에는 아래와 같이 플러그인들이 포함되어 있어야 합니다. 이 부분은 꼭 확인을 하셔야 합니다.

module.exports = {
  plugins: [
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
    // 나머지 플러그인...
  ],
}

3. GraphQL 쿼리 수정

이후, GraphQL 쿼리를 수정해서 마크다운 문서의 thumb 키의 값을 가져오도록 합니다. 게시글 목록의 파싱을 담당하는 src/pages/index.js 파일의 GraphQL 쿼리를 다음과 같이 수정합니다.

export const pageQuery = graphql`
  {
    site {
      siteMetadata {
        title
      }
    }
    allMarkdownRemark(sort: { frontmatter: { date: DESC } }) {
      nodes {
        excerpt
        fields {
          slug
        }
        frontmatter {
          date(formatString: "YYYY. MM. DD.")
          title
          description
          thumb {
            childImageSharp {
              gatsbyImageData(width: 320, layout: CONSTRAINED)
            }
          }
        }
      }
    }
  }
`
  1. frontmatter 필드의 하위 필드로 thumb을 추가했습니다. 프런트매터에 작성한 thumb을 참조합니다.
  2. 그 아래에는 childImageSharp를 추가했는데, gatsby-plugin-sharp 플러그인이 thumb의 하위 노드로 childImageSharp라는 노드를 생성합니다. 여기서 childImageSharp는 이미지를 담을 컨테이너 역할을 합니다.
  3. childImageSharp의 내부 필드로는 gatsbyImageData를 추가했습니다. 이 필드는 표시할 이미지와, 최적화된 이미지를 렌더링하는 데 필요한 데이터가 포함된 객체입니다. 속성 값으로 width를 320px, 레이아웃은 CONSTRAINED(최대 너비/높이를 지정하되, 더 작은 화면에서는 비율을 유지하며 축소됨)를 사용했습니다.

4. 글 목록 레이아웃 수정

이제 글 목록에 섬네일을 띄울 차례입니다. 이번에도 마찬가지로 글 목록 생성을 담당하는 src/pages/index.js 파일을 수정할 것입니다.

먼저, GatsbyImagegetImage, StaticImage 모듈을 불러옵니다.

import { GatsbyImage, getImage, StaticImage } from "gatsby-plugin-image"

그리고, 레이아웃에서 글 목록을 파싱하여 출력하는 map 함수 내부에 섬네일 변수를 할당합니다.

{posts.map(post => {
  const title = post.frontmatter.title || post.fields.slug
  const thumb = !!post.frontmatter.thumb
	? getImage(post.frontmatter.thumb)
	: null
  return (
          
  (이하 생략...)

저는 프런트매터에 섬네일 파일 경로가 없는 경우를 예외로 처리하기 위해 위와 같이 삼항 연산자를 사용했습니다. 섬네일 파일 경로가 있을 경우에는 getImage 함수로 섬네일 파일을 불러오고, 없을 경우 변수에 null을 할당합니다.

그리고, 섬네일이 위치할 부분에 다음과 같이 코드를 작성합니다.

{thumb === null ? (
  <StaticImage
    src="../images/og-default.png"
    alt={""}
    imgStyle={{ objectFit: "contain" }}
    className="w-full aspect-video object-contain bg-bunker-50 rounded-md"
  />
) : (
  <GatsbyImage
    image={thumb}
    alt={""}
    imgStyle={{ objectFit: "contain" }}
    className="w-full aspect-video object-contain bg-bunker-50 rounded-md"
  />
)}

섬네일 경로가 없을 경우 기본 이미지를 출력하기 위해 마찬가지로 삼항 연산자를 사용했습니다. thumb 변수의 값이 null일 경우에는 <StaticImage> 컴포넌트로 기본 이미지를 출력하고, thumb 변수에 섬네일 이미지가 있을 경우에는 <GatsbyImage> 컴포넌트로 섬네일 이미지를 출력합니다.

결과

블로그 글 목록에 섬네일 이미지가 표시되는 모습 이제 글 목록에 섬네일이 표시됩니다! 프런트매터에 섬네일 경로가 존재할 경우 섬네일 이미지를, 섬네일 경로가 존재하지 않는다면 기본 이미지(og-default.png)가 표시되는 모습을 볼 수 있습니다.

섬네일 이미지를 파싱해서 다루는 법을 터득했으니, 이제 이를 활용해서 다양한 상황에서 섬네일 이미지를 불러올 수 있게 되었습니다. 저는 이를 응용해서 Open Graph를 보완하고자 하는데, 이에 대해서는 다음 글에 작성하도록 하겠습니다.


  1. frontmatter: 책의 머리말이나 목차가 담긴 부분을 뜻하는 단어입니다.본문으로 돌아가기

jihun의 프로필 일러스트.

jihun, 테크놀로지에 상상력을 더하는 프론트엔드 개발자.