PR
PR

【Astro入門】ディレクトリ構造の解説と共通レイアウト(ひな形)の作り方

記事内に広告が含まれています。

今回は以前構築したPodman + Astroの開発環境を使って、実際にWebサイトのトップページを構築してみます。

前回の記事: https://vpslife.server-memo.net/podman_astro_install/

Astro開発サーバ起動

まずは、作業用のコンテナ(開発サーバー)を起動します。

$ cd ~/project/astro-dev
$ podman-compose up -d

Astroプロジェクトのディレクトリ構造

Astroでは、「src」ディレクトリが、これからWebサイトのページ等を作成していくメインの作業場所となります。

Astroでビルドコマンド(npm run build)を実行すると、この「src」ディレクトリの中身を読み込んで最適化し、本番公開用の最終的なHTMLファイルを作成してくれます。

インストール直後のsrcディレクトリ

インストール直後の「src」ディレクトリ内は、以下のような構造になっていて、役割ごとにディレクトリが分かれています(必要に応じて自分で追加作成します)。

./astro-dev/src/
├── assets/
│   ├── astro.svg
│   └── background.svg
├── components/
│   └── Welcome.astro
├── layouts/
│   └── Layout.astro
└── pages/
    └── index.astro

各ディレクトリの役割を解説します。

src/assets (画像やCSSなど)

画像やCSSファイルを格納する場所です。

ここに置いた画像やCSSファイルは、ビルド時にAstroが自動的にファイルサイズを圧縮したり、ブラウザのキャッシュが効きやすい名前に最適化してくれます。

※プロジェクトの直下にあるpublicディレクトリも画像を格納する場所ですが、あちらはAstroが加工せずにそのまま配信するファイルを格納する場所です。

src/components (部品・コンポーネント)

サイト内で何度も使用する「UIの部品」を格納する場所です。

ヘッダー、フッター、ボタンなどを、それぞれ「.astro」ファイルとして作成しておきます。

src/layouts (レイアウト・ひな形)

ページ全体の大枠(テンプレート)を格納しておく場所です。

HTMLの基本構造(<html>、<head>、<body>)や、全ページ共通のヘッダーやフッターの配置をここで定義しておきます。

src/pages (ページとルーティング)

Webサイトの各ページとなるファイルを作成する場所です。

ここに置いたファイル(.astro、.md、.html など)の構成が、そのままWebサイトのURLになります。

  • src/pages/index.astro localhost:4321/ (トップページ)
  • src/pages/about.astro localhost:4321/about/ (アバウトページ)
  • src/pages/blog/first-post.md localhost:4321/blog/first-post/ (ブログ記事)

src/content(コンテンツコレクション)※新規作成が必要

ブログ記事などMarkdown形式(.md)で書いた記事をまとめて管理する専用のディレクトリです。(初期状態では存在していないので、自分で作成する必要があります)

事前に「スキーマ」と呼ばれるルールの設定書を用意しておくことで、Astroが「記事のタイトルが入力し忘れられていないか」「日付の形式が間違っていないか」などを厳密にチェックしてくれます。

また、この機能を使うと「最新の記事一覧表示」などが非常に簡単に実装できるようになります。

トップページ(index.astro)の編集

それでは、実際に「src/pages/index.astro」ファイルを編集してみます。

$ cd ~/project/astro-dev/src/pages
$ vi index.astro

初期状態で作成されている「index.astro」ファイルを編集し、お約束の「Hello World」を追加してみました。

---
import Welcome from '../components/Welcome.astro';
import Layout from '../layouts/Layout.astro';

// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
---

<Layout>
<h1>Hello World!!</h1>
        <Welcome />
</Layout>

