ミドルウェア
ミドルウェアにより、リクエストとレスポンスをインターセプトし、ページやエンドポイントがレンダリングされる直前に動的に振る舞いを注入できます。こうしたレンダリングは、ページが事前レンダリングされる場合にはビルド時におこなわれますが、オンデマンドにレンダリングされるページの場合はルートへのリクエスト時におこなわれ、クッキーやヘッダーなどの追加のSSR機能が利用できます。
また、ミドルウェアを使って、すべてのAstroコンポーネントとAPIエンドポイントで利用可能なlocals
オブジェクトを変更し、リクエスト固有の情報を各エンドポイントとページで設定・共有することもできます。このオブジェクトは、このミドルウェアがビルド時に実行される場合でも利用できます。
基本的な使い方
セクションタイトル: 基本的な使い方-
src/middleware.js|ts
というファイルを作成します。(あるいは、src/middleware/index.js|ts
を作成しても構いません。) -
このファイルの中で、
context
オブジェクトとnext()
関数を受け取るonRequest()
(EN)関数をエクスポートします。これをデフォルトエクスポートにしてはいけません。 -
.astro
ファイルの中で、Astro.locals
を使ってレスポンスデータにアクセスします。
context
オブジェクト
セクションタイトル: contextオブジェクトcontext
(EN)オブジェクトには、レンダリング中に他のミドルウェア、APIルート、.astro
ルートで利用可能な情報が含まれています。
これはonRequest()
に渡されるオプション引数で、locals
オブジェクトや、レンダリング中に共有されるその他のプロパティを含む場合があります。たとえばcontext
オブジェクトには、認証に使用されるクッキーを含められます。
context.locals
にデータを保存する
セクションタイトル: context.localsにデータを保存するcontext.locals
は、ミドルウェア内で変更可能なオブジェクトです。
このlocals
オブジェクトは、リクエスト処理のプロセスを通じて受け渡されていき、APIContext
(EN)とAstroGlobal
(EN)のプロパティとして利用できます。これにより、ミドルウェア、APIルート、.astro
ページ間でデータを共有できます。ユーザーデータなど、リクエスト固有のデータを各レンダリングステップをまたいで保持する際に役立ちます。
インテグレーションは、locals
オブジェクトを介してプロパティを設定し、機能を提供する場合があります。インテグレーションを使用している場合は、そのドキュメントを確認して、プロパティを上書きしていないか、不要な操作をしていないかを確認してください。
locals
には、文字列、数値、さらには関数やマップといった複雑なデータ型など、どんな型のデータでも格納できます。
そして、任意の.astro
ファイル内でAstro.locals
によりこの情報を利用できます。
locals
は単一のAstroルートの中で生成・消滅します。ページルートがレンダリングされると、locals
はもう存在せず、その後また新しいものが作成されます。複数のページリクエストをまたいで保持されるべき情報は、別の場所に保存する必要があります。
locals
の値はランタイムに上書きできません。これをおこなうと、ユーザーが保存した情報がすべて消去される可能性があるためです。dev
モードにおいてAstroはこれを監視し、locals
が上書きされた場合にエラーをスローします。
センシティブな情報を消去する例
セクションタイトル: センシティブな情報を消去する例以下の例では、ミドルウェアを使用して「極秘情報」という文字列を「削除済み」という語に置き換えることで、変更されたHTMLをページにレンダリングできるようにします。
ミドルウェアの型
セクションタイトル: ミドルウェアの型defineMiddleware()
ユーティリティ関数をインポートして使用すると、型安全性を確保できます。
JsDocにより型を記述している場合は、MiddlewareHandler
を使用できます。
Astro.locals
内の情報に型を付け、.astro
ファイルとミドルウェアの両コードで自動補完を有効化するには、env.d.ts
ファイルでグローバル名前空間を宣言します。
これにより、ミドルウェアファイル内で自動補完が有効になり、型安全性が確保されます。
ミドルウェアを連結する
セクションタイトル: ミドルウェアを連結するsequence()
(EN)を使用して、複数のミドルウェアを指定した順序で連結できます。
これにより、以下の順序でコンソールに出力されます。
リライト
セクションタイトル: リライト
追加:
astro@4.13.0
APIContext
は、Astro.rewriteと同じように動作するrewrite()
メソッドを公開しています。
ページ閲覧者を新しいページにリダイレクトすることなく異なるページコンテンツを表示するには、ミドルウェア内でcontext.rewrite()
を使用します。これにより新しいレンダリングフェーズがトリガーされ、ミドルウェアが再実行されます。
また、next()
関数にオプションのURLパスパラメータを渡すことで、新しいレンダリングフェーズを再トリガーすることなく、現在のRequest
を書き換えることができます。リライト先のパスは、文字列、URL、またはRequest
として与えます。
next()
関数には、Astro.rewrite()関数 (EN)と同じペイロードを渡せます。リライト先のパスは、文字列、URL、またはRequest
として与えます。sequence()により複数のミドルウェア関数を連結している場合、next()
にパスを渡すとRequest
はその場で書き換えられ、ミドルウェアは再実行されません。チェーン内の次のミドルウェア関数は、更新されたcontext
をもつ新しいRequest
を受け取ります。
エラーページ
セクションタイトル: エラーページミドルウェアは、オンデマンドレンダリングされるすべてのページに対して実行を試みます。これにはAstroのデフォルト(空白)の404ページや、カスタムの404ページが含まれます。ただし、そのコードが実行されるかどうかはアダプターによって決定されます。一部のアダプターは、プラットフォーム固有のエラーページを代わりに提供する場合があります。
ミドルウェアはまた、カスタムの500ページを含む500エラーページを提供する前にも実行を試みます。ただし、ミドルウェア自体の実行中にサーバーエラーが発生した場合を除きます。ミドルウェアが正常に実行されない場合、500ページをレンダリングするためにAstro.locals
にアクセスすることはできません。