Gatsbyでブログ構築(3) 2021.06.03
ディレクトリとパスの変更
チュートリアルから発展させてカスタマイズした内容。
記事ページのMarkdownファイルをsrc/posts
ディレクトリに移動して、サイト上では/posts/<slug>
で表示されるようにする。
Markdownファイルの場所を変更するにはgatsby-node.js
でslug
生成時のbasePath
を変更。
表示URLにプレフィックスを入れるのは、node生成時にslug
を改変するのが簡単でよさそう。
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === 'MarkdownRemark') {
+ const slug = createFilePath({ node, getNode, basePath: 'posts' })
- const slug = createFilePath({ node, getNode, basePath: 'pages' })
createNodeField({
node,
name: 'slug',
+ value: `/posts${slug}`,
- value: slug,
})
}
}
タグを使えるようにする
公式のとおり。
デザインフレームワーク
気になっていたtailwindcssを使ってみる。公式にGatsbyへの導入方法が案内されている。
基本的なタイポグラフィ
はじめはtypography.jsにしようとしたが、head内の読み込み順の関係か、scaleRatioで設定した見出しスタイルがtailwindに上書きされて消えてしまう。
かわりにtailwindcss-typographyを使ってみる。
prose
というクラスをつけるとよしなにしてくれるので、これをlayout.js
のmain
要素に指定。prose
クラスにmax-width
が指定されていて、レイアウトが崩れるので少しハマった。
...
const Layout = ({ pageTitle, children }) => {
...
return (
+ <main className="prose">
...
</main>
)
}
export default Layout
カスタマイズの方法が一見よくわからず難儀したが、基本はtailwind.config.js
のtheme.extend.typography.DEFAULT.css
で上書きできる。デフォルトは https://github.com/tailwindlabs/tailwindcss-typography/blob/master/src/styles.js で設定されている。
画像の扱い
Gatsbyにロックインしてしまうのが気になるので、いったん保留。しばらくは記事内に画像を使わないことにする。
syntax highlighting
書いてあるとおり。
Twilightテーマを使うと文中のcode
の表示が死ぬのでnoInlineHighlight: true
とした。
フォント
日本語の本文は変更しない。英文はGoogle FontsのOverpassがテクニカルな印象で気に入ったので採用。monospace
もOverpass Monoにしたかったが、ウェイトの調整が思い通りにならないのでSource Code Proにした。
Gatsbyでは通常、<body>
より上位の構造は隠されているが、.cache/default-html.js
をコピーしてsrc/html.js
に置くと自分でコントロールできるので、Google Fontsの指定タグを追加する。
<html {...props.htmlAttributes}>
<head>
<!-- ... -->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Overpass:wght@300&family=Source+Code+Pro&display=swap" rel="stylesheet" />
</head>
<!-- ... -->
</html>
CSSのほうはtailwind.config.js
で指定。
const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
theme: {
fontFamily: {
'sans': ['Overpass', ...defaultTheme.fontFamily.sans],
'mono': ['"Source Code Pro"', ...defaultTheme.fontFamily.mono],
},
},
}
これだけだと、code highlightingの部分は変わらないので、styles/global.css
でtailwindcssのディレクティブを使ってスタイルを上書き
@tailwind base;
@tailwind components;
@tailwind utilities;
/* ... */
.gatsby-highlight pre,
.gatsby-highlight code,
.gatsby-highlight span {
@apply font-mono !important;
@apply font-light !important;
}
もっといい方法があるかもしれないが、とりあえず変更できた。VSCodeのデフォルトのリンターはtailwindcssのディレクティブ記法を許してくれないので、あとでなんとかしたい。
description
meta descriptionを入れる。react-helmet
を導入済みなので、meta
要素を追加した。
descriptionについてはオプショナルにしたかったが、なにもせずにいきなりクエリでdescriptionを要求するとエラーになる。
ERROR #85923 GRAPHQL
There was an error in your GraphQL query:
Cannot query field "description" on type "MarkdownRemarkFrontmatter".
とりいそぎ解決したいなら最低1つのエントリーにそのフィールドを追加せよ、とのこと。まあだいたいの記事にdescriptionは必要なので、さしあたってはそれで行く。
- You want to optionally use your field "description" and right now it is not used anywhere. Therefore Gatsby can't
infer the type and add it to the GraphQL schema. A quick fix is to add at least one entry with that field ("dummy
content")
TOCと見出しリンク
gatsby-transformer-remarkを導入済みならば、クエリにtableOfContents
を追加するだけでTOCのHTMLが取れる。DOM決め打ちなのでカスタマイズの範囲は限られる。
export const query = graphql`
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
description
date(formatString: "YYYY.MM.DD")
tags
}
+ tableOfContents
}
}
`
すでにリンクになっているが、まだ見出し要素のほうにIDが振られていないので動かない。gatsby-remark-autolink-headersを入れて見出しにIDを振る。
% npm install --save gatsby-remark-autolink-headers
書いてあるとおり。gatsby-remark-prismjsを導入しているときは指定順に注意する必要がある。
アンカーリンクで見出しにジャンプするとき固定ヘッダの高さを考慮する
見出しが固定ヘッダの下に突っ込んでしまう。
gatsby-remark-auto-headersのoffsetY
というオプションがそれっぽいが、これはいまのところ動かないようだ。何のオフセットなのかもよくわからない。
CSSだけで、このような指定で実現できた。
:target::before {
content: "";
display: block;
height: 40px;
margin-top: -40px;
}
この方法だと、ターゲットしている見出しだけアイコンが浮いてしまうので、gatsby-remark-autolink-headersのスタイルを上書きして、浮いている分を調整した。
:target a.anchor.before {
top: 40px !important;
}