1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsのサイトにmicroCMSをAPI接続する

Last updated at Posted at 2021-08-31

今回はこのようなサイト内のニュース欄をmicroCMSを用いて作ります。
デプロイはAWS amplifyでする前提です。image (1).png

microCMSの設定

(1)プロジェクトを作る

image (2).png
image (3).png
個人開発レベルではHobbyで事足りるかと(検証中)。

(2)APIを作成

image (4).png

リスト形式を選択
image (5).png

(3)投稿したい項目を定義

image (6).png

APIで取得したデータをmapで出す

(1)API keyを.envに書き込む

.env.production
NEXT_PUBLIC_API_KEY=your key

keyはこちら
2021_06_30_16_38_33_管理画面_microCMS (1).png
2021_06_30_16_40_27_.env.production_it_feels_it_Visual_Studio_Code (1).png

(2)nextがexport出来るようにする

next.config.js
module.exports = {
  env: {
    MICROCMS_API_KEY: process.env.X_API_KEY,
  },
}

(3)pages/index

componentに書き込んでも、なぜかうまく動作しないので、直接pagesに書き込むことをお勧めします。

pages/index.tsx
import styles from '../styles/Home.module.scss'
import Link from 'next/link'
import React from 'react'
import Moment from 'react-moment'
import Icon from '../components/bases/IconCompo'

export const getStaticProps = async () => {
  const key = {
    headers: { 'MICROCMS-API-KEY': process.env.NEXT_PUBLIC_API_KEY },
  }
  try {
    const news = await (await fetch('https://it-feels-it.microcms.io/api/v1/news', key)).json()
    return {
      props: {
        news: news.contents,
      },
    }
  } catch (error) {
    console.error(error)
  }
}
const Home = ({ menu, news, staff }) => {
  return (
      <div className={styles.news}>
        <p className={styles.title}>ニュース</p>
        <div className={styles.newsContainer}>
          {news.slice(0, 4).map((news) => (
            <Link href={`news/${news.id}`} key={news.id}>
              <div className={styles.item}>
                <tr>
                  <td className={styles.date}>
                    <Moment format="YYYY/MM/DD" style={{ marginRight: 30, color: '#a1a1a1;' }}>
                      {news.date}
                    </Moment>
                  </td>
                  <td className={styles.body}>{news.title}</td>
                </tr>
              </div>
            </Link>
          ))}
        </div>
        <button className={styles.moreContainer}>
          <span>
            もっと見る
            <Icon type="arrowRight" />
          </span>
        </button>
    </div>
  )
}

export default Home

・apiURLはこのページから取得します
2021_06_30_16_40_27_.env.production_it_feels_it_Visual_Studio_Code (2).png

・Momentは、別記事で紹介してます。
・.slice(0,4)は、直近の1番目から4番目までだけを表示します。

(4)CSS

.news {
    text-align: center;
    padding-top: 2%;
    .title {
      font-size: 30px;
      font-weight: bold;
    }
    .newsContainer {
      width: 50%;
      margin: 0 auto;
      border-top: solid 1px #e8e8e8;
      .item {
        width: 100%;
        border-bottom: solid 1px #e8e8e8;
        tr {
          td {
            cursor: pointer;
            padding: 23px;
            font-weight: bold;
            text-align: left;
          }
        }
      }
    }
    .moreContainer {
      margin: 0 auto;
      padding: 20px 0;
      span {
        display: flex;
        justify-content: center;
        align-items: center;
        font-family: 'ten mincho text';
        font-size: 15px;
        font-weight: bold;
        color: #606060;
      }
    }

これで外観は完成したかと思います。

(4)詳細を表示するページを作る

ニュースのタイトルをクリックしたときに、その詳細を表示させるページを作ります。
pages/newsを作成

pages/news/[id].tsx
import styles from './id.module.scss'
import Moment from 'react-moment'

type Props = InferGetStaticPropsType<typeof getStaticProps>

export interface News {
  id: string
  createdAt: string
  updatedAt: string
  publishedAt: any
  revisedAt: string
  title: string
  date: string
  thumbnail?: thumbnailTag
  body: string
}

export interface thumbnailTag {
  url: string
  width: number
  height: number
}
export const getStaticPaths = async () => {
  const key = {
    headers: { 'MICROCMS-API-KEY': process.env.NEXT_PUBLIC_API_KEY },
  }
  const data = await fetch('https://examplerenren.microcms.io/api/v1/news', key)
    .then((res) => res.json())
    .catch((err) => console.warn(err))
  const paths = data.contents.map((content) => `/news/${content.id}`)
  return { paths, fallback: false }
}

export const getStaticProps = async (context) => {
  const id = context.params.id
  const key = {
    headers: { 'MICROCMS-API-KEY': process.env.NEXT_PUBLIC_API_KEY },
  }
  const data: News = await fetch('https://examplerenren.microcms.io/api/v1/news/' + id, key)
    .then((res) => res.json())
    .catch((err) => console.warn(err))
  return {
    props: {
      news: data,
    },
  }
}

const NewsId: NextPage<Props> = ({ news }) => {
  return (
    <div>
          <div className={styles.contents}>
            <h1 className={styles.title}>{news.title}</h1>
            <Moment format="YYYY/MM/DD" className={styles.date}>
              {news.publishedAt}
            </Moment>
            <div className={styles.imgContainer}>
              <img src={news.thumbnail.url} className={styles.thumbnail}></img>
            </div>
            <div
              className={styles.body}
              dangerouslySetInnerHTML={{
                __html: `${news.body}`,
              }}
            />
          </div>
    </div>
  )
}
export default NewsId

これで表示できると思います。
getStaticPropsのところのapiのURLの最後に/を追加するのを忘れないでください。
1日ハマりました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?