商品一覧やお知らせを、トップページと一覧ページの両方に載せることがあります。同じ内容をページごとに持たせていると、項目を追加するたびに複数のファイルを直す必要があり、片方だけ古い内容が残りやすくなります。
Astroでは、一覧データをTypeScriptファイルにまとめ、各ページからimportして描画できます。更新するデータをひとつにしながら、見出しや表示件数、レイアウトはページごとに変えられます。
この記事では、商品一覧を例に、共通データの置き方、画像パス、更新後の確認までをまとめます。同じ仕組みは、書籍やイベントなど、複数ページで同じ項目を扱う小規模な一覧にも使えます。少量のデータをコードと一緒に管理し、静的HTMLを生成する構成が対象です。
コード例はAstro 5.0.0でビルドと型検査を確認しています。サイトをルートパスで公開する前提で、商品名とリンクは架空のものです。
最初にデータの置き場所を確認する
既存サイトを直す場合は、まず一覧を描画しているページと、そのimport先を確認します。見た目が同じでも、ページ内に別々の配列がある場合と、すでに共通データを参照している場合では、変更する場所が変わります。
すでにひとつのデータを使っているなら、項目の追加はそのファイルで行えます。ページごとに同じ内容を持っているなら、共通ファイルへ移す前に、項目や並び順の違いを見ておきます。トップページだけ抜粋になっているなど、差に意味があることもあるためです。
データを共有しても、両ページを必ず同じ表示にする必要はありません。まず共通にしたい内容と、ページごとに残したい表示の違いを分けます。
今回のサンプルは、次のファイルで構成します。
| ファイル | 役割 |
|---|---|
src/data/items.ts |
商品の情報を管理する |
src/pages/index.astro |
トップページで一覧を表示する |
src/pages/catalog.astro |
一覧ページで同じデータを表示する |
public/images/items/内の画像 |
商品画像として配信する |
この段階では、データを共通にし、描画部分は各ページに置きます。
一覧データをTypeScriptにまとめる
商品ごとの情報を、型と配列で定義します。
export interface CatalogItem {
title: string;
url: string;
image: string;
description?: string;
}
export const items: CatalogItem[] = [
{
title: '卓上ライト',
url: '/products/desk-light/',
image: '/images/items/desk-light.jpg',
description: '机の上で使う小型のライトです。',
},
{
title: '収納ボックス',
url: '/products/storage-box/',
image: '/images/items/storage-box.jpg',
},
];
例では、商品名、紹介先のURL、画像、任意の説明文を持たせています。リンク先の商品ページは別途用意する構成です。既存サイトへ取り入れるときは、そのサイトで使う紹介先と画像を指定します。
CatalogItem[]にしておくと、型検査で必須項目の不足や型の違いを見つけられます。説明文は省略できるようにし、表示側でも説明がある場合だけ段落を出します。
項目を増やすときは、この配列へ追加します。並び順も配列の順序に揃える構成なら、掲載順の管理先をひとつにできます。ページ内に同じ情報をコピーしておく必要がなくなるため、修正すべき箇所が分かりやすくなります。
一方、型が合っていても、URLの入力間違いや画像ファイルの不足は残ります。string型であることは、リンク先や画像の存在を保証するものではありません。この部分は、後でビルド出力と表示を確認します。
各ページから共通データを読み込む
src/pages/index.astroでは、共通ファイルから配列をimportし、mapで一覧を作ります。
---
import { items } from '../data/items';
---
<section aria-labelledby="items-heading">
<h2 id="items-heading">商品紹介</h2>
<ul>
{items.map((item) => (
<li>
<a href={item.url}>
<img
src={item.image}
alt={item.title}
width="400"
height="300"
/>
<h3>{item.title}</h3>
</a>
{item.description && <p>{item.description}</p>}
</li>
))}
</ul>
</section>
src/pages/catalog.astroにも、同じコードを置くと、同じ2件を表示できます。この配置では両ページが同じ階層にあるため、import先も../data/itemsになります。ページをサブフォルダへ移す場合は、その場所からの相対パスに合わせます。
画像の幅と高さは、例では400×300に揃えています。実際には使用する画像の縦横比に合わせて指定します。
ここまでで、商品の内容は共通データ、一覧のHTMLは各ページ、という分担になります。たとえばトップページでは先頭の3件だけ表示し、一覧ページでは全件表示するようにもできます。
const featuredItems = items.slice(0, 3);
この場合、トップページではfeaturedItems.map(...)で描画し、一覧ページではitems.map(...)を使います。元の配列を変更せずに、表示対象だけを絞れます。
ただし、配列の先頭が本当に「おすすめ」や「新着」を意味するのかは、データの運用に合わせて決めます。単に3件取り出しただけで、新着順になるわけではありません。
データの共有と表示部品の共通化を分ける
データを共有した後、一覧のHTMLも共通コンポーネントにまとめるかは、表示の違いを見て判断できます。
両ページで同じカードを使い、画像サイズや説明文の条件も揃えるなら、描画部分をコンポーネントへ切り出すと、その後の表示修正も一度で済みます。
一方で、トップページは画像中心、一覧ページは説明文を詳しく載せる、といった違いがあるなら、データだけを共有する形でも運用できます。無理にひとつの部品へまとめて条件を増やす前に、どこを揃えたいのかを確かめます。
気をつけたいのは、データを共有しても表示の違いは残ることです。一方では説明文を表示し、もう一方では表示しない構成なら、データの修正が両方の見た目に同じように現れるとは限りません。更新後の確認は、利用しているページごとに行います。
画像ファイルの保存先と公開パスを揃える
この例では、画像をpublic/images/items/へ置きます。
| リポジトリ内のファイル | データに設定する公開パス |
|---|---|
public/images/items/desk-light.jpg |
/images/items/desk-light.jpg |
public/images/items/storage-box.jpg |
/images/items/storage-box.jpg |
Astroのpublic/内のファイルは、そのままビルド先へコピーされます。ルートパスで公開する場合、画像URLにpublicは含めません。
この置き方では、画像の自動最適化は行われません。画像をそのまま配信する構成に向いています。Astroの画像機能で変換や最適化を行いたい場合は、src/内へ置いてimportする構成を検討します。
また、/images/...の先頭の/は、オリジンのルートを指します。サブパス配下へ公開するサイトでは、base設定と実際の配信先に合わせたURLが必要です。
更新後は生成HTMLと実際の表示を確認する
共通データにまとめた後は、1か所の変更が各ページにどう現れるかを確かめます。見る項目を先に決めておくと、ビルドが通っただけで確認を終えずに済みます。
| 確認箇所 | 確かめること |
|---|---|
| 共通データの差分 | 意図した項目・掲載順・URLになっているか |
| 各ページの生成HTML | 商品名・リンク・画像パスが反映されているか |
| ビルド出力の画像 | 指定した公開パスに対応するファイルがあるか |
| ブラウザー | 画像が読み込まれ、各ページのレイアウトに収まるか |
| リンク先 | クリックして意図した紹介先へ移動できるか |
既存プロジェクトに次のスクリプトがあれば、ビルドとプレビューを使えます。
{
"scripts": {
"build": "astro build",
"preview": "astro preview",
"check": "astro check"
}
}
npm run check
npm run build
npm run preview
astro checkには@astrojs/checkとtypescriptが必要です。未導入のプロジェクトでは開発用依存へ追加してから実行します。astro buildは型検査を行わないため、両方を確認するなら別々のコマンドとして用意します。
プレビューを開いたら、トップページだけでなく一覧ページも確認します。画像については、ブラウザーのNetworkでリクエストが成功しているかを見ると、HTML内にパスがあることと、実際に画像を取得できたことを分けて確認できます。
記事用の最小例では、共通データから2ページを生成し、両ページに同じ2件の商品名・リンク・画像パスが出力されることと、画像ファイルのコピーを確認しました。型検査もエラー・警告なしで通っています。
静的サイトでは、共通データを更新した後に、再ビルドした出力を公開する必要があります。ローカルのプレビューと公開先の反映を分けて確認すると、変更がどこまで届いているかを把握できます。
まとめ
複数ページで同じ一覧を扱うときは、共通のTypeScriptファイルに情報をまとめると、内容の更新先をひとつにできます。そこから各ページが必要な件数や見せ方を選ぶ形なら、情報を揃えながら表示の違いも残せます。
まずデータの参照元を確かめ、共有する内容を決める。そのうえで、画像やリンクを含めて利用先のページを確認する。この流れは、商品一覧だけでなく、同じ情報を複数の場所へ載せる構成にも応用できます。
参考資料
仕様は2026年11月9日に公式ドキュメントで確認しています。