Counts the Clouds

Gatsbyでブログ構築(2)
2021.06.02

JavaScript
Gatsby
GraphQL
Markdown
React

Your first GraphQL query

前:Gatsbyでブログ構築

最新のチュートリアルは書きかけなので、ここからはv2のチュートリアルですすめる。

page queryはビルドタイムでソースコードを解析してGraphQLのクエリを実行しpropsに流し込んでくれる。

gatsby-config.jssiteMetadataをAboutページに適用する。

  import * as React from 'react'
  import Layout from '../components/layout'
+ import { graphql } from 'gatsby'
+ const AboutPage = ({ data }) => {
    return (
+     <Layout pageTitle={`About ${data.site.siteMetadata.title}`}>
        <p>Hi there! I'm the proud creator of this site, which I built with Gatsby.</p>
      </Layout>
    )
  }
+ export const query = graphql`
+   query {
+     site {
+       siteMetadata {
+         title
+       }
+     }
+   }
+ `
  export default AboutPage

Use a StaticQuery

StaticQueryはuseStaticQueryフックを使用して、ページコンポーネントでなくてもGraphQLクエリでデータを取得できる。

gatsby-config.jssiteMetadataをレイアウトコンポーネントに適用してみる。

  import * as React from 'react'
+ import { graphql, useStaticQuery, Link } from 'gatsby'
  import {
    container,
    heading,
    navLinks,
    navLinkItem,
    navLinkText
  } from './layout.module.css'
  const Layout = ({ pageTitle, children }) => {
+   const data = useStaticQuery(
+     graphql`
+       query {
+         site {
+           siteMetadata {
+             title
+           }
+         }
+       }
+     `
+   )
    return (
      <main className={container}>
        <title>{pageTitle}</title>
        <nav>
          <ul className={navLinks}>
            <li className={navLinkItem}>
              <Link to="/" className={navLinkText}>
+               {data.site.siteMetadata.title}
              </Link>
            </li>
            <li className={navLinkItem}>
              <Link to="/about" className={navLinkText}>
                About
              </Link>
            </li>
          </ul>
        </nav>
        <h1 className={heading}>{pageTitle}</h1>
        {children}
      </main>
    )
  }
  export default Layout

Source Plugin

Markdownファイルを記事にするため、ファイルシステムをデータソースにするgatsby-source-filesystemを追加。

% npm install gatsby-source-filesystem

gatsby-config.jsにプラグイン指定を追加。

  module.exports = {
    siteMetadata: {
      title: "Pandas Eating Lots",
    },
    plugins: [
+     {
+       resolve: `gatsby-source-filesystem`,
+       options: {
+         name: `src`,
+         path: `${__dirname}/src/`,
+       },
+     },
      "gatsby-plugin-gatsby-cloud"
    ],
  };

GraphQLのIDEがhttp://localhost:8000/___graphqlにホスティングされているのでアクセスするとクエリを試すことができる。

左カラムの“Explorer”でほしい値にチェックを入れる。fileallFileをクリック。

中央カラムがクエリのプレビュー。command + Enterするか“▶”をクリックすると右カラムに結果が表示される。

Transformer Plugin

取得したファイルをMarkdownパーサで変換するためgatsby-transformer-remarkプラグインをインストールして設定。

% npm install gatsby-transformer-remark
  module.exports = {
    siteMetadata: {
      title: "Pandas Eating Lots",
    },
    plugins: [
      {
        resolve: `gatsby-source-filesystem`,
        options: {
          name: `src`,
          path: `${__dirname}/src/`,
        },
      },
+     `gatsby-transformer-remark`,
      "gatsby-plugin-gatsby-cloud"
    ],
  };

トップページへMarkdownページのリストを追加する。リンク先となるページはまだない。

  import * as React from 'react'
+ import { graphql } from 'gatsby'
  import Layout from '../components/layout'
  const IndexPage = ({ data }) => {
    return (
      <Layout pageTitle="Home Page">
        <p>I'm making this by following the Gatsby Tutorial.</p>
+       <h4>{data.allMarkdownRemark.totalCount} Posts</h4>
+       {data.allMarkdownRemark.edges.map(({ node }) => (
+         <div key={node.id}>
+           <h3>
+             {node.frontmatter.title}{" "}
+             <span style={{color: '#bbb'}}>
+               — {node.frontmatter.date}
+             </span>
+           </h3>
+           <p>{node.excerpt}</p>
+         </div>
+       ))}
      </Layout>
    )
  }
+ export const query = graphql`
+   query {
+     allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
+       totalCount
+       edges {
+         node {
+           id
+           frontmatter {
+             title
+             date(formatString: "DD MMMM, YYYY")
+           }
+           excerpt
+         }
+       }
+     }
+   }
+ `
  export default IndexPage

変換されたデータからページを生成する

Markdownファイルをsourceとして、実際にページを生成する部分。

gatsby-node.jsを追加。ビルドタイムに1回だけ実行されるGatsby Node APIsと呼ばれるもの。

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)

  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: node.fields.slug,
      },
    })
  })
}

おまけ

Gatsby CloudでカスタムドメインとSSL化も可能。

Gatsby Cloudにドメインを追加して、指定されたレコードをDNSに設定するだけで、Let’s Encryptで自動的にSSL化される。

次:Gatsbyでブログ構築(3)