コンテンツにスキップ

オンデマンドレンダリング

Astroプロジェクトのコードはウェブに表示するためにHTMLとしてレンダリングされる必要があります。

デフォルトでは、Astroのページ、ルート、APIエンドポイントはビルド時に静的ページとして事前レンダリングされます。しかし、リクエストがあったときにサーバーで一部またはすべてのルートをオンデマンドレンダリングすることもできます。

オンデマンドレンダリングされたページやルートはアクセスごとに生成され、ユーザーごとにカスタマイズできます。たとえば、オンデマンドレンダリングされたページでログインユーザーのアカウント情報を表示したり、サイト全体を再ビルドせずに最新データを取得して表示したりできます。

リクエスト時にサーバーで行うオンデマンドレンダリングは**サーバーサイドレンダリング(SSR)**とも呼ばれます。

任意のページをオンデマンドレンダリングするにはアダプターを追加します。アダプターは、Astroが特定のランタイム(NetlifyやCloudflareなど)上でプロジェクトを実行するスクリプトを出力できるようにします。ランタイムはリクエスト時にページを生成するサーバー環境です。

サイトが完全に静的でオンデマンドレンダリングを行わない場合でも、アダプターを追加する価値があります。たとえばNetlifyアダプター (EN)はNetlifyのImageCDNを有効にし、サーバーアイランド (EN)server:deferを使うにはアダプターのインストールが必須です。

SSRアダプター

Astro公式アダプターはNode.jsNetlifyVercelCloudflare用が提供されています。公式およびコミュニティ製のアダプター一覧から、デプロイ環境に合ったものを選んでください。

Astroが保守する公式アダプターは、以下のastro addコマンドで追加できます。このコマンドはアダプターのインストールとastro.config.mjsへの設定変更を一度に行います。

例としてNetlifyアダプターをインストールする場合は、次のコマンドを実行します。

ターミナルウィンドウ
npx astro add netlify

アダプターを手動で追加し、astro.config.mjsを自分で更新することもできます(例:@astrojs/netlify)。

アダプターによっては独自の設定が必要な場合があります。各アダプターのドキュメントを確認し、必要な設定をastro.config.mjsに追加してください。

デフォルトではサイト全体が事前レンダリングされ、静的HTMLがブラウザに送信されます。たとえば、クッキーをチェックしてパーソナライズしたコンテンツを表示するページなど、サーバーレンダリングが必要なルートだけ事前レンダリングを無効化できます。

まず、オンデマンドレンダリングを有効にするためにアダプターを追加します。

次に、オンデマンドレンダリングしたいページやエンドポイントの先頭にexport const prerender = falseを追加します。その他のページは静的サイトのままです。

src/pages/page-rendered-on-demand.astro
---
export const prerender = false
---
<html>
<!--
このコンテンツはリクエスト時にサーバーレンダリングされます!
サーバーランタイム用アダプターを追加するだけ!
他のページはビルド時に静的生成されます!
-->
<html>

以下は、事前レンダリングを無効にして、毎回ランダムな数値を返すエンドポイントの例です。

src/pages/randomnumber.js
export const prerender = false;
export async function GET() {
const number = Math.random();
return new Response(
JSON.stringify({
number,
message: `ランダムな数字はこちら:${number}`,
}),
);
}

動的なアプリの場合は、アダプターを追加したあとビルド出力をoutput: 'server'に設定すると、すべてのページがデフォルトでサーバーサイドレンダリングされます。これは、各ページで事前レンダリングをオフにするのと同じ効果です。

そのうえで、プライバシーポリシーや会社概要ページなど、サーバーを介さずともよいページだけを個別に事前レンダリングできます。

src/pages/about-my-app.astro
---
export const prerender = true
---
<html>
<!--
`output: 'server'`を設定していますが、このページは静的です!
他のページはオンデマンドレンダリングです!
-->
<html>

ページやルートを静的生成したい場合はexport const prerender = trueを追加します。

src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `これは静的エンドポイントです`,
}),
);
}
設定リファレンスのoutput設定を参照してください。

HTMLストリーミングでは、ドキュメントをチャンクごとに分割し、順に送信して描画します。Astroはオンデマンドレンダリング時にコンポーネント単位でストリーミングを行い、描画済みの部分をすぐにユーザーへ表示します。これによりHTMLを可能な限り速く表示できますが、大きなドキュメントの場合はネットワーク状況によってダウンロードが遅くなったり、データ取得待ちで描画がブロックされることがあります。

オンデマンドレンダリングされたページやAPIエンドポイントでは、クッキーの確認・設定・取得・削除ができます。

以下の例はページビューのカウンターとしてクッキー値を更新しています。

src/pages/index.astro
---
export const prerender = false; // 'server'モードでは不要
let counter = 0
if (Astro.cookies.has('counter')) {
const cookie = Astro.cookies.get('counter')
const value = cookie?.number()
if (value !== undefined && !isNaN(value)) counter = value + 1
}
Astro.cookies.set('counter', String(counter))
---
<html>
<h1>Counter = {counter}</h1>
</html>

Astro.cookiesAstroCookie型 (EN)についてはAPIリファレンスを参照してください。

Astro.response (EN)は標準のResponseInitオブジェクトで、ステータスやヘッダーを設定できます。

次の例は商品が存在しない場合にステータスを設定しています。

src/pages/product/[id].astro
---
export const prerender = false; // 'server'モードでは不要
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 商品が存在しない
if (!product) {
Astro.response.status = 404;
Astro.response.statusText = 'Not found';
}
---
<html>
<!-- ページ内容 -->
</html>

Astro.response.headersでヘッダーを設定できます。

src/pages/index.astro
---
export const prerender = false; // 'server'モードでは不要
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- ページ内容 -->
</html>

オンデマンドレンダリングを使用するページでは、Responseオブジェクトを直接返すこともできます。手動で返すか、Astro.redirect (EN)を使用します。

src/pages/product/[id].astro
---
export const prerender = false; // 'server'モードでは不要
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 商品が存在しない
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
// 販売終了
if (!product.isAvailable) {
return Astro.redirect("/products", 301);
}
---
<html>
<!-- ページ内容 -->
</html>

Astro.requestは標準のRequestオブジェクトで、urlheadersmethod、ボディなどを取得できます。静的生成されないページで追加情報を取得する際に利用します。

リクエストヘッダーはAstro.request.headersで取得します。これはブラウザのRequest.headersと同じくHeadersオブジェクトです。

src/pages/index.astro
---
export const prerender = false; // 'server'モードでは不要
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- ページ内容 -->
</html>

HTTPメソッドはAstro.request.methodで取得できます。ブラウザのRequest.methodと同様で、文字列で返されます。

src/pages/index.astro
---
export const prerender = false; // 'server'モードでは不要
console.log(Astro.request.method) // ブラウザ遷移時はGET
---

Astro.request (EN)について詳しくはAPIリファレンスを参照してください。

サーバーエンドポイント(APIルートとも呼ばれます)は、src/pages/フォルダー内の.jsまたは.tsファイルからエクスポートされる特殊な関数です。オンデマンドのサーバーサイドレンダリングにおける強力な機能で、安全にサーバー上でコードを実行できます。

この関数はエンドポイントコンテキスト (EN)を受け取り、Responseを返します。

詳しくはEndpointsガイドを参照してください。

貢献する コミュニティ スポンサー