コンテンツにスキップ

オンデマンドレンダリングアダプター

Astroでは、一部あるいはすべてのページとエンドポイントにオンデマンドレンダリングを選択できます。これはサーバーサイドレンダリング(SSR) とも呼ばれ、リクエスト時にサーバー上でHTMLページを生成し、結果をクライアントに送信します。プロジェクトをサーバー上で実行しリクエストを処理するためには、アダプターが使用されます。

このオンデマンドレンダリングを利用すると、次のようなことが可能になります。

  • アプリのログイン状態のためにセッションを実装する。
  • fetch()を使って動的にAPIを呼び出しデータをレンダリングする。
  • アダプターを利用してサイトをホストにデプロイする。

以下が必要な場合は、Astroプロジェクトでオンデマンドレンダリングを有効にすることを検討してください。

  • APIエンドポイント: クライアントから機密データを隠したまま、データベースへのアクセス、認証、認可などのタスクをおこなうAPIエンドポイントとして機能するページを作成する。

  • ページの保護: サーバーでユーザーアクセスを制御し、ユーザーの権限に基づいてページへのアクセスを制限する。

  • 頻繁に変更されるコンテンツ: サイトを静的に再ビルドすることなく個々のページを生成する。これはページのコンテンツが頻繁に更新される場合に有効。

Astroは、Node.jsVercelNetlifyCloudflareの公式アダプターを提供しています。

(Deno、SST、AWSなどの)コミュニティ製のアダプターを、インテグレーションディレクトリで確認してください。

SSRアダプター

オンデマンドサーバーレンダリングを有効にする

セクションタイトル: オンデマンドサーバーレンダリングを有効にする

Astroのオンデマンドレンダリングの出力モード(serverhybrid)はいずれも、可能な限り個々のルートを事前レンダリングすることで、静的サイトのパフォーマンスを活かせるようにします。このことは、完全に動的なアプリケーションであっても、特定のルートのみにオンデマンドレンダリングが必要なほぼ静的なサイトであっても同様です。

プロジェクトでどちらを使用するかを決定するには、ページとルートの多くがどのようにレンダリングされるかに応じてoutputオプションを選択します。

  • output: 'server': デフォルトでオンデマンドレンダリングされます。サイトやアプリの大部分またはすべてをリクエスト時にサーバーレンダリングする場合に使用します。個別のページやエンドポイントで、事前レンダリングにオプトインできます。
  • output: 'hybrid': デフォルトでHTMLに事前レンダリングされます。サイトの大部分が静的である場合に使用します。個別のページやエンドポイントで、事前レンダリングをオプトアウトできます。

サーバーは少なくともいくつかのページをオンデマンドに生成する必要があるため、どちらのモードを選択しても、サーバー機能を実行するためにアダプターを追加する必要があります。

プロジェクトをserverまたはhybridモードでデプロイするには、アダプターを追加する必要があります。これは、どちらのモードも、リクエスト時にページを生成するためにサーバーでコードを実行する環境であるランタイムが必要であるためです。各アダプターによってAstroは、VercelやNetlify、Cloudflareなどの特定のランタイムでプロジェクトを実行するためのスクリプトを出力できるようになります。

公式版とコミュニティ版のアダプターを、インテグレーションディレクトリで確認できます。自分のデプロイ環境に対応するものを選択してください。

Astroが管理する公式のアダプターは、次のastro addコマンドを使って追加できます。これにより、アダプターのインストールと、astro.config.mjsファイルへの適切な変更が一度に実行されます。

たとえばVercelアダプターをインストールするには、以下のコマンドを実行します。

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

パッケージのインストールとastro.config.mjsの更新を手動でおこない、アダプターを追加することもできます。

たとえば、Vercelアダプターを手動で追加するには以下のようにします。

  1. 好みのパッケージマネージャーを利用してプロジェクトの依存関係にアダプターをインストールします。

    ターミナルウィンドウ
    npm install @astrojs/vercel
  2. astro.config.mjsファイルのimportとdefault exportにアダプターを追加し、必要なoutputモードを設定します。

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import vercel from '@astrojs/vercel/serverless';
    export default defineConfig({
    output: 'server',
    adapter: vercel(),
    });

    アダプターごとに設定が異なることに注意してください。各アダプターのドキュメントを読み、選択したアダプターに必要な設定オプションをastro.config.mjsで適用してください。

