なにこれ
GatsbyでWebサイトを作るときに、ブログや職種紹介など2種類以上のマークダウンファイルを管理する場合があると思います。通常だとMarkdownRemarkNodeのfileAbsolutePath
でしか両者のマークダウンファイルを見分ける術がありませんが、ここではもっとスマートなやり方を紹介します。簡単に言うとFileNodeのsourceInstanceName
をMarkdownRemarkNodeに引き継ぐことにより、GraphQLのfilterで簡単に区別できるという方法です。
実装方法
Step1. マークダウンファイルのFleNodeでsourceInstanceNameを定義
マークダウンファイルの読み込み設定はgatsby-config.jsで以下のようにします。
name
を付けることでマークダウンファイルのFileNodeにおいてsourceInstanceName
が設定できます。
gatsby-config.js
module.exports = {
/* (中略) */
plugins: [
/* (中略) */
{
resolve: 'gatsby-source-filesystem',
options: {
// オプションでname(FileNodeにおけるsourceInstanceName)を指定 name: 'posts', path: `${__dirname}/content/posts`,
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
// オプションでname(FileNodeにおけるsourceInstanceName)を指定 name: 'jobs', path: `${__dirname}/content/jobs`,
},
},
'gatsby-transformer-remark',
/* (中略) */
],
/* (中略) */
};
Step2. FileNodeのnameをMarkdownFileNodeに引継ぐ
何もしないとFileNodeのsourceInstanceName
はMarkdownRemarkNodeに引き継がれません。
そのためgatsby-node.js
で引継ぎ処理を実装します。
gatsby-node.js
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
const { createNodeField } = boundActionCreators
// MarkdownRemarkNodeの場合のみ処処
if (node && node.internal && node.internal.type === 'MarkdownRemark') {
// 親のFileNodeを取得して
const parent = getNode(node.parent)
// gatsby-config.jsで設定したFileNodeのsourceInstanceNameを
// MarkdownRemarkのフィールドに引き継ぐ
// 名前はMarkdownRemarkの他プロパティとかぶらないようにcollectionとしている
createNodeField({
node,
name: 'collection',
value: parent.sourceInstanceName,
})
}
};
Step3. GraphQLでnameをもとにマークダウンを区別
GraphQLではcollectionフィールドで、それぞれを区別します。
query {
allMarkdownRemark(
# collectionにて記事のNodeのみ抽出 filter: { fields: { collection : { eq: "posts" } } } ) {
edges {
node {
# (中略)
}
}
}
}
まとめ
簡単ですがGatsbyで良く困る事例の1つを紹介しました。 Gatsbyは多くのフックポイントを設けているので、今回のよう、やろうと思えば結構いろんなことができます🍅
参考
関連記事
Gatsbyバージョンアップ(v2 to v5)
2023/04/06
Gatsbyビルドチューニング ビルド時間を15分から7分に短縮するためのTips 7選
Gatsbyビルドエラー「window is not defined」への対処法
2020/05/23
Gatsby + Netlify + ZapierでRSSリーダーを作る
2019/06/18
Gatsbyにおける外部取得画像へのgatsby-image適用方法
2019/06/02