0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Astroで複数ページの一覧データを共有する

0
Posted at

商品一覧やお知らせを、トップページと一覧ページの両方に載せることがあります。同じ内容をページごとに持たせていると、項目を追加するたびに複数のファイルを直す必要があり、片方だけ古い内容が残りやすくなります。

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にまとめる

商品ごとの情報を、型と配列で定義します。

src/data/items.ts
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で一覧を作ります。

src/pages/index.astro
---
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 商品名・リンク・画像パスが反映されているか
ビルド出力の画像 指定した公開パスに対応するファイルがあるか
ブラウザー 画像が読み込まれ、各ページのレイアウトに収まるか
リンク先 クリックして意図した紹介先へ移動できるか

既存プロジェクトに次のスクリプトがあれば、ビルドとプレビューを使えます。

package.jsonのscripts部分
{
  "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日に公式ドキュメントで確認しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?