Astro 6 の新機能を全部試した


Astro 6 で安定化・追加された機能を網羅する。このブログに実際に適用したものと、Changelog から拾った全変更点。


Responsive Images

Astro 6 最大の目玉。<Image> コンポーネントに layout prop を追加するだけで、レスポンシブ画像が自動生成される。

3つのレイアウトモード

<!-- constrained: コンテナに収まる。指定サイズ以上にはならない -->
<Image src={myImage} alt="" layout="constrained" width={800} height={600} />

<!-- full-width: コンテナ幅いっぱいにスケール -->
<Image src={myImage} alt="" layout="full-width" />

<!-- none: レスポンシブ無効(従来の挙動) -->
<Image src={myImage} alt="" layout="none" />

グローバル設定

// astro.config.mjs
export default defineConfig({
  image: {
    layout: 'constrained',
  },
});

これを設定すると、全ての <Image> / <Picture> コンポーネントに加え、Markdown の ![]() 構文にも自動適用される。記事中の画像が全てレスポンシブになる。

生成される HTML

Astro が自動生成する HTML はこうなる:

<img
  src="/_astro/my_image.hash3.webp"
  srcset="/_astro/my_image.hash1.webp 640w,
      /_astro/my_image.hash2.webp 750w,
      /_astro/my_image.hash3.webp 800w,
      /_astro/my_image.hash4.webp 828w,
      /_astro/my_image.hash5.webp 1080w,
      /_astro/my_image.hash6.webp 1280w,
      /_astro/my_image.hash7.webp 1600w"
  sizes="(min-width: 800px) 800px, 100vw"
  loading="lazy"
  decoding="async"
  fetchpriority="auto"
  width="800"
  height="600"
  data-astro-image="constrained"
>

srcset に7つのサイズバリアント。sizes でブレイクポイント制御。loading="lazy"decoding="async" も自動付与。手書きでこれをやったら1画像あたり数分かかる。Astro は prop 1つで済ませる。

実測

このブログでの結果:

  • 画像1枚あたり 5〜7バリアント生成
  • 3記事 + トップ + About で 18バリアント が自動生成された
  • ビルド時間への影響: 577ms(画像最適化部分)
  • モバイルでは 640w の小さいバリアントが配信され、帯域を節約

ClientRouter(旧 ViewTransitions)

Astro 5 では ViewTransitions だった名前が ClientRouter に変更された。実態に合った命名。これはクライアントサイドルーターであり、ページ遷移時にフルリロードではなく差分更新を行う。

導入

---
import { ClientRouter } from 'astro:transitions';
---
<head>
  <ClientRouter />
</head>

<head> に1行追加するだけ。全ページに適用される。

何が変わるか

  • ページ遷移がスムーズになる — フルリロードが消え、フェードやスライドのトランジションに
  • ヘッダーやナビゲーションがちらつかないtransition:persist で要素を維持
  • ブラウザの戻る/進むも対応 — クライアントサイドルーティングなので履歴管理も自動

transition:persist

<header transition:persist>
  <!-- ページ遷移してもヘッダーは再レンダリングされない -->
</header>

ナビゲーション要素に付けると、ページ遷移時に DOM が維持される。アニメーション状態やスクロール位置も保持。

体感

このブログで適用済み。Home → Blog → 記事 → About と遷移してみてほしい。フルリロードの白い点滅がなくなり、コンテンツがスムーズに切り替わるのがわかるはず。


Sessions

サーバーサイドセッション管理が安定化。Redis、Cloudflare KV などのドライバーに対応。

import { defineConfig, sessionDrivers } from 'astro/config'

export default defineConfig({
  session: {
    driver: sessionDrivers.redis({
      url: process.env.REDIS_URL
    }),
    cookie: { secure: true },
    ttl: 3600
  }
})

v5 では driver: 'redis', options: {...} だったのが、sessionDrivers.redis({...}) のオブジェクト形式に変更。型安全性が向上。

このブログは静的サイトなので Sessions は使わない。だが SSR モードの Astro アプリケーション — 管理画面、ダッシュボード、認証付きサービス — では即座に価値がある。


Live Content Collections

Astro 6 の新しいデータ取得パラダイム。従来の Content Collections がビルド時にデータを確定するのに対し、Live Content Collections はランタイムで外部データソースからコンテンツを取得する

定義

src/live.config.ts(従来の content.config.ts とは別ファイル)で定義する:

import { defineLiveCollection } from 'astro:content';
import { storeLoader } from '@example/astro-loader';

const products = defineLiveCollection({
  loader: storeLoader({
    apiKey: process.env.STORE_API_KEY,
    endpoint: 'https://api.example.com/v1',
  }),
});

export const collections = { products };

defineCollection ではなく defineLiveCollection。loader はビルド時ではなくリクエスト時に実行される。

データ取得

専用の getLiveCollection()getLiveEntry() を使う:

---
export const prerender = false; // SSR必須

import { getLiveCollection, getLiveEntry, render } from 'astro:content';

// 一覧取得
const { entries: allProducts } = await getLiveCollection('products');

// フィルタ付き取得
const { entries: featured } = await getLiveCollection('products', { featured: true });

// 単体取得
const { entry, error } = await getLiveEntry('articles', Astro.params.id);
if (error) {
  return Astro.rewrite('/404');
}
const { Content } = await render(entry);
---

<h1>{entry.data.title}</h1>
<Content />

何が変わるか

従来の Content Collections は「ビルド時にデータを収集 → 静的に配信」。Live は「リクエスト時にデータを取得 → 動的に配信」。

