brand logo

ドキュメント

レイアウト

Nuxt Kitは、レイアウトを扱うためのユーティリティを提供します。

レイアウトは、ページをラップするために使用されます。例えば、ヘッダーやフッターなどの共通コンポーネントでページをラップするために使用できます。レイアウトは addLayout ユーティリティを使用して登録できます。

addLayout

テンプレートをレイアウトとして登録し、レイアウトに追加します。

Nuxt 2では、このユーティリティを使用して error レイアウトも登録できます。Nuxt 3+では、error レイアウトはプロジェクトルートの error.vue ページに置き換えられました

使用法

import { addLayout, createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    const { resolve } = createResolver(import.meta.url)

    addLayout({
      src: resolve('templates/custom-layout.ts'),
      filename: 'custom-layout.ts',
    }, 'custom')
  },
})

function addLayout(layout: NuxtTemplate | string, name: string): void

パラメータ

layout: テンプレートオブジェクトまたはテンプレートへのパスを持つ文字列。文字列が提供された場合、それは src が文字列値に設定されたテンプレートオブジェクトに変換されます。テンプレートオブジェクトが提供された場合、以下のプロパティを持っている必要があります:

プロパティ必須説明
srcstringfalseテンプレートへのパス。src が提供されない場合、代わりに getContents を提供する必要があります。
filenamestringfalseテンプレートのファイル名。filename が提供されない場合、それは src パスから生成されます。この場合、src オプションが必要です。
dststringfalse出力先ファイルへのパス。dst が提供されない場合、それは filename パスと nuxt buildDir オプションから生成されます。
optionsRecord<string,>{lang="ts"}falseテンプレートに渡すオプション。
getContents(data) => string | Promise<string>{lang="ts"}falseoptions オブジェクトを引数に取る関数。この関数は文字列または文字列に解決されるプロミスを返す必要があります。src が提供されている場合、この関数は無視されます。
writebooleanfalsetrue に設定すると、テンプレートは出力先ファイルに書き込まれます。それ以外の場合、テンプレートは仮想ファイルシステムでのみ使用されます。

name: レイアウトを登録する名前(例:defaultcustom など)。

これは、ヘッダーとフッターでページをラップする custom という名前のレイアウトを登録します。

import { addLayout, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    addLayout({
      write: true,
      filename: 'my-layout.vue',
      getContents: () => `<template>
  <div>
    <header>My Header</header>
    <slot />
    <footer>My Footer</footer>
  </div>
</template>`,
    }, 'custom')
  },
})

このレイアウトをページで使用できます:

pages/about.vue
<script setup lang="ts">
definePageMeta({
  layout: 'custom',
})
</script>

<template>
  <div>About Page</div>
</template>

@vitejs/plugin-vue による仮想 .vue ファイルのサポートがないため、この制限を回避するには、addLayout の最初の引数に write: true を渡すことで対処できます。

tips

このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。

Nuxtのレイアウト機能とは?〜共通UI管理の強力な味方〜

Nuxtのレイアウト機能は、ヘッダーやフッター、サイドバーなど、複数ページで共通して使うUIパーツを効率的に管理できる仕組みです。これにより、ページごとに同じコードを繰り返す必要がなくなり、保守性や開発効率が大幅に向上します。

また、レイアウトを切り替えることで、サイト内で異なるデザインや構造を簡単に実現できるため、ユーザー体験の向上にもつながります。

まず結論:Nuxtレイアウトのポイント

  • レイアウトはページをラップし、共通のUIをまとめるために使う
  • addLayout ユーティリティでカスタムレイアウトを登録可能
  • レイアウト名をページのメタ情報で指定して切り替えられる
  • レイアウトは仮想ファイルとしても、実ファイルとしても登録できる
  • SSRとCSRの両方で適切に動作するよう設計されている

いつ使うべき?使わない方がよいケースは?

使うべきケース

  • 複数ページで共通のヘッダーやフッターを持たせたいとき
  • ページごとに異なるレイアウト(例:管理画面と公開サイト)を使い分けたいとき
  • ページの構造を統一し、コードの重複を減らしたいとき
  • ページ遷移時にレイアウトを切り替えてUIを変えたいとき

使わない方がよいケース

  • 単一ページアプリケーションで共通UIがほぼない場合
  • レイアウトの切り替えが不要で、単純なページ構成の場合
  • 動的にレイアウトを頻繁に切り替える必要があり、パフォーマンスに影響が出る場合(この場合は工夫が必要)

実務でよくあるユースケースとサンプルコード

1. ヘッダー・フッターを共通化したカスタムレイアウト

import { addLayout, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    addLayout({
      write: true,
      filename: 'custom-layout.vue',
      getContents: () => `<template>
  <div>
    <header>共通ヘッダー</header>
    <main><slot /></main>
    <footer>共通フッター</footer>
  </div>
</template>`,
    }, 'custom')
  },
})

このレイアウトを使うページは以下のように指定します。

<script setup lang="ts">
definePageMeta({
  layout: 'custom',
})
</script>

<template>
  <div>このページはカスタムレイアウトを使用しています。</div>
</template>

2. 管理画面専用のレイアウトを用意する

管理画面は一般公開ページと異なるUIが必要なことが多いです。専用レイアウトを作成し、管理画面のページで切り替えます。

addLayout({
  write: true,
  filename: 'admin-layout.vue',
  getContents: () => `<template>
  <div class="admin-layout">
    <nav>管理メニュー</nav>
    <section><slot /></section>
  </div>
</template>`,
}, 'admin')

管理画面ページでは

definePageMeta({
  layout: 'admin',
})

と指定します。

3. エラーページのカスタムレイアウト(Nuxt 2との違い)

Nuxt 2では addLayouterror レイアウトを登録できましたが、Nuxt 3以降は error.vue ページに置き換わっています。独自のエラーレイアウトを作りたい場合は、error.vue を編集しましょう。

よくある落とし穴・注意点

SSRとCSRの違いによるHydration問題

レイアウトを動的に切り替える場合、SSRで生成されたHTMLとCSRでの初期レンダリングが一致しないとHydrationエラーが発生します。特に、レイアウト内でクライアント専用の処理を行う場合は注意が必要です。

仮想ファイルの扱いとViteの制限

addLayout で仮想 .vue ファイルを登録する際、@vitejs/plugin-vue の制約により仮想ファイルが正しく認識されないことがあります。この場合は write: true を指定して物理ファイルとして出力することで回避可能です。

パフォーマンスへの影響

レイアウトを複雑にしすぎると、ページの初期表示速度に影響が出ることがあります。特に多くのコンポーネントや重い処理をレイアウトに含める場合は、必要に応じて遅延読み込みや分割を検討しましょう。

まとめ

Nuxtのレイアウト機能は、共通UIの管理やページ構造の統一に非常に便利な仕組みです。addLayout を使ってカスタムレイアウトを登録し、ページごとに切り替えることで、効率的かつ保守性の高い開発が可能になります。

ただし、SSR/CSRの違いやViteの制約など、実務で使う際にはいくつかの注意点もあります。これらを理解し適切に運用することで、Nuxtのレイアウト機能を最大限に活用できるでしょう。

レイアウトの切り替えはUXに大きく影響するため、設計段階でどのようなレイアウトが必要かをよく検討することをおすすめします。