Contentful 및 React로 간단한 블로그 구축

개요



이번 포스트에서는 유명한 헤드리스 CMS, Contentful로 간단한 웹 애플리케이션을 구축하는 방법을 소개하겠습니다.

견본



이 게시물에 대한 내 코드는 다음과 같습니다.
레포https://github.com/koji/typescript/tree/master/simple_blog_with_contentful
.

헤드리스 CMS란 무엇입니까?



헤드리스 CMS가 무엇인지 간단히 말씀드리겠습니다.
대략적으로 헤드리스 CMS는 콘텐츠를 표시하는 기능이 없는 CMS입니다.dashboard 만 있는 WordPress와 같다고 가정해 보겠습니다.
아마도 다른 CMS 대신 헤드리스 CMS를 사용해야 하는 이유에 대해 생각하시는 분들도 계실 것입니다.

  • 공적
  • 프론트엔드에 집중할 수 있고 CMS에 의한 제한이 없음(사용하고 싶은 것은 무엇이든 사용할 수 있으며 개발 프로세스는 일반 프론트엔드 개발과 동일함)
  • Contentful 측면에서 데이터 가져오기를 위한 npm 패키지를 제공합니다
  • .


  • 단점
  • 비전공자의 외모 변경이 어려울 것임
  • 헤드리스 CMS에 문제가 발생하면 서비스 공급자가 문제를 해결할 때까지 기다려야 합니다.
    .
    만족스러운 정보
    https://www.contentful.com/developers/
    Contentful은 좋은 문서, Slack 그룹 및 포럼이 있기 때문에 훌륭합니다.
    .
    ## 1단계 콘텐츠 모델 정의
    Contentful에 로그인하고 반응 애플리케이션에 데이터를 표시할 모델을 정의합니다.
    이번 포스팅에서는 제목, 시선을 사로잡는 이미지, 본문 이렇게 3가지 항목만 만들었습니다.
    .

    .Data structure


  • {
      "name": "easysite", <-- コンテンツモデル名
      "description": "simple website like a blog",
      "displayField": "title",
      "fields": [
        {
          "id": "title",
          "name": "title",
          "type": "Symbol",
          "localized": false,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false
        },
        {
          "id": "image",
          "name": "image",
          "type": "Link",
          "localized": false,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false,
          "linkType": "Asset"
        },
        {
          "id": "description",
          "name": "Description",
          "type": "Text",
          "localized": false,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false
        }
      ],
      "sys": {
        "space": {
          "sys": {
            "type": "Link",
            "linkType": "Space",
            "id": "if4se75018sp"
          }
        },
        "id": "easysite",
        "type": "ContentType",
        "createdAt": "2020-10-01T15:28:51.896Z",
        "updatedAt": "2020-10-01T15:28:52.158Z",
        "environment": {
          "sys": {
            "id": "master",
            "type": "Link",
            "linkType": "Environment"
          }
        },
        "publishedVersion": 1,
        "publishedAt": "2020-10-01T15:28:52.158Z",
        "firstPublishedAt": "2020-10-01T15:28:52.158Z",
        "createdBy": {
          "sys": {
            "type": "Link",
            "linkType": "User",
            "id": "0EGNAqGfBgN849uaItzT7r"
          }
        },
        "updatedBy": {
          "sys": {
            "type": "Link",
            "linkType": "User",
            "id": "0EGNAqGfBgN849uaItzT7r"
          }
        },
        "publishedCounter": 1,
        "version": 2,
        "publishedBy": {
          "sys": {
            "type": "Link",
            "linkType": "User",
            "id": "0EGNAqGfBgN849uaItzT7r"
          }
        }
      }
    }
    

    .
    .

    2단계 콘텐츠 생성



    이 단계에서는 dev.to에 게시물을 작성하는 것과 거의 동일한 항목을 만들기만 하면 됩니다. 마크다운을 사용할 수 있습니다.

    콘텐츠 --> 항목 추가 --> easysite(이 경우 항목 모델easysite을 명명했습니다.)

    .


    상단부터 제목, 눈길을 끄는 이미지, 본문입니다.

    한 가지 알아두셔야 할 점은 본문을 공개한다고 해서 눈길을 끄는 이미지를 공개하는 것이 아니라는 것입니다.
    별도로 게시해야 합니다.
    .

    3단계 API 키 받기



    설정에서 API 키를 생성해야 합니다. 그런 다음 SpaceIDAccess Token를 얻습니다.

    .

    4단계 React 앱 만들기



    Contentful에 대한 작업이 끝났습니다. 이 단계부터 반응 애플리케이션을 개발하기만 하면 됩니다.
  • create-react-app로 앱 만들기
  • API 키에 대한 구성 요소를 추가합니다. 이 경우 로컬 환경에서 SpaceID와 Access Token을 하드코딩했지만, 이 앱을 퍼블리싱하려면 netlify와 같은 호스팅 서비스에서 환경 변수를 사용해야 합니다.
  • Yarn/npm으로 Contentful 설치
    https://www.npmjs.com/package/contentful
  • Contentful을 사용하여 데이터 가져오기
  • 데이터 구문 분석 및 표시
    .
    이 샘플은 useEffect를 사용하여 Contentful에서 데이터를 가져오고 content_type를 사용하여 Contentful(easysite)에서 대상을 지정합니다.
  • 아시다시피 any 사용을 피해야 합니다 ㅋㅋ
    .

  • useEffect(() => {
        fetchData();
        // console.log(articles);
      }, [articles]);
    
      const fetchData = async() => {
        try {
          const resp = await client.getEntries ({content_type: 'easysite'});
          setArticles(resp.items as any);
        } catch (error) {
          console.log(error);
        }
      }
    

    .Entry part
    export const Post = ({ article }: IArticle) => {
        // console.log(article);
        const { title, image, description} =article.fields;
        const postDescription = marked(description);
        return (
            <div className="post">
                <h2 className="title">{title}</h2>
                {image && <img className="featuredImage" src={image.fields.file.url} alt={title} title={title} /> }
                <section dangerouslySetInnerHTML={{ __html: postDescription}} />
            </div>
        )
    }
    

    좋은 웹페이지 즐겨찾기