[Gastby] Contentful

YunHee·2024년 5월 31일

Gatsby

목록 보기
7/7

1. Contentful ?

  • Headless CMS (Content Management System : 컨텐츠를 관리하는 시스템)
  • 간편하게 Markdown으로 컨텐츠를 관리할 수 있습니다.
  • Record (entries + assets) 25k까지 무료입니다.
  • https://www.contentful.com/

1-1. 가입 및 content 생성

  • Post model 만들기
    - Title
    - slug
    - content

1-2. Post 생성하기

  • 모델 생성후, content탭을 눌러 post를 작성해보자.
  • 작성하고 Publish 한다.


💡포인트

이미지 파일은 꼭 Published 상태여야 한다. (Draft 이면 안됨.) 그래야 graphql 쿼리에서 preview - gatsbyImageData 리졸버에 접근 가능하다.


2. Gastby 에서 contentful 데이터 가져오기

2-1. Install

npm install gatsby-source-contentful gatsby-plugin-image
npm install dotenv
  • dotenv : .env 허용


2-2. API

  • CONTENTFUL -> SETTINGS -> API
  • Space IDContent Delivery API - access token 확인

2-3. Setting

  • gatsby-config.ts : 플러그인 추가
// gatsby-config.ts

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
});
...
plugins: [
    {
      resolve: "gatsby-source-contentful",
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        // Learn about environment variables: https://gatsby.dev/env-vars
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
      },
    },
  ],
  • .env.development : 개발환경일 때 사용. 루트폴더 아래 .env.development 파일 작성.
// .env.development
GATSBY_APP_CONTENTFUL_SPACE_ID = Id
GATSBY_APP_CONTENTFUL_ACCESS_TOKEN = 토큰
  • .gitignore : github에 올라가지 않도록 .env 추가
// .gitignore
node_modules/
.cache/
public
src/gatsby-types.d.ts
.env

3. Contentful 데이터로 페이지 작성하기

3-1. GraphqQL로 Contentful 데이터 확인


3-2. product 폴더 만들기

  • src/pages/products/{contentfulPost.id}.tsx 경로의 파일을 만든다.

💡 컬렉션 경로를 만들려면 파일 이름에 중괄호({ })를 사용하여 노드 내의 필드와 관련된 동적 URL 세그먼트를 나타냅니다.

  • pageContext prop을 사용하면 빌드시 필요한 모든 데이터를 가져올 수 있어 성능에 이점을 얻을 수 있다.
  • context 매개변수(parameter)를 선언한 후 한 곳에서 데이터를 쿼리할 수 있다는 이점이 있다.
// src/pages/products/{contentfulPost.id}.tsx
import React from "react";

interface productProps {
  pageContext: any;
}

export default function Product({ pageContext }: productProps) {
  const { product } = pageContext;
  return (
    <div>
      <ul>
        <li>Name:{product.title}</li>
        <li>Price:{product.price}</li>
        <li>Slug:{product.slug}</li>
        <li>Preview:{product.preview}</li>
        <li>content:{product.content}</li>
      </ul>
    </div>
  );
}

3-3. Contentful

  • Home 페이지에서Posts 쿼리를 작성한다.
  • 쿼리의 data를 받아서 article 안에 title, price, imagedata를 불러온다.
// src/pages/index.tsx
import * as React from "react";
import { graphql, Link, PageProps } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";
import Seo from "../components/Seo";
import Layout from "../components/Layout";

export default function IndexPage({ data }: PageProps<Queries.PostsQuery>) {
  return (
    <Layout title="Welcome my stie!">
      <Link to="/about">About</Link>
      <p>I'm making this by following the Gatsby Tutorial.</p>
      {data.allContentfulPost.nodes.map((post) => (
        <article>
          <GatsbyImage
            image={getImage(post.preview?.gatsbyImageData!)!}
            alt={post.title!}
          />
          <h2>{post.title}</h2>
          <h4>{post.price}</h4>
        </article>
      ))}
    </Layout>
  );
}

export const query = graphql`
  query Posts {
    allContentfulPost {
      nodes {
        id
        title
        slug
        price
        preview {
          gatsbyImageData(placeholder: BLURRED, height: 250)
        }
      }
    }
  }
`;

export const Head = () => <Seo title="Home" />;


3-4. Products Detail

  • title,priceLink를 달아주고
// src/pages/index.tsx
import * as React from "react";
import { graphql, Link, PageProps } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";
import Seo from "../components/Seo";
import Layout from "../components/Layout";

export default function IndexPage({ data }: PageProps<Queries.PostsQuery>) {
  return (
    <Layout title="Welcome my stie!">
      <Link to="/about">About</Link>
      <p>I'm making this by following the Gatsby Tutorial.</p>
      {data.allContentfulPost.nodes.map((post) => (
        <article>
          <GatsbyImage
            image={getImage(post.preview?.gatsbyImageData!)!}
            alt={post.title!}
          />
          <Link to={`/products/${post.id}`}>
            <h2>{post.title}</h2>
            <h4>{post.price}</h4>
          </Link>
        </article>
      ))}
    </Layout>
  );
}

export const query = graphql`
  query Posts {
    allContentfulPost {
      nodes {
        id
        title
        slug
        price
        preview {
          gatsbyImageData(placeholder: BLURRED, height: 250)
        }
      }
    }
  }
`;

export const Head = () => <Seo title="Home" />;

  • 상품을 클릭했을때 상품의 detail 페이지로 이동할 수 있도록 product 쿼리를 작성해준다.
// src/pages/products/{contentfulPost.id}
import { graphql, PageProps } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";
import React from "react";
import Layout from "../../components/Layout";

export default function Product({ data }: PageProps<Queries.ProductQuery>) {
  const image = getImage(data.contentfulPost?.preview?.gatsbyImageData!);
  return (
    <Layout title={data.contentfulPost?.title!}>
      <GatsbyImage image={image!} alt={data.contentfulPost?.title!} />
      <h2>{data.contentfulPost?.price}</h2>
    </Layout>
  );
}

export const query = graphql`
  query Product($id: String!) {
    contentfulPost(id: { eq: $id }) {
      price
      title
      preview {
        gatsbyImageData(placeholder: BLURRED, height: 450)
      }
    }
  }
`;

  • 클릭하면, contentfulPostid로 만들어진 url을 확인할 수 있다.

3-5. GraphqQL로 모든사이트의 페이지 목록 확인하기

  • GraphqQL에서 allSitePage 필드로 현재 모든사이트의 페이지를 한번에 볼 수 있다.
  • contentful 에서 생성한 product의 slug를 받아와서 url로 바뀐것을 볼 수있다.




참고 사이트

Gatsby Docs

Gatsby Blog

블로그

그외

profile
오늘도 개발하는 코맹이

0개의 댓글