contact

blog-MainImage

Kabe-Log

2021-09-04

2021-11-11

Next.jsでGraphCMSを使ったブログの作成

Next.js,

frontend,

React.js,

TypeScript,

GraphQL

今回は、GraphCMS を使って Next.js アプリにブログを導入する方法を書いていきます。

GraphCMS とは

名前の通り、GraphQL クエリを使える HeadlessCMS になります。見た目の UI が綺麗で使いやすいです。

ただ、google 日本語翻訳をしたままスキーマを作成したりすると、クラッシュする頻度が多いのがネックです(自分の Macbook だけなのかもしれません...)。

ブログの作成

Next.js の立ち上げ

まずは、create-next-app でプロジェクトを立ち上げます。 「graphcms_blog」の箇所は任意の名前をつけてください。

yarn create next-app graphcms_blog --typescript

そのプロジェクトに移動します。

cd graphcms_blog

yarn dev でプロジェクトを起動しましょう。

graphCMS1.png

localhost:3000 にアクセスしてこの画面が表示されれば OK です。 Next.js の使用経験がある人ならお馴染みのページですね。

GraphCMSで記事の作成

次にブログの記事を GraphCMS で作成します。

プロジェクト作成

こちらでGraphCMSへサインアップします。

https://graphcms.com

サインアップが完了したらプロジェクトを作成しましょう。

graphCMS3.png

新しいプロジェクトを作成します。Blank を選択。

graphCMS4.png

プロジェクト名を任意で入力し、リージョンを Tokyo に指定します。なぜかアジアでは東京リージョンのみ選択できます。

graphCMS5.png

サービスプランを選択します。 個人利用でしたら、「Free forever」を選択。

graphCMS6.png

ここはそのまま。ここで他のユーザーを招待して複数人開発することができます。

graphCMS7.png

この手順通りに行っていきましょう。

ちなみに、右から出てくるアナウンスは普通に閉じるだけでは永遠と出てくるので、表示しないボタンを押しましょう。

今回の記事は簡単に、以下の構成にします。

  • タイトル
  • コンテンツ内容
  • 画像

この時、このタイトル、コンテンツ、画像をまとめた一塊を「Model」といいます。 そして、タイトル、コンテンツ、画像、それぞれを「Schema」といいます。

Model の作成

サイドバーから schema を選択し、create Model を選択。

graphCMS8.png

Display name を入力します。ここでは blog という名前にします。 API ID、Plural API ID は自動で出力されるので、そのままで大丈夫です。 Description は記入は任意になります。

graphCMS9.png

Create Model を選択します。

Schema の作成

次に作成したモデルに Schema を作成していきます。 右側の「Add Fields」から型を選択できます。

一つ目の、タイトルを作成します。

Add Fields から「Single line text」を選択します。 Display name をつけます。ここでは title とします。API ID は自動で付与されます。Description は記入してもしなくても大丈夫です。

graphCMS10.png

Settings の隣の「VALIDATIONS」を選択します。

graphCMS11.png

Settings の隣からバリデーションをかけられるので title は、一番上の Make field required を選択しましょう。 指定することで、この Schema を必須項目にすることができます。 チェックを入れたら、Create を選択しましょう。

他にも、文字数を制限したりなどのバリデーションをかけられるので、気になる人は見てみてください。

タイトルの他も同じように作成していきましょう。

スキーマDisplay namefields必須かどうか
タイトルtitleSingle line text必須
コンテンツcontentmarkdown必須
画像imageAsset picker任意

このような感じになればオッケーです。 graphCMS12.png

また、「Show system Fields」を開くと、自動で作成されるスキーマの一覧が見れます。 「createdAt」を作らなかったのは、既にあるからです。

サイドバーからコンテンツを選択し、create item を押します。

graphCMS13.png

タイトル、コンテンツ内容、画像を作成し、記事を作成します。

緑色の「Save and publish」を選択

graphCMS14.png

画像を公開するか聞かれるのでチェックを入れましょう。

同じようにコンテンツを 4 つほど作成しましょう。

クエリを投げる

Playground でクエリを投げてみましょう。 こちらで、graphql クエリを投げた時の挙動、結果を試すことができるのでかなり便利です。

下記画像のクエリを投げてみましょう。(GlaphQLクエリの記述については今回取り扱いません)

graphCMS15.png

graphCMS16.png クエリが正常に取得できているとこのようになるはずです。

Permissionの編集

サイドバーの setting から「public content API」を選択

「Create permission」を選択

graphCMS17.png

graphCMS18.png read と publish 権限を All にして Create を選択。

最後に API からコンテンツ API をコピーしておきます。

