1. 経緯
あくまで趣味の範囲だが、自分の音楽活動をまとめたページが欲しいなと思った。
関わった作品をまとめていればアピールしやすくなるし、何より実績として見える形にしておくと自信につながるからだ。
2. Gatsby+NetlifyCMSを採用した理由
WordPressで作る方法などもあったが、どれも自分には未知の世界だった。それならReactには馴染みがあるので、Reactつながりで話題のGatsbyに触れてみようと思ったのがきっかけだった。正直静的サイトジェネレータじゃなくても(ry
あとはブログっぽく更新が出来た方がいいので、NetlifyCMSで気軽に更新できるようにした。
3. 構築
Gatsbyのstarterを少しいじるだけで構築できる。
3-1. Gatsby
3-1-1. インストール
npm install -g gatsby-cli
で、Gatsbyのインストールができる。
gatsby new gatsby-starter-netlify-cms https://github.com/netlify-templates/gatsby-starter-netlify-cms
とし、テンプレートから制作を開始した。
あとはMarkdownにiframeを読み込むプラグインを入れる(Youtubeを埋め込んだりしたいので)。
npm i -S gatsby-remark-responsive-iframe
プラグインの設定をgatsby-config.jsから行う。
{
resolve: `gatsby-transformer-remark`,
options: {
// CommonMark mode (default: true)
commonmark: true,
// Footnotes mode (default: true)
footnotes: true,
// Pedantic mode (default: true)
pedantic: true,
// GitHub Flavored Markdown mode (default: true)
gfm: true,
// Plugins configs
plugins: [`gatsby-remark-responsive-iframe`],
},
},
{
3-1-2. Markdownをページに変換する
Markdownファイルをページに変換するためにgatsby-node.jsを編集する。
// gatsby-node.js
/**
* Implement Gatsby's Node APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/node-apis/
*/
const _ = require('lodash');
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
// You can delete this file if you're not using it
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions
return graphql(`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
id
fields {
slug
}
frontmatter {
title
category
templateKey
}
}
}
}
}
`).then(result => {
if (result.errors) {
result.errors.forEach(e => console.error(e.toString()))
return Promise.reject(result.errors)
}
const posts = result.data.allMarkdownRemark.edges
posts.forEach(edge => {
const id = edge.node.id
const templateKey = edge.node.frontmatter.templateKey;
if(templateKey !== 'live-page'){
createPage({
path: edge.node.fields.slug,
component: path.resolve(
`src/templates/${String(templateKey)}.js`
),
// additional data can be passed via context
context: {
id,
},
})
}
})
let category = []
posts.forEach((edge) => {
if (_.get(edge, `node.frontmatter.category`)) {
category = category.concat(edge.node.frontmatter.category)
}
})
category = _.uniq(category)
category.forEach((cat) => {
const categoryPath = `/works/${cat}/`
createPage({
path: categoryPath,
component: path.resolve(`src/templates/category.js`),
context: {
category: cat,
},
})
})
})
}
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
const parent = getNode(node.parent)
createNodeField({
node,
name: 'collection',
value: parent.sourceInstanceName,
})
}
}
GraphQLで取得して、createPageでページを作成する。その際、frontmatterでどのページのものかを判別し、テンプレートを決定する。こうすることで、Markdownファイルをページとしてビルドできる。
また、works以下にバンドごとの一覧ページを作成するため、categoryでもcreatePageする。gatsby-starter-netlify-cmsのtagsの実装を参考に書いた。
3-1-3. テンプレートを作成する。
例えばworksのページだと以下のような感じ。
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/Layout'
import Cover from '../components/Cover'
import { HTMLContent } from '../components/Content'
export const WorksPostTemplate = ({title,content}) => {
return (
<Layout>
<Cover>
<h2>{title}</h2>
<HTMLContent content={content}/>
</Cover>
</Layout>
)
}
const WorksPost = ({data}) => {
const { markdownRemark: post } = data;
return (
<WorksPostTemplate title={post.frontmatter.title} content={post.html}/>
)
}
export default WorksPost
export const pageQuery = graphql`
query worksPost($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
title
}
}
}
`
3-2. NetlifyCMS
3-2-1. NetlifyCMSから更新するページ
NetlifyCMSから更新したいページはstatic/admin/config.yamlを編集して、Markdownの構造を記述する必要がある。
collections:
- name: "works"
label: "Works"
folder: "src/pages/works"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "works-post"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Description", name: "description", widget: "string", required: false}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Category", name: "category", widget: "string"}
- {label: "Image", name: image, widget: image, required: false}
- {label: "ImageUrl", name: imageUrl, widget: string, required: false}
- name: "live"
label: "Live"
folder: "src/pages/live"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "live-page"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Body", name: "body", widget: "markdown"}
- name: "pages"
label: "Pages"
files:
- file: "src/pages/info/index.md"
label: "Info"
name: "info"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "info-page"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Body", name: "body", widget: "markdown"}
- file: "src/pages/profile/index.md"
label: "Profile"
name: "profile"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "profile-page"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Image", name: "image", widget: "image", required: false}
- {label: "Body", name: "body", widget: "markdown"}
aboutページとprofileページは単一のページとしてpages以下に、worksページとliveページはブログポストページとしてそれぞれworksとliveに記述する。
4. 完成

ちなみに背景画像は以前撮った夕暮れの写真をSnapSeedというアプリでサクッと加工した。案外雰囲気は出たと思う。
5. まとめ
GatsbyはReactに触れたことがある人ならスムーズに開発を行えると感じた。ページのルーティングもそこそこ速い。難点があるとすればNetlifyCMSからの更新の反映に若干の遅延があることくらいだと思う。