Gatsbyでブログ構築(2) 2021.06.02
Your first GraphQL query
最新のチュートリアルは書きかけなので、ここからはv2のチュートリアルですすめる。
page queryはビルドタイムでソースコードを解析してGraphQLのクエリを実行しprops
に流し込んでくれる。
gatsby-config.js
のsiteMetadata
を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.js
のsiteMetadata
をレイアウトコンポーネントに適用してみる。
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”でほしい値にチェックを入れる。file
やallFile
をクリック。
中央カラムがクエリのプレビュー。command + Enter
するか“▶”をクリックすると右カラムに結果が表示される。
- デフォルトでExplorerに
file
やallFile
が存在していたので、設定済みかもしれないと思って上記の手順を行ってみたが、結果が空なのでプラグインのインストールと設定は必要らしい。
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化される。