コードの変更

Next.js の project に戻ります。

apollo-clientgraphqlをインストールします。

yarn add @apollo/client graphql

API を.env に記述しましょう。

.env

NEXT_PUBLIC_GRAPHCMS_API=<先ほどコピーしたAPI>

apollo-client の設定を行います。

libs/apollo-client.tsx

import { ApolloClient, InMemoryCache } from "@apollo/client"; const client = new ApolloClient({ uri: process.env.NEXT_PUBLIC_GRAPHCMS_API, cache: new InMemoryCache(), }); export default client;

Next.js では外部から画像を読み込む際はドメインを config に設定する必要があります。 next.config.js で設定していきます。

next.config.js

module.exports = { reactStrictMode: true, images: { domains: ["media.graphcms.com"], }, };

index.tsxの変更

設定が終わりましたので、index.tsx を変更していきます。

pages/index.tsx

import type { NextPage } from "next"; import Image from "next/image"; import Link from "next/link"; import styles from "../styles/Home.module.css"; import client from "../libs/apollo-client”; import { GetStaticProps } from "next"; import { gql } from "@apollo/client"; type Blog = { id: string; title: string; createdAt: string; content: { html: JSX.Element }; image: { url: string }; }; type Props = { data: { blogs: Blog[] }; }; export const getStaticProps: GetStaticProps<Props> = async () => { const { data } = await client.query({ query: gql` query MyQuery { blogs { id createdAt title content { html } image { url } } } `, }); return { props: { data: data, }, }; }; const Home: NextPage<Props> = ({ data }: Props) => { return ( <div className={styles.container}> <main className={styles.main}> <h1 className={styles.title}>GraphCMS Blog</h1> <div className={styles.grid}> {data.blogs.map((value: Blog) => { const d = new Date(value.createdAt); const createdDate = String(d.getFullYear()) + "." + String(("0" + (d.getMonth() + 1)).slice(-2)) + "." + String(("0" + d.getDate()).slice(-2)); return ( <Link passHref key={value.title} href={`/articles/${value.id}`}> <div className={styles.card}> <p>{createdDate}</p> <h2>{value.title}</h2> <Image alt={value.title} src={value.image.url} width={350} height={190} /> </div> </Link> ); })} </div> </main> </div> ); }; export default Home;

createdAt は日付に直します。日付が一桁だった場合は左側に0を追加するように設定します。

今回は、SSG でデータを取得するため、getStaticProps 内でクエリを投げます。

Next.js の getStaticProps のドキュメントはこちら

【Next.js の公式ドキュメント】

console.log で(data)の中を見てみましょう。

graphCMS19.png

しっかりと取得できていることが確認できます。

スタイルの変更

css を変更します。

styles/Home.module.css

.main { padding: 1rem 0; flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; } .title { font-size: 2.5rem; } .grid { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; max-width: 800px; margin-top: 1rem; } .card { margin: 0.5rem; padding: 1rem; text-align: left; color: inherit; text-decoration: none; border: 1px solid #eaeaea; border-radius: 10px; transition: color 0.15s ease, border-color 0.15s ease; width: 45%; } .card:hover, .card:focus, .card:active { color: #0070f3; border-color: #0070f3; } .card h2 { margin: 0 0 0.5rem 0; font-size: 1.5rem; } .card p { margin: 0; font-size: 0.8rem; line-height: 1.0; } @media (max-width: 600px) { .grid { width: 100%; flex-direction: column; } }

このようになればオッケーです。 graphCMS20.png

以上で、graphCMS からデータを表示することができました。お疲れ様でした。

まだ、ページ先の遷移がないので、次回はそちらを作っていきたいと思います。

ではまた。

search

recommended

AWS資格 SAPとSOAを取得したので、対策や受験時の感想について
2022-05-23AWS資格 SAPとSOAを取得したので、対策や受験時の感想について
実務経験一年の転職活動(エンジニア生活:2月)
2022-03-15実務経験一年の転職活動(エンジニア生活:2月)
2022年は、フルスタックエンジニアに(エンジニア生活:1月)
2022-02-072022年は、フルスタックエンジニアに(エンジニア生活:1月)
「AWSエンジニア入門講座――学習ロードマップで体系的に学ぶ」を読んだ感想
2022-01-29「AWSエンジニア入門講座――学習ロードマップで体系的に学ぶ」を読んだ感想
エンジニア転職した一年の振り返り
2022-01-04エンジニア転職した一年の振り返り
Remixと朝活(エンジニア生活:11月)
2021-12-02Remixと朝活(エンジニア生活:11月)

contact