Build-time CollectionsLive Collections
データ取得ビルド時リクエスト時
定義ファイルcontent.config.tslive.config.ts
関数getCollection()getLiveCollection()
プリレンダリング可能不可(SSR必須)
ユースケースブログ、ドキュメントEC商品、リアルタイムデータ

schema は Zod で定義でき、型安全性は従来と同じ。loader の実装次第でフィルタリングもサーバーサイドで処理される。

このブログは静的なので Live は使わない。だが CMS 連携、EC サイト、ダッシュボードなど「常に最新データが必要」なケースで真価を発揮する。Content Collections の設計を維持したまま動的データに対応できるのは、Astro のアーキテクチャとしてきれい。


Middleware Rewrite

context.rewrite() でリダイレクトなしに別ルートをレンダリングできる。

// src/middleware.js
import { isLoggedIn } from "~/auth.js"

export function onRequest(context, next) {
  if (!isLoggedIn(context)) {
    return context.rewrite(new Request("/login", {
      headers: {
        "x-redirect-to": context.url.pathname
      }
    }));
  }
  return next();
}

URL はそのまま。表示だけがログインページに変わる。ユーザーの体験として、302 リダイレクトのちらつきがない。認証後に元のURLに戻すのも x-redirect-to ヘッダーで簡単。

これも SSR 向け。静的サイトでは使わないが、Astro で動的アプリケーションを構築する場合の選択肢が広がった。


astro:routes:resolved フック

インテグレーション開発者向け。astro:build:doneroutes プロパティに代わる新フック。

const integration = () => {
  let routes;
  return {
    name: 'my-integration',
    hooks: {
      'astro:routes:resolved': (params) => {
        routes = params.routes;
      },
    }
  }
}

開発時にもルート変更を検知できる。astro:build:done はビルド時のみだったが、astro:routes:resolved は dev server でもファイル追加・削除のたびに発火する。プラグイン開発の DX が向上。


実験的フラグの卒業

v5 で experimental だった以下が stable に昇格:

  • Responsive Imagesexperimental.responsiveImagesimage.layout
  • Sessionsexperimental.sessionsession
  • ClientRouterViewTransitions からのリネーム

astro.config.mjs から experimental ブロックを削除するだけで移行完了。


その他の新機能

Changelog から拾った、上記以外の注目すべき変更。

SVG → ラスター変換(#15180)

Sharp の画像サービスが SVG を PNG/WebP 等のラスター画像に変換可能に。SVG アイコンを最適化されたラスターとして配信したいケースに対応。

Server Island セキュリティ強化

  • security.serverIslandBodySizeLimit(#15755)— Server Island の POST ボディサイズに制限を設定可能に
  • バリデーション強化(#15765)— own-property チェックでエンドポイント検証を厳格化

Image Service API 拡張

  • getRemoteSize()(#15231)— リモート画像のサイズを取得するオプショナルメソッド追加
  • emitClientAsset(#15345)— インテグレーションがクライアントアセットを生成するための新ユーティリティ

Adapter API の刷新

  • entryTypeentrypointResolution にリネーム(#15461)
  • createRequest() / writeResponse()astro/app/node からエクスポート(#15535)
  • setPrerenderer()astro:build:start フックに追加(#15077)

createContext() の拡張(#15781)

clientAddress オプション追加。テストやミドルウェアでコンテキストを生成する際にクライアント IP を注入できる。


破壊的変更の全リスト

v5 から v6 への移行で対応が必要なもの:

削除された機能移行先
Astro.glob()getCollection() / import.meta.glob()
CommonJS config(.cjs.mjs に変更
astro:build:doneroutesastro:routes:resolved フック
astro:build:ssrentryPointsAdapter API 経由
app.render() シグネチャ新シグネチャに更新
prefetch()with オプション削除(代替なし)
emitESMImage()削除
Session test ドライバー削除
%25 パーセントエンコードルート非対応に
Content Loader 動的スキーマ関数createSchema() に変更

非推奨(今後削除予定)

非推奨 API代替
loadManifest() / loadApp()createRequest() / writeResponse()
Session ドライバー文字列署名sessionDrivers.xxx() 形式
getStaticPaths() 内の Astro直接参照を避ける
import.meta.env.ASSETS_PREFIX別の手段で取得
createExports() / start()新 Adapter API

パッチリリース(6.0.1〜6.0.3)

リリース翌日までに3つのパッチが出ている。初期バグの修正が早い。

6.0.1 / 6.0.2(同日リリース): frontmatter の return; 構文がコンテキストによって動作しない問題を修正。

6.0.3:

  • dev 環境でのプリレンダールート処理改善。Cloudflare の prerenderEnvironment: 'node' でルートマッチングと HMR が正常動作するように(#15711)
  • astro:build:done フックで distURL 配列が空だったリグレッション修正(#15852)
  • Server Island POST エンドポイントのバリデーション強化(#15765)

総評

Astro 6 は「破壊」ではなく「成熟」のリリース。

実験的だったものを安定させ(Responsive Images、Sessions、Live Content Collections)、名前を実態に合わせ(ClientRouter)、古い API を整理した(Astro.glob() 削除、Adapter API 刷新)。

静的サイトで即効性があるのは Responsive ImagesClientRouter。SSR アプリケーションには Live Content CollectionsSessionsMiddleware Rewrite が加わった。

195 の変更のうち、ほとんどがインテグレーション・アダプター開発者向け。エンドユーザーにとっての移行コストは低い。Astro.glob() を使っていなければ、ほぼそのまま動く。

このブログは Responsive Images と ClientRouter を適用済み。体感してみてほしい。