ファイルを保存してブラウザで(http://localhost:4321)を確認すると、リロード(更新)ボタンを押さなくても、保存した瞬間に変更が反映されました!

Astroのホットリロード機能、ちょっと感動しますよね。

トップページを作成する

公式のサンプルコードの動作が確認できたので、今度は中身をすべて消して、自分のブログ用のトップページを1から作成してみます。

Astroファイル(.astro)のコードの仕組み

Astroファイル(.astro)は、大きく2つのパーツで構成されています。

上部(--- で囲まれた部分)

ここは「コンポーネントスクリプト」と呼ばれ、サーバー側で動くJavaScriptやTypeScript(変数の定義など)を書きます。

変数名はJavaScriptの標準的な文化である「キャメルケース」(ペースを使わずに複数の単語を連結し、2語目以降の先頭を大文字にする命名規則)で定義するのが一般的です

今回は「siteName」という変数にサイト名を入れています。

ここの処理結果はブラウザには表示されず、サーバー側(ビルド時)で実行されます。

下部(HTML部分)

実際の画面の骨組みです。

普通のHTMLとほぼ同じですが、上部で作った変数を {siteName} のように波括弧 { } で囲むだけで、簡単に文字をHTML内に埋め込むことができます。

新しいindex.astroの作成

「index.astro」の中身を、以下の内容に書き換えます。

今回はサイト名を「Game Life」として作成してみます。

---
// ここは「コンポーネントスクリプト(Component Script)」と呼ばれる部分です。
// サーバー側で動くJavaScriptやTypeScript(変数の定義など)を書きます。
// 変数名はJavaScriptの標準的な文化である「キャメルケース」を使って変数を定義
const siteName = "Game Life";
const description = "ゲームに関することを書いていきます。";
---

<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <meta name="description" content={description} />
    <title>{siteName}</title>
  </head>
  <body>
    <header>
      <h1>{siteName}</h1>
      <nav>
        <a href="/">ホーム</a>
        <a href="/blog/">ブログ</a>
      </nav>
    </header>

    <main>
      <h2>こんにちは!</h2>
      <p>AstroとPodmanで構築した新しいブログ環境へようこそ。</p>
      <p>ここはトップページ(index.astro)です。これからここに、最新の記事一覧などを表示させていきます。</p>
    </main>

    <footer>
      <p>© 2026 {siteName}</p>
    </footer>
  </body>
</html>

編集し保存すると、内容が即時に反映されます。

ヘッダーとフッターをコンポーネント(部品)化する

次に、全ページの共通で使用する「ヘッダー」と「フッター」部分を切り離して、再利用できるようにコンポーネント(部品)化してみます。

コンポーネント化するための部品は「src/components」ディレクトリに作成します。

ヘッダー作成(Header.astro)

今回は、「src/components/Header.astro」というファイルを作成し、以下のコードを記述します。

---
const siteName = "Game Life";
---

<header>
  <h2><a href="/">{siteName}</a></h2>
  <nav>
    <a href="/">ホーム</a>
    <a href="/blog/">ブログ</a>
  </nav>
</header>

<style>
  /* CSSもここで書けます */
  header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #ccc;
    padding: 10px 20px;
  }
  nav a {
    margin-left: 15px;
    text-decoration: none;
    color: #333;
  }
</style>

フッターの作成 (Footer.astro)

「src/components/Footer.astro」という名前でフッター部分を作成します。

ここでは少し工夫して、Copyrightで表示される「年」を自動で取得する機能をつけてみます。

todayという変数に現在の日付を代入し、「{today.getFullYear()}」で年を取得して表示させています。

---
// サーバーがページを生成した時の「現在の日付」を取得します
const today = new Date();
---

<footer>
  <p>© {today.getFullYear()} Game Life. All rights reserved.</p>
</footer>

<style>
  footer {
    text-align: center;
    padding: 20px;
    margin-top: 40px;
    border-top: 1px solid #eee;
    color: #666;
  }
</style>

index.astroでヘッターとフッターを読み込ませる

作成したヘッダーとフッターの部品を呼び出すように、トップページ(index.astro)を修正します。

上部のコンポーネントスクリプト部分で「import」を使用し、ヘッダーとフッターを読み込ませます。

そして、下部のHTML部分でヘッダー挿入したい部分に「<Header />」、フッターを追加したい部分に「<Footer />」を記述します。

---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';

const description = "ゲームに関することを書いていきます。";
---

<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <meta name="description" content={description} />
    <title>Game life</title>
  </head>
<body>
    <Header />

    <main style="padding: 20px;">
      <h2>こんにちは!</h2>
      <p>AstroとPodmanで構築した新しいブログ環境へようこそ。</p>
      <p>ヘッダーとフッターが「コンポーネント」として分離されました。</p>
    </main>

    <Footer />
  </body>
