最終更新日: 2023年08月15日

ミドルウェア ディレクトリ

Nuxtはカスタマイズ可能なルートミドルウェアフレームワークを提供しており、アプリケーション全体で使用できます。特定のルートに移動する前に実行したいコードを抽出するのに最適です。

ルートミドルウェア(route middleware)には3種類あります:

  • 匿名(またはインライン)ルートミドルウェア
    使用されるページに直接定義されるミドルウェアです。
  • 名前付きのルートミドルウェア
    middleware/ディレクトリに配置され、ページで使用される際に非同期インポート経由で自動的に読み込まれます。(注意:ルートミドルウェアの名前はケバブケースに正規化されるため、someMiddlewareはsome-middlewareになります。)
  • グローバルルートミドルウェア
    middleware/ディレクトリに配置され(.global接尾辞を持つ)、すべてのルート変更時に自動的に実行されます。

最初の2つのルートミドルウェアは、definePageMeta内で定義することができます。

フォーマット

ルートミドルウェアは、現在のルートと次のルートを引数として受け取るナビゲーションガードです。

  • ts
export default defineNuxtRouteMiddleware((to, from) => {
  if (to.params.id === "1") {
    return abortNavigation();
  }
  // 実際のアプリでは、おそらくすべてのルートを / にリダイレクトすることはないでしょう。
  // ただし、リダイレクトする前に to.path をチェックすることが重要です。
  // そうしないと、無限リダイレクトループに陥る可能性があります。
  if (to.path !== "/") {
    return navigateTo("/");
  }
});

Nuxtは、ミドルウェアから直接返すことができる2つのグローバルに利用可能なヘルパーを提供しています。

  • navigateTo
    与えられたルートにリダイレクトします。プラグインやミドルウェアの内部で使用することができます。また、ページナビゲーションを行うために直接呼び出すこともできます。
    navigateTo (to: RouteLocationRaw | undefined | null, options?: { replace: boolean, redirectCode: number, external: boolean })
  • abortNavigation
    ナビゲーションを中止し、オプションでエラーメッセージを指定します。
    abortNavigation (err?: string | Error)

Vue Routerのドキュメントのナビゲーションガードとは異なり、Nuxtのルートミドルウェアでは第3のnext()引数は渡されず、リダイレクトやルートのキャンセルはミドルウェアから値を返すことで処理されます。

  • 「nothing」は、ナビゲーションをブロックせず、次のミドルウェア関数があればそちらに移動し、ない場合はルートのナビゲーションを完了します。
  • return navigateTo('/')またはreturn navigateTo({ path: '/' })は、与えられたパスにリダイレクトします。もしリダイレクトがサーバーサイドで発生する場合、リダイレクトコードは302 Foundに設定されます。
  • return navigateTo('/', { redirectCode: 301 })は、与えられたパスにリダイレクトします。もしリダイレクトがサーバーサイドで発生する場合、リダイレクトコードは301 Moved Permanentlyに設定されます。
  • return abortNavigation()は、現在のナビゲーションを中止します。
  • return abortNavigation(error)は、エラーを伴う形で現在のナビゲーションを拒否します。

ミドルウェアの実行順序

ミドルウェアは以下の順序で実行されます:

  • グローバルミドルウェア
  • ページに定義されたミドルウェアの順序(複数のミドルウェアが配列構文で宣言されている場合)

例えば、以下のようなミドルウェアとコンポーネントがあると仮定します:

  • pages/profile.vue
  • ts
<script setup lang="ts">
definePageMeta({
  middleware: [
    function (to, from) {
      // Custom inline middleware
    },
    'auth',
  ],
});
</script>

以下の順序でミドルウェアが実行されることが予想されます:

  • analytics.global.ts
  • setup.global.ts
  • Custom inline middleware
  • auth.ts

グローバルミドルウェアの順序付け

デフォルトでは、グローバルミドルウェアはファイル名に基づいてアルファベット順に実行されます。

ただし、特定の順序を定義したい場合もあります。たとえば、前述のシナリオでは、setup.global.tsがanalytics.global.tsよりも先に実行される必要があるかもしれません。その場合、グローバルミドルウェアの前に「アルファベット順」の番号を付けることをおすすめします。

  • middleware / directory
  • ts
middleware/
--| analytics.global.ts
--| setup.global.ts
--| auth.ts

ミドルウェアの実行タイミング

もしサイトがサーバーレンダリングまたは生成されている場合、初期ページのミドルウェアはページがレンダリングされるときとクライアント上でも再度実行されます。これは、ミドルウェアがブラウザ環境を必要とする場合に必要になるかもしれません。例えば、生成されたサイトやキャッシュを積極的に行うサイト、またはローカルストレージから値を読み取る必要がある場合などです。

しかしながら、もしこの動作を避けたい場合は、それが可能です:

  • ts
middleware/
--| 01.setup.global.ts
--| 02.analytics.global.ts
--| auth.ts

ミドルウェアを動的に追加する

addRouteMiddleware()というヘルパー関数を使用して、グローバルまたは名前付きのルートミドルウェアを手動で追加することができます。これは、プラグイン内部などから行うことが可能です。

  • ts
export default defineNuxtPlugin(() => {
  addRouteMiddleware(
    "global-test",() => {
      console.log("このグローバルミドルウェアはプラグインで追加され、すべてのルート変更時に実行されます");
    },
    { global: true }
  );

  addRouteMiddleware(
    "named-test", () => {
    console.log(
      "この名前付きミドルウェアはプラグインで追加され、同じ名前の既存のミドルウェアを上書きします。"
    );
  });
});

例: 名前付きのルートミドルウェア

  • middleware / directory
  • ts
-| middleware/
---| auth.ts

ページファイル内で、このルートミドルウェアを参照することができます。

  • vue
<script setup lang="ts">
definePageMeta({
  middleware: ["auth"],
  // or middleware: 'auth'
});
</script>

そのページへのナビゲーションが完了する前に、認証ルートミドルウェアが実行されます。