K1ファクトリー
WordPressをヘッドレスCMSとして利用してNext.jsで表示(GraphQL編)

WordPressをヘッドレスCMSとして利用してNext.jsで表示(GraphQL編)

前回は REST APIを使い、
ヘッドレスCMS化したWordPressのブログを表示してたのですが、
今回は GraphQLを使って表示してみます。
GraphQLというと、同じReactの Gatsby みたいでですね。

まずは WordPressにて「WPGraphQL」プラグインをインストールします。


queri(クエリ)を使って表示するものを指定してるんですね。
※ちなみにクエリって、検索キーワードとか、
データベースからデータを抽出したり操作したりといった処理を行うための命令のことだそうです。

ところで、WordPressでGraphQLを扱う際には、
Apollo Clientとかいうライブラリを使うといいみたいなことをネットでみるのですが、
まだ不勉強なので、とりあえず、それを使わずにやってみました。

海外のYoutubeで説明されてたので、それを参考にしています。
Getting Started with Headless WordPress with NEXTJS & WPGRAPHQL
この方のGithubにソースがあります。


pages/index.js ブログ一覧ページ

import Link from 'next/link'

// HTML出力部分
export default function Home({ posts }) {
 return (
  <div>
   {posts.nodes.map(post => {
    return (
     <ul key={post.slug}>
      <li>
       <Link href={`/posts/${post.slug}`}>{post.title}</Link>
      </li>
     </ul>
    )
   })}
  </div>
 )
}

// getStaticProps関数でコンテンツを取得する
export async function getStaticProps() {
 const res = await fetch(process.env.WORDPRESS_GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
   query: `
     query HomePageQuery {
      posts {
       nodes {
        slug
        title
       }
      }
     }
    `,
  })
 })

 const json = await res.json()

 return {
  props: {
   posts: json.data.posts,
  },
 }
}


以下の部分が、WPGraphQL プラグインで取得したクエリですね。

query HomePageQuery {
 posts {
  nodes {
   slug
   title
  }
 }
}



①でクエリを指定します。
posts > nodes > slug, title 欲しい情報をチェックします。

②クエリがツリー形式で表示されます。

③再生ボタンを押すと、④内容が表示されます。これでチェックです。

②の部分をコピペして貼り付けたのが上のクエリですね。

それと、GraphQLでもエンドポイントを指定する必要があって、
それは、REST APIとは違い、WPGraphQLプラグインの設定画面を見ればわかります。
http://wordPressのURL/graphql となっています。

process.env.WORDPRESS... のところですね。
.envファイルで http://wordPressのURL/graphql を指定しています。
.envファイルにて、WORDPRESS_GRAPHQL_ENDPOINTを設定、読み込んでます。



次にブログ個別詳細ページです。
pages/posts/[slug].js

import Image from 'next/image'
import Link from 'next/link'

export default function Post(data) {

 const post = data.post;

 return (
  <div>
   <h1>{post.title}</h1>
   {post.featuredImage && <Image src={post.featuredImage.node.sourceUrl} width={1600} height={600} />}
   <article dangerouslySetInnerHTML={{ __html: post.content }}></article>
   <Link href="/">Back</Link>
  </div>
 )
}

// getStaticProps関数
export async function getStaticProps(context) {
 const res = await fetch(process.env.WORDPRESS_GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
   query: `
    query SinglePost($id: ID!, $idType: PostIdType!) {
     post(id: $id, idType: $idType) {
      title
      slug
      content
      featuredImage {
       node {
        sourceUrl
       }
      }
     }
    }
   `,
   variables: {
    id: context.params.slug,
    idType: 'SLUG'
   }
  })
 })

 const json = await res.json()

 return {
  props: {
   post: json.data.post,
  },
 }
}

// getStaticPaths関数
export async function getStaticPaths() {
 const res = await fetch(process.env.WORDPRESS_GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
   query: `
    query AllPostsQuery {
     posts {
      nodes {
       slug
       content
       title
       featuredImage {
        node {
         sourceUrl
        }
       }
      }
     }
  	}
   `
  })
 })

 const json = await res.json()
 const posts = json.data.posts.nodes;

 const paths = posts.map((post) => ({
  params: { slug: post.slug },
 }))

 return { paths, fallback: false }
}

getStaticProps関数、getStaticPaths関数、
それぞれで、クエリを取得しています。

HTML is loading comments...