Astroの静的ルーティングとファイルタイプの整理

ファイルタイプで少し混乱することがあったので、公式ドキュメントのルーティングページを参考に確認していく。

静的ルーティング(ファイルベースルーティング)

ファイルベースのルーティングによって、src/pages以下に置いたファイルのパスがほぼそのまま有効なルーティングになる。

ルーティングが有効となるファイルタイプはいくつかあって、例えば/aboutというパスを静的ルーティングで実現するためには以下のようなファイルパスのパターンがある。

  • src/pages/about.astro
  • src/pages/about/index.astro
  • src/pages/about.md
  • src/pages/about/index.md
  • src/pages/about.mdx
  • src/pages/about/index.mdx
  • src/pages/about.html
  • src/pages/about/index.html

またルーティングに含まないのかもしれないが、public以下にHTMLを置いてもパスは有効になる(Astroを使っていてpublic以下にHTMLを置く運用はあまりしないと思うが)

  • public/about/index.html

publicに置いた場合は開発サーバーでは/aboutではなく/about/index.htmlでアクセスしなくてはならないが、ビルド後にデプロイすれば大抵のウェブサーバーでは/aboutでアクセスできるだろう(ビルド後にnpm run previewでも確認できるはず)

MDXインテグレーション

MDXを使う場合は以下のコマンドでMDXインテグレーションを追加してやる必要がある。

npx astro add mdx

手元の環境だと開発サーバー(npm run dev)ではこれをやらなくてもなぜか動いたが、ビルド時(npm run build)にはコンパイル対象にならない。微妙にハマりどころだと思った。

被るファイルがある場合の優先順位

被るファイルがある場合の優先順位はアンドキュメンテッドなので不定と見る。

開発サーバーのときはastroだが、ビルドするとmdの内容が入っていたりする。
開発サーバーでは先に見つかったものを拾い、ビルド時には一番後に見つかったもので上書きしているような気がする。

被っていてもビルド時に警告やエラーは出ないので、単純に被らないように注意するということで。

ページのファイルタイプとサンプルコード

ページとして有効なファイルタイプの特徴を見ていく。

Astroページ

Astroコンポーネントと同じ機能を持つ。

---
// コンポーネントスクリプト(JavaScript)
import Layout from '../layouts/Layout.astro'
const title = "Hello"
const hello = "Hello!"
---
<!-- コンポーネントテンプレート (HTML + JS Expressions) -->
<Layout title={title}>
  {hello}
</Layout>

色々なコンポーネントや他のデータファイル、Markdownファイルなどの内容を使ってページを組み立てたい場合はAstroページを使うといいだろう。
例えばインデックスページなど。

コンポーネントスクリプト内でJavaScriptを書いてコンポーネントをインポートしたり、変数を定義したりできる。

コンポーネントテンプレートではJSXのようにHTMLとJavaScriptを混ぜられる。
JSXとは少し違うところもある(属性やコメントの書き方など)

Markdownページ

慣れ親しんだMarkdownファイル。

---
# フロントマター Front-matter(YAML)
layout: ../layouts/Layout.astro
title: Hello
draft: true
---
<!-- Markdown -->
Hello!

AstroではMarkdownのフロントマターでlayoutを指定できる。
レイアウトの中にHTMLの文章がはまればよい、というなシンプルで文章が主体なページではMarkdownを使うといいだろう。

Markdownで記事を書いていけば簡単なブログ的なサイトはすぐ作れる。

本文内でAstroコンポーネントを使ったりフロントマターの値を使うことはできない(HTMLのscriptタグを使ってAstro由来ではないJavaScriptを埋め込むことはできる)

draftをtrueにするとそのファイルはビルドされない。
しかしAstro.globでは引っかかって来るので、インデックスページやレイアウト内でページ一覧を生成している場合には注意が必要。

フロントマターはfrontmatterという名前でレイアウトに渡されるので、レイアウトからはフロントマターの内容を利用できる(frontmatter.titleのようにアクセスする)

Markdownはページとしてそのまま使うのではなく、Astroコンポーネントからインポートして使うこともできる。その場合はsrc/pagesとは別の適当な場所に置く(コンテンツコレクションとして扱うならsrc/content以下に置く)

MDXページ

Markdownを拡張して本文内でJSXを使えるようにしたフォーマットがMDX。

---
# フロントマター Frontmatter(YAML)
layout: ../layouts/Layout.astro
title: Hello
hello: Hello!
---
{/* JavaScript */}
export const hellowello = 'hellowello'
import Greet from '../components/Greet.astro';

<!-- Markdown -->
<Greet>
  {frontmatter.hello}
</Greet>

本文内でJavaScriptを書いたり、インポートしたコンポーネントを使ったり、普通にMarkdownを書いたりできる。
フロントマターの内容を本文内で直接使えたりもする。

Markdownに比べて互換性は下がる(MDXの実装がないツールには持っていきにくくなる)
また非プログラマーにはけっこう書くハードルが高い。
考えなしに使うとカオスになるのが目に見えているので上級者向けな気がする。

ただ文書内にリッチな要素を組み込みたいと思うとMarkdownの表現力では物足りなく感じることも事実なので、そういうケースではMDXは検討の価値がある。
特にもしMarkdownの中にHTMLをたくさん書いているようなら、MDXにした方が幸せになれるかもしれない。

MDXはMarkdownと同様にページとしてそのまま使うのではなく、Astroコンポーネントからインポートして使うこともできる。その場合はsrc/pagesとは別の適当な場所に置く(コンテンツコレクションとして扱うならsrc/content以下に置く)

参考: Markdown を拡張する MDX はドキュメント作成の新たな可能性?

HTMLページ

単純なHTMLによるページ。

<html>
  <head>...</head>
  <body>Hello!<body>
</html>

HTMLコンポーネントと同様にほとんどAstroだからという機能は持たない。レイアウトも使えない。

既存のサイトからの移植作業など特殊なケースで使われる(つまり基本的には使わない)

必要ならばHTMLもAstroコンポーネントからインポートしてHTMコンポーネントとして利用することができる。その場合はsrc/pagesとは別の適当な場所に置く。