본문 바로가기
Programming/Javascript

개츠비(Gatsby) 마크다운 파일과 이미지 처리하기

by Wilkyway 2023. 7. 30.
반응형

사실...여러 예제와 뤼튼 AI를 이용해서 하루 종일 고생하며 방법을 찾아봤는데, 지금도 왜 되었는지 잘 모르겠습니다. 예제를 따라 해도 안되던게 갑자기 됩니다. 우선 코드만 남겨놓습니다.

 

 

 

1. 마크다운 파일 읽어오는 옵션

'gatsby-source-filesystem'은 기본적으로 설치되었을겁니다. 마크다운 파일들을 모아놓는 곳을 아래와 같이 설정해줍니다.

// gatsby-config.js
module.exports = {
  siteMetadata: { ... },
  plugins: [
    ...,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/content/posts`,
      },
    },
    ...
  ],
};

2. gatsby-plugin-image 플러그인

'gatsby-plugin-image' 플러그인도 기본으로 설치가 되어있을 확률이 높습니다. Gatsby에서 이미지를 렌더링 할 때 사용하는 플러그인입니다. 이미지들에 대해 자동으로 인식하여 속성정보를 생성해주지만, 가장 중요한 것 - 이미지 폴더를 지정해줘야합니다.

module.exports = {
  ...,
  plugins: [
    `gatsby-plugin-image`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/content/posts/images`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/content/posts`,
      },
    },

 

3. 마크다운 파일

아래 정도의 frontmatter를 작성해줍니다. 샘플로 몇개를 더 만들어놓습니다. 그리고 thumbnail경로에 예시 코드와 맞도록 이미지를 준비해줍니다.

---
title: Todo List
date: "2022-05-10T22:12:03.284Z"
description: 남은 할일 목록
slug: page1
thumbnail: './images/page1.png'
---


- 댓글기능
- 검색최적화(SEO)
- 카테고리 만들기

 

4./gatsby-node.js

이 부분에서는 이전 포스트 대비 특별히 손댈 것은 없습니다. thumbnail노드 하위의 속성은 gatsby-plugin-image 플러그인을 통해 인식된 이미지들로 인해 자동으로 생성됩니다.

const path = require('path');

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;

  const blogPostTemplate = path.resolve('src/templates/md-files.js');

  return graphql(`
    {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `).then((result) => {
    if (result.errors) {
      return Promise.reject(result.errors);
    }

    result.data.allMarkdownRemark.edges.forEach(({ node }) => {
      createPage({
        path: node.fields.slug,
        component: blogPostTemplate,
        context: {
          slug: node.fields.slug,
        },
      });
    });
  });
};

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;

  if (node.internal.type === `MarkdownRemark`) {
    const slug = path.basename(node.fileAbsolutePath, '.md');

    createNodeField({
      node,
      name: `slug`,
      value: `/${slug}`,
    });
  }
};

6. src/pages/index.js

이전 포스팅에서 작성한 내용에서, 각 포스팅의 타이틀 스타일을 변경해주고, 표시되는 순서를 작성일의 역순정렬로 변ㄱ여하였습니다.

import React from "react"
import { useStaticQuery, Link, graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) => {
  console.log(data)
  return (
    <Layout>
      <div>
        <h1>
          A World of Hello World and Todo List
        </h1>
        <h4>{data.allMarkdownRemark.totalCount} Posts</h4>
        {data.allMarkdownRemark.edges.map(({ node }) => (
          <div key={node.id} style={{
            marginBottom: "50px",
          }}>
            <h2>
              <Link to={node.fields.slug}
                style={{
                  color: "#555",           
                  textDecoration: "none",
                }}>
                {node.frontmatter.title}{" "}
                <span>
                  — {node.frontmatter.date}
                </span>
              </Link>
            </h2>
            <p>{node.excerpt}</p>
          </div>
        ))}
      </div>
    </Layout>
  )
}

export const query = graphql`
  query {
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
            description
          }
          excerpt
          fields{
            slug
          }
        }
      }
    }
  }
`

 

7. src/templates/md-files.js

이부분이 마크다운 파일들을 읽어서 동일한 템플릿 형태로 표현해주는 부분입니다. 여기서 gatsby-plugin-image 플러그인에서 제공하는 GatsbyImage 컴포넌트와 getImage 메서드를 활용합니다. gatsby-plugin-image 역시 이미 설치되어있을 확률이 높습니다. 

import React from "react"
import { graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import Layout from "../components/layout"

export default function Template({ data }) {
  
  const { markdownRemark } = data
  const { frontmatter, html } = markdownRemark
  const thumbnailImg = getImage(frontmatter.thumbnail?.childImageSharp?.gatsbyImageData)

  return (
    <Layout>
      <div className="blog-post-container">
        <div className="blog-post">
          <GatsbyImage image={thumbnailImg} alt="Thumbnail" />
          <h1>{frontmatter.title}</h1>
          <h2>{frontmatter.date}</h2>
          <div dangerouslySetInnerHTML={{ __html: html }} />
        </div>
      </div>
    </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")        
        title  
        thumbnail {
          childImageSharp {
            gatsbyImageData
          }
        }
      }
    }  
  }
`

 

8. gatsby-remark-images 설치 및 설정

gatsby-remark-images플러그인을 설치한 후 gatsby-config.js파일에 아래와 같이 추가합니다. 이 플러그인은 마크다운 파일의 이미지를 최적화하여 사용할 수 있도록 도와주는 플러그인입니다. 화면에서 이상하게 나오던 이미지들이 아래의 설정 이후정상적으로 나옵니다. 

{
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 800,
            },
          },
        ],
      },
    },

 

<결과>

반응형

댓글