序
時代はモバイルファーストかもしれないけど、(自分も含めて)対象読者として想定しているエンジニアの大半は、PC で表示する機会が多いと思う。ところがモバイルファーストに割り切っている Gatsby Starter Blog を横長の画面で表示すると、両端の大きなデッドスペース が目立つ。どうしても勿体なく感じてしまう。そしてナビゲーション機能が乏しい点もどうにかしたい。
そこで、ヘッダにナビゲーションメニューを設置し、ページのメイン領域を 2 カラムレイアウトにして、横の余白に記事の目次やら何かしらのウィジェットを配置するようにしたい。PC ファースト(笑)とは言え、もちろんレスポンシブ対応はする。
前提条件
既に React-Bootstrap が適用済みである事を前提とする。適用方法は こちらの記事 で説明している。Gatsby Starter Blog を利用しているが、他のスタータでも大きな違いはないはず。
ナビゲーションメニュー
幅が狭い画面ではハンバーガーメニューが表示されるようにする。ウィンドウの上方にスティッキーにするのは迷ったけど、画面が狭くなるから今回は止めた。
実装
ナビゲーションメニューは React-Bootstrap の NavBar コンポーネントと、Nav コンポーネントを組み合わせて実装する。
<Navbar bg="light" expand="lg" className="mb-5">
<Container>
<Link to="/" className="navbar-brand">
<StaticImage
src="../images/favicon_io/favicon-32x32.png"
width={32}
height={32}
formats={["auto", "webp", "avif"]}
className="d-inline-block align-top me-2"
quality={95}
alt=""
/>
{siteTitle}
</Link>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="ms-auto">
<Nav.Item>
<Link to="/tags/react/" className="nav-link">
React
</Link>
</Nav.Item>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
Gatsby の StaticImage コンポーネントを利用して、ロゴを挿入している。また、Navbar.Toggle コンポーネントと Navbar.Collapse コンポーネントによって、レスポンシブ対応している。
ポイント
ここでいちばん大切なのは、リンクの貼り方だ。React-Bootstrap の Navbar.Brand
コンポーネントと Nav.Link
コンポーネントを利用せず、代わりに 内部リンクに最適化 された Gatsby Link コンポーネントを利用するようにする。<Link to="/about/" className="nav-link">...
のように、Bootstrap のクラスを指定しすれば良い。
カラムレイアウト
幅によってレスポンシブに、2 カラムになったり 1 カラムになったりする、お馴染みのレイアウトを構成する。右側のサイドバーにはプロフィールとタグ一覧のウィジェットを表示する。
横方向の広さが命の数式にも、出来る限り支障をきたさないように、ある程度の横幅が確保できるまで 1 カラムを維持する。
実装
React-Bootstrap のグリッドシステム を利用して、Layout コンポーネント (src/components/Layout.js) を実装する。レスポンシブに変化する境界を lg
として、出来る限りメイン領域の幅を広めに確保するようにしている。
<Container>
<Row>
<Col lg={8}>
<main>{children}</main>
</Col>
<Col lg={4}>
<Bio />
<Tags />
</Col>
</Row>
<footer className="py-4">
© {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.com">Gatsby</a>
</footer>
</Container>
タグ一覧ウィジェット
サイドバーに表示するタグ一覧ウィジェット Tags コンポーネント(src/components/Tags.js)を作成する。Gatsby のカスタマイズ - マークダウン記事のタグ機能 のタグの一覧表示と同じ要領で簡単にできる。
const Tags = () => {
const data = useStaticQuery(graphql`
query {
allMarkdownRemark(limit: 2000) {
group(field: frontmatter___tags) {
fieldValue
totalCount
}
}
}
`);
return (
<div className="mb-4 p-3 bg-light">
<h2>Tags</h2>
<ul className="m-0 list-unstyled">
{data.allMarkdownRemark.group.map((tag) => (
<li key={tag.fieldValue}>
<Link to={`/tags/${kebabCase(tag.fieldValue)}/`}>
{tag.fieldValue} ({tag.totalCount})
</Link>
</li>
))}
</ul>
</div>
);
};