[Gatsby] Gatsby에 MDX 플러그인 적용해서 기술 블로그 만들기

코린·2023년 8월 24일
0
post-thumbnail

gatsby-plugin-mdx | Gatsby

공식문서를 찬찬히 살펴보면서 해보겠음미닥!!!!!!

학습 페이지
이건 참고하면 좋으실거 같아 추가로 남겨둡니다.

Adding MDX Pages | Gatsby

일단.. 이걸 보면서 했습니다..

🧐 마크다운 파일을 추가하고 읽어옵시다!


📌 플러그인 설치

npm install gatsby-plugin-mdx gatsby-source-filesystem @mdx-js/react

📌 마크다운 파일 생성

${__dirname}/content/posts 폴더를 생성합니다.

그리고 그 안에 mdx 파일을 작성하고 넣습니다.

---
title: Blog Post 1
slug: /blog-1
---

Trying out MDX

📌 gastby-config.js 파일 수정

/**
 * @type {import('gatsby').GatsbyConfig}
 */
module.exports = {
    siteMetadata: {
        title: `my-portfolio`,
        siteUrl: `https://www.yourdomain.tld`,
    },
    plugins: [
        'gatsby-plugin-postcss',
        {
            resolve: `gatsby-plugin-mdx`,
            options: {
                extensions: [`mdx`, `md`],
                name: `posts`,
                path: `${__dirname}/content/posts`,
                gatsbyRemarkPlugins: [
                    {
                        resolve: `gatsby-remark-images`,
                        options: {
                            maxWidth: 590,
                        },
                    },
                ],
            },
          {
          	resolve: `gatsby-source-filesystem`,
          	options: {
          		name: `posts`,
          		path: `{__dirname}/content/posts`
        	},
          
          }
        },
    ],
};

gatsby-plugin-mdx 이 부분이 참고하면 되는 부분입니다!

gastbyRemarkPlugins 이 부분은 있어도 그만 없어도 그만입니다! 저건 이미지때문에 미리 적용해놓은거긴 한데.. 몰라여 아직 쓸줄..

📌 gatsby-node.js 파일 생성

const path = require('path');
const postTemplate = path.resolve(`./src/templates/post.jsx`);

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

    const result = await graphql(`
        query {
            allMdx {
                nodes {
                    id
                    frontmatter {
                        slug
                    }
                    internal {
                        contentFilePath
                    }
                }
            }
        }
    `);

    if (result.errors) {
        reporter.panicOnBuild('Error loading MDX result', result.errors);
    }

    // Create blog post pages.
    const posts = result.data.allMdx.nodes;

    // you'll call `createPage` for each result
    posts.forEach((node) => {
        createPage({
            // As mentioned above you could also query something else like frontmatter.title above and use a helper function
            // like slugify to create a slug
            path: node.frontmatter.slug,

            // Provide the path to the MDX content file so webpack can pick it up and transform it into JSX
            component: `${postTemplate}?__contentFilePath=${node.internal.contentFilePath}`,
            // You can use the values in this context in
            // our page layout component
            context: { id: node.id },
        });
    });
};

gatsby-config.js 와 동일한 경로에 gatsby-node.js 파일을 생성해줍니다.

그리고 ./src/templates/post.jsx 이 파일을 생성해줍니다.

(src폴더에 templates 폴더를 생성하고 post.jsx 만들라는거 알져..?)

폴더의 경로와 이름은 임의로 설정하셔도 됩니다! 저는 그냥 공식문서 그대로 따라했을 뿐..

📌 Post.jsx

import React from "react"
import { graphql } from "gatsby"
import { MDXProvider } from "@mdx-js/react"
import { Link } from "gatsby"

const shortcodes = { Link } // Provide common components here

export default function PageTemplate({ data, children }) {
  return (
    <>
      <h1>{data.mdx.frontmatter.title}</h1>
      <MDXProvider components={shortcodes}>
        {children}
      </MDXProvider>
    </>
  )
}

export const query = graphql`
  query($id: String!) {
    mdx(id: { eq: $id }) {
      frontmatter {
        title
      }
    }
  }
`

이 파일의 역할은 마크다운 파일을 보여줄때 사용할 템플릿입니다!

📌 index.jsx

import React from 'react';
import 'aos/dist/aos.css';
import { graphql, Link } from 'gatsby';
import Nav from '../Components/Header/Nav';
import notebook from '../images/notebook.png';

function IndexPage({ data }) {
    let introText = 'bg-gradient-to-r from-h-blue to-h-gray text-transparent bg-clip-text font-extrabold text-3xl';

    const posts = data.allMdx.edges;

    return (
       ...생략..
                    <div className="mt-4">
                        {posts.map((post) => (
                            <Link
                                to={post.node.frontmatter.slug}
                                key={post.node.id}
                                className="w-full h-56 p-4 flex flex-col rounded-lg cursor-pointer hover:bg-post-hover-gray"
                            >
                                <div className="font-extrabold mt-2 text-2xl flex-none">
                                    {post.node.frontmatter.title}
                                </div>
                                <div className="text-slate-500 mt-2 flex-grow">{post.node.excerpt}</div>
                                <div className="text-slate-500 mt-2 flex-none">{post.node.frontmatter.date}</div>
                            </Link>
                        ))}
                    </div>
                </div>
            </div>
        </div>
    );
}

export const query = graphql`
    query {
        allMdx(sort: { frontmatter: { date: DESC } }, limit: 2) {
            edges {
                node {
                    id
                    excerpt(pruneLength: 250)
                    frontmatter {
                        title
                        date(formatString: "MMMM DD, YYYY")
                        slug
                    }
                }
            }
        }
    }
`;

export default IndexPage; 

이렇게 하면 data에 마크다운 파일에서 읽어온 값들이 저장되는 것을 확인할 수 있습니다.

객체 형태로 data가 결과값이 들어오니 그 점 참고해서 잘 입력받아주면 됩니다!

(아니면 graphql 콘솔에서 어떻게 출력되는지 확인해보세여! → http://localhost:8000/___graphql)

🤬 문제점과 해결


아니 다른 파일에서 graphql 쿼리를 써주고 data를 받았는데 undefined가 뜨더랍니다..

해결방법

암튼 index.js에서 graphql 쿼리를 짜주고 날렸더니 데이터가 잘 들어오더라~~

🧐 근데 왜 다른 페이지로 넘어가서 하면 안되는걸까요?
gatsby-config.js에 파일 경로를 잘못 지정해줘서 생긴 문제인 것 같습니다. 해당 파일을 수정해줬더니 어느파일에서든 graphql이 잘 작동합니다.

/**
 * @type {import('gatsby').GatsbyConfig}
 */
module.exports = {
    siteMetadata: {
        title: `my-portfolio`,
        siteUrl: `https://www.yourdomain.tld`,
    },
    plugins: [
        'gatsby-plugin-postcss',
       {
            resolve: `gatsby-plugin-mdx`,
            options: {
                extensions: ['.mdx', '.md'],
                gatsbyRemarkPlugins: [
                    {
                        resolve: `gatsby-remark-images`,
                        options: {
                            maxWidth: 590,
                        },
                    }    
                ],
            },
        },
        {
            resolve: `gatsby-source-filesystem`,
            options: {
                name: `posts`,
                path: `${__dirname}/content/posts`,
            },
        },
    ],
};
profile
안녕하세요 코린입니다!

0개의 댓글