みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Apollo Clientを使ってShopifyのブログ記事一覧を取得しNext.jsで表示する(GraphQL編) 📝

先日、自前でAPIを用意してShopifyのブログ記事一覧を取得しましたが、前回、商品一覧を取得する際にGraphQLの使いかたを学んだので、GraphQLで書き換えてみます。

blog.kimizuka.org
blog.kimizuka.org

手順

プライベートアプリを用意して、ストアフロントAPIのアクセストークンを取得する

毎回のことですが、ストアフロントAPIのアクセストークンが必要になるので取得します。

blog.kimizuka.org

  1. プライベートアプリを用意する
  2. ストアフロントAPIを有効にする
  3. 商品、バリエーション、コレクションを読み込むの権限を付与する
  4. ストアフロントのアクセストークンを控える

と、こちらの手順通り進めましょう。

コードを書く

src/pages/graph-ql-blog-list-page.tsx

import gql from 'graphql-tag';
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';

type Data = {
  articles: {
    edges: {
      cursor: string;
      node: {
        blog: {
          title: string;
        };
        title: string;
      };
    }[];
  };
};


export default function GraphQlBlogListPage({ data }: {
  data: Data;
}) {

  return (
    <ul>
      { data.articles.edges.map(({ node }, i) => <li key={ i }>{ node.title } - { node.blog.title }</li> ) }
    </ul>
  );
}

export async function getStaticProps() {
  const httpLink = createHttpLink({ uri: `https://${ process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN }/api/graphql` });
  const middlewareLink = setContext(() => ({
    headers: {
      'X-Shopify-Storefront-Access-Token': process.env.NEXT_PUBLIC_SHOPIFY_STORE_FRONT_ACCESS_TOKEN || ''
    }
  }));
  const client = new ApolloClient({
    link: middlewareLink.concat(httpLink),
    cache: new InMemoryCache(),
  });  
  const { data } = await client.query({
    query: gql`{
      articles(first: 250 reverse: true) {
        edges {
          node {
            cursor
            blog {
              title
              id
            }
            title
            content
            excerptHtml
          }
        }
      }
    }`
  });

  return {
    props: {
      data
    }
  };
}


前回同様、importはしていませんが、graphqlも必要になるので、

yarn add graphql graphql-tag apollo-client apollo-link-http apollo-link-context apollo-cache-inmemory

と、必要なモジュールをaddしておく必要があります。

クエリの書き方はこちらにまとまっていました。

ブログを跨いで記事を取ってくるので若干の戸惑いがありました。
引数でblog_idを渡して絞り込むことができれば便利だと思うのですが、それはできないみたいなので、特定のブログ記事のみを表示したい場合は、値の取得後にblogのid(今回は取得せず)か、titleでフィルターを掛ける必要があります。

また、自前APIで取得したときは251件目以降をどうやって取得するか悩みましたが、GraphQLのArticleは引数でafterを渡せるので、返ってきたcursorをafterに渡すことで、それ以降の記事を取得することができます。便利です。

ページングに関してはこちらに詳しくまとまっています。

shopify.dev