</html>

これでトップページが作成されました。

<head>部分もコンポーネント化したい

トップページは完成しましたが、<head>部分も全ページほぼ共通の記述になるため、今後を見据えてコンポーネント化してしまいます。

ここで注意が必要なのが、「titleやdescriptionはページによって変更したい」という点です。

トップページなら「Game Life」、ブログ記事なら「記事のタイトル」といったように、中身を動的に変える必要がありますよね。

Astroでは、「Props(プロップス:引数)」という仕組みを使うことで、この点をスマートに解決できます。

BaseHead.astro(<head>部分)を作成

「src/components/」ディレクトリに、「BaseHead.astro」というファイルを以下の内容で作成します。

---
// 「Astro.props」を使って、呼び出し元からデータを受け取ります
const { title, description } = Astro.props;
---

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />

<title>{title}</title>
<meta name="description" content={description} />

index.astroでBaseHeadを読み込ませる

「index.astro」を編集して、BaseHeadの読み込みと<head>部分にBaseHead表示させる設定を追加します。

---
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';

const siteName = "Game Life";
const description = "ゲームに関することを書いていきます。";
---

<html lang="ja">
  <head>
    <BaseHead title={siteName} description={description} />
  </head>
  <body>
    <Header />

    <main style="padding: 20px;">
      <h2>こんにちは!</h2>
      <p>AstroとPodmanで構築した新しいブログ環境へようこそ。</p>
      <p>head部分もコンポーネント化しました!</p>
    </main>

    <Footer />
  </body>
</html>

データの受け渡し(Props)の仕組み

「index.astro」で下記のように記述することで、タイトル(title)と説明文(description)に使用する内容を、コンポーネント(部品)側へパス(渡す)することが出来ます。

 <BaseHead title={siteName} description={description} />

パスされた内容は、「BaseHead.astro」の「Astro.props」で受け取ることができます。

const { title, description } = Astro.props;

共通レイアウト(BaseLayout.astro)を作成する

これまで作成してきた「Header.stro」「Footer.astro」「BaseHead.astro」を1つにまとめた、全ページ共通の雛形(レイアウトファイル)を「src/layouts/」ディレクトリに作成します。

このレイアウトを作成することで、今後はスクリプトコンポーネント部分と数行のコードと本文を書くだけで、新しいページを作成することが出来るようになります。

レイアウトファイル(BaseLayout.astro)を作成

今回は「BaseLayout.astro」という名前でレイアウトファイルを作成していきます。

---
// これまで作った3つの部品をすべて読み込みます
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';

// このレイアウトを使うページからタイトルと説明文を受け取ります
const { title, description } = Astro.props;
---

<html lang="ja">
  <head>
    <BaseHead title={title} description={description} />
  </head>
  <body>
    <Header />

    <main style="padding: 20px;">
      <slot />
    </main>

    <Footer />
  </body>
</html>

<slot />について

このレイアウトを使って新しいページを作る時、そのページで書いた独自の文章や画像が、すべて自動的にこの
<slot />の部分に挿入されて表示される仕組みになっています。

index.astroをレイアウトを使って書き換える

作成したレイアウトファイル(BaseLayout.astro)を使用するように、トップページ(index.astro)を編集します。

---
// 先ほど作った「BaseLayout(最強のひな形)」だけを読み込みます
import BaseLayout from '../layouts/BaseLayout.astro';

// このトップページ用のタイトルと説明文を定義します
const pageTitle = "Game Life トップページ";
const pageDescription = "Game Lifeのトップページです。最新のゲーム情報をお届けします。";
---

<BaseLayout title={pageTitle} description={pageDescription}>
  
  <h2>こんにちは!</h2>
  <p>AstroとPodmanで構築した新しいブログ環境へようこそ。</p>
  <p>「BaseLayout」を使用することで、ページの作成がより簡単になりました!</p>
  <p>この文章は、レイアウトの<slot />(スロット)に自動的に挿入されています。</p>

</BaseLayout>

とりあえず今回はここまでとします。

コメント

タイトルとURLをコピーしました