4. Astroファイル
この章ではAstroファイルが普通のHTMLファイルと何が違うのかを解説します。
4.1 styleタグを使ったCSSの適用
前章でAstroファイルはHTMLファイルと同じものであると解説しました。そのためstyleタグを使ってCSSを適用することも、通常のHTMLファイルと同様にできます。
試しにsrc/pages/index.astroの</body>の直前にstyleタグを追加してみましょう。
<style> h1 { color: royalblue; } </style>ブラウザで確認すると、「Astroからこんにちは」が青色になっていることがわかります。

4.2 scriptタグの記述とJavaScriptの実行
同様に、scriptタグを使いJavaScriptを実行することもできます。
試しにsrc/pages/index.astroを次のように書き換えてみましょう。
<html lang="ja"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Astro</title> </head> <body> <h1>Astroからこんにちは</h1> <button id="test">こんにちは</button> <ul> <li><a href="/about">自己紹介</a></li> </ul> <h2>ブログ</h2> <ul> <li><a href="/blog/yadosai">やどかり祭に行ってきた</a></li> </ul> <script> const testButton = document.getElementById("test") testButton?.addEventListener("click", () => alert("JavaScriptからこんにちは")) </script> <style> h1 { color: royalblue; } </style> </body></html>実際にボタンをクリックするとアラートが表示されることがわかります。このように、scriptタグ中に記述したJavaScriptはページを訪れた人のブラウザで実行されます。

しかし、Astroファイル中に記述したscriptタグは通常のHTMLファイルと異なりデフォルトでTypeScriptを使うことができるので、型の恩恵を受けることができます。例えば次のようにnumber型にstringを代入しようとするようなTypeScriptをscriptタグ内に記述するとエディターがエラーを表示します。
let i: number = "こんにちは";
4.3 フロントマター
Astroファイルの一番上には---で囲まれたフロントマターと呼ばれる領域を書くことができます。
---// ここがフロントマター---
<html>...フロントマターにもJavaScript(TypeScript)を書くことができます。また、フロントマターで定義した変数は{}を使ってHTMLの中で展開することができます。
試しにsrc/pages/about.astroを次のように書き換えてみましょう。
---const name = "筑波太郎";---
<html lang="ja"> <head> <meta charset="utf-8" /> <title>{name + "の自己紹介"}</title> </head> <body> <h1>{name}の自己紹介ページ</h1> <a href="/">トップに戻る</a> </body></html>ブラウザで/aboutを確認すると、h1に「筑波太郎の自己紹介ページ」と表示されているはずです。nameの値を変えるとtitleとh1の両方が一度に変わることを確認してみましょう。

ではなぜ、フロントマターとscriptタグの両方にJavaScriptを書くことができるのでしょうか?それは、実行されるタイミングが異なるからです。
Astroはサイトを公開する前に、bun run build コマンドで.astroファイルをブラウザが読み込める純粋なHTMLファイルへ変換します。これが上の図で示しているビルドという処理です。フロントマターに書いたJavaScriptはこのビルド時に実行され、変数の値はHTMLに埋め込まれます。フロントマター自体は最終的なHTMLファイルには含まれません。

一方、scriptタグに書いたJavaScriptは最終的なHTMLファイルにそのまま含まれるため、実際にページを開いたブラウザ上で実行されます。
実際にフロントマターとscriptタグの実行タイミングの違いを確かめてみましょう。about.astroを次のように書き換えてみてください。
---const name = "筑波太郎";const buildTime = new Date().toLocaleString("ja-JP");---
<html lang="ja"> <head> <meta charset="utf-8" /> <title>{name + "の自己紹介"}</title> </head> <body> <h1>{name}の自己紹介ページ</h1> <p>最終更新: {buildTime}</p> <a href="/">トップに戻る</a> <script> console.log("表示日時:", new Date().toLocaleString("ja-JP")); </script> </body></html>実行タイミングの違いを確かめるために、一度ビルドしてプレビューサーバーで確認してみましょう。bun run dev を停止し、次のコマンドを順番に実行してください。1
bun run buildbun run previewbun run build が上の図の変換処理を行い、bun run preview はそのビルド済みのファイルをそのまま配信するサーバーです。表示されたURLにアクセスして /about を開き、ページをリロードしてみてください。ページに表示されている「最終更新」の日時は変わらないのに、ブラウザの開発者ツールのコンソールに出力される日時はリロードのたびに変わることがわかります。フロントマターの buildTime はビルドした時点で確定し、scriptタグの new Date() はページを表示するたびにブラウザで実行されるからです。

確認できたら bun run preview を停止(q + Enter またはCtrl+C)し、次の章からも引き続き使うために再度 bun run dev で開発サーバーを起動しておきましょう。
bun run dev{}にはJavaScriptの式であれば何でも書くことができます。これを活かして、配列のデータからHTMLの要素を自動生成することもできます。
前の章で作ったsrc/pages/blog/yadosai.astroには、タグを<ul>・<li>で並べていました。タグが増えるたびに<li>を追加する必要があります。ここでフロントマターを使ってこれを書き換えてみましょう。
---const tags = ["筑波大学", "学園祭", "やどかり祭"];---
<html lang="ja"> <head> <meta charset="utf-8" /> <title>やどかり祭に行ってきた</title> </head> <body> <h1>やどかり祭に行ってきた</h1> <p>投稿日: 2026/5/29</p> <ul> {tags.map((tag) => <li>{tag}</li>)} </ul> <h2>概要</h2> <p>やどかり祭の感想などがあれば書いてみましょう</p> <h2>感想</h2> <p>ここにも感想を書いてみましょう</p> <a href="/">トップに戻る</a> </body></html>表示は変わりませんが、タグの追加・削除がtags配列の変更だけで済むようになりました。
tags.map((tag) => <li>{tag}</li>) のmapは、配列の各要素を別の値に変換するメソッドです。(tag) => <li>{tag}</li> はアロー関数で、「tagを受け取り、<li>{tag}</li>に変換する」という処理を表しています。
["筑波大学", "学園祭", "やどかり祭"] ↓ map[<li>筑波大学</li>, <li>学園祭</li>, <li>やどかり祭</li>]この変換結果をAstroが<ul>の中に並べて出力します。

Footnotes
-
bun run dev(開発サーバー)はファイルを保存するたびに即座に変更を確認できる便利なツールですが、ページへのアクセスのたびに再レンダリングを行うため、フロントマターも毎回実行されます。そのためbuildTimeの値がリロードのたびに変わってしまい、ビルド時に1回だけ実行されるという挙動を確認できません。 ↩