オンデマンドレンダリングを有効化するには、outputの設定値を2つのサーバーレンダリングモードのいずれかに更新する必要があります。

たとえば、デフォルトですべてのページがオンデマンドにレンダリングされるような、大部分が動的なアプリケーションを設定するには、Astroの設定ファイルにoutput: 'server'を追加します。

astro.config.mjs
import { defineConfig } from 'astro/config';
import node from "@astrojs/node";
export default defineConfig({
output: 'server',
adapter: node({
mode: "standalone"
})
});

serverモードで事前レンダリングにオプトインする

セクションタイトル: serverモードで事前レンダリングにオプトインする

output: serverを設定したほぼサーバーレンダリングされるアプリについては、export const prerender = trueをページまたはルートに追加して、静的なページまたはエンドポイントを事前レンダリングできます。

src/pages/mypage.astro
---
export const prerender = true;
// ...
---
<html>
<!-- 事前レンダリングされた静的なページ... -->
</html>
src/pages/mypage.mdx
---
layout: '../layouts/markdown.astro'
title: 'My page'
---
export const prerender = true;
# 事前レンダリングされた静的なページです
src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `静的なエンドポイントです`,
}),
);
}

hybridモードで事前レンダリングをオプトアウトする

セクションタイトル: hybridモードで事前レンダリングをオプトアウトする

output: hybridを設定したほぼ静的なサイトについては、オンデマンドにサーバーレンダリングしたいファイルにexport const prerender = falseを追加します。

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

HTMLストリーミングにより、ドキュメントはチャンクへと分割され、ネットワークを経由して順に送信され、その順番でページにレンダリングされます。serverまたはhybridモードでは、Astroはコンポーネントをレンダリングする際にブラウザに送信するためにHTMLストリーミングを使用します。これによりユーザーにできるだけ早くHTMLを表示できますが、ネットワークの状況によっては、大きなドキュメントのダウンロードが遅れたり、データの取得を待つことでページのレンダリングがブロックされることがあります。

serverhybridモードでは、ページやAPIエンドポイントでクッキーをチェック、設定、取得、削除できます。

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

src/pages/index.astro
---
let counter = 0
if (Astro.cookies.has("counter")) {
const cookie = Astro.cookies.get("counter")
counter = cookie.number() + 1
}
Astro.cookies.set("counter", counter)
---
<html>
<h1>Counter = {counter}</h1>
</html>

Astro.cookiesAstroCookieの詳細については、APIリファレンスを参照してください。

オンデマンドレンダリングにより、ページからResponseを返すこともできます。

以下の例では、データベースでidを検索した後、動的に404を返しています。

src/pages/[id].astro
---
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 商品(Product)が見つからなかった
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
---
<html>
<!-- ページの内容... -->
</html>

Astro.requestは標準のRequestオブジェクトです。リクエストのurlheadersmethod、さらにはbodyを取得するなどのために使用できます。

serverhybridモードの両方で、静的に生成されないページに関する追加の情報にこのオブジェクトからアクセスできます。

リクエストのヘッダーにはAstro.request.headersからアクセスできます。これはブラウザのRequest.headersと同様に動作します。これはHeadersオブジェクトで、クッキーなどのヘッダーを取得できます。

src/pages/index.astro
---
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- ページの内容... -->
</html>

リクエストで使用されているHTTPメソッドにはAstro.request.methodからアクセスできます。これはブラウザのRequest.methodと同様に動作します。リクエストで使用されているHTTPメソッドを文字列として返します。

src/pages/index.astro
---
console.log(Astro.request.method) // GET (ブラウザで遷移した際)
---

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

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

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

詳しくは、エンドポイントガイドを参照してください。

貢献する

どんなことを?

GitHub Issueを作成

チームに素早く問題を報告できます。

コミュニティ