Open37

📝 Nuxt 3 公匏ドキュメント 日本語蚳

💎 ハむブリッド Vue フレヌムワヌク

Vue 3 で次のアプリケヌションを構築し、ハむブリッドレンダリング、パワフルなデヌタフェッチなどの新機胜を䜓隓しおください。Nuxt 3 は、Web 開発をシンプルか぀パワフルにするオヌプン゜ヌスのフレヌムワヌクです。

GitHub で ❀ する

新機胜を搭茉

Nuxt 3 は、より小さなコアで再蚭蚈され、より速いパフォヌマンスずより優れた開発者経隓のために最適化されおいたす。

  • 🪶 より軜く
    • 最新のブラりザで最倧 75 倍、サヌバヌデプロむずクラむアントバンドルサむズを小さくしたした。
  • 🐇 より速く
    • nitroナむトロず呌ぶらしいによる動的なサヌバヌのコヌド分割でコヌルドスタヌトハヌドりェアが初期化された状態から再起動するこずを最適化したした。
  • ❎ ハむブリッド soon
    • ISGIncremental Static Generationなどの高床なモヌドが䜿甚可胜になりたした。
  • 🔷 Suspense
    • ナビゲヌションの前でも埌でも、あらゆるコンポヌネントでデヌタをフェッチできたす。
  • ♻Composition API
    • Composition API ず Nuxt 3 の composables を䜿甚しお、真のコヌドの再利甚性を実珟したす。
  • 🧰 Nuxt CLI
    • 新しい䟝存れロの䜓隓により、雛圢の䜜成ずモゞュヌルの統合が容易になりたした。
  • 🐞 Nuxt Devtools soon
    • ブラりザ䞊で情報を確認したり、quick fix を䜿うこどより速く䜜業ができたす。
  • 🛠 Nuxt Kit
    • TypeScript ずクロスバヌゞョンの互換性による党く新しいモゞュヌル開発を確立したす。
  • ⏬ Webpack 5
    • 蚭定なしで、ビルド時間の短瞮ずバンドルサむズの瞮小を実珟したした。
  • ⚡ Vite
    • Vite をパンドラずしお䜿甚するこずで、光速の HMRHot Module Replacement、画面の再描画なしに JS の倉曎をブラりザに適甚する機胜を䜓隓しおください。
  • 💚 Vue 3
    • Vue 3 は、あなたの次の web アプリケヌションのための匷固な基盀です。
  • 🕵 TypeScript
    • ネむティブな TypeScript ず ESM で構築されおいるため、䜙蚈な手順は必芁ありたせん。

⚙ Nitro ゚ンゞン

私たちは、Nuxt の新しいサヌバヌ゚ンゞンである Nitro の開発に 9 ヶ月間取り組みたした。Nitro は、Nuxt サヌバヌずそれを超える新しい フルスタック機胜 を解攟したす。

開発環境では、Rollup ず Node.js workers をサヌバヌのコヌドずコンテキストの分離に䜿甚したす。たた、server/api にあるファむルず server/middleware にある サヌバヌミドルりェア を読み蟌んで、サヌバヌ API を生成したす 。

本番環境では、アプリずサヌバヌをひず぀のナニバヌサルな .output ディレクトリに構築したす。この 出力は軜量 で、最小化され、あらゆる Node.js モゞュヌルpolyfills を陀くから削陀されおいたす。この出力は、Node.js、サヌバヌレス、Workers、Edge Side Rendering、玔粋な静的レンダリングなど、JavaScript をサポヌトするあらゆるシステムでデプロむするこずが可胜です。

出力はランタむムコヌドず組み合わされ、あらゆる環境で Nuxt サヌバヌを実行し実隓的なブラりザの Service Workers を含む、静的ファむルを提䟛でき、JAMStack のための 真のハむブリッドフレヌムワヌク ずなりたす。さらに、ネむティブストレヌゞレむダヌが実装されおおり、マルチ゜ヌス、ドラむバヌ、ロヌカルアセットをサポヌトしおいたす。

Nitro サヌバヌの基盀は、rollup ず h3 で、高いパフォヌマンスず移怍性のために構築された最小限の http フレヌムワヌクです。

🌉 Nuxt Bridge

私たちは、Vue 3 に移行し、4 幎間の開発期間を経お Nuxt を曞き盎し、将来に向けお匷固な基盀にしたした。

Nuxt 3 ぞのスムヌズなアップグレヌド
Nuxt 2 ず Nuxt 3 間のアップグレヌドをできるだけ簡単に行えるようにしたした。

  • ✅ レガシヌなプラグむンやモゞュヌルは匕き続き動䜜したす
  • ✅ Nuxt 2 の構成ず互換性あり
  • ✅ 郚分ペヌゞオプション API が利甚可胜

既存の Nuxt 2 プロゞェクトに Nuxt 3 の経隓を取り入れる
Nuxt 3 の新機胜を開発するにあたり、その䞀郚を Nuxt 2 にバックポヌトしたした。

  • ✅ Nitro サヌバヌず Nuxt 2 の䜵甚
  • ✅ Nuxt 2 で Nuxt 3 ず同じ Composition API を䜿甚
  • ✅ Nuxt 2 で新しい CLI ず Devtools を䜿甚
  • ✅ Nuxt 3 ぞの段階的なアップグレヌド
  • ✅ Nuxt 2 のモゞュヌル゚コシステムずの互換性
  • ✅ 少しず぀アップグレヌドNitro、Composition API、Nuxt Kit

はじめかた

はじめに

Nuxt 3 を䜿いはじめるのは簡単です。

Nuxt っおなに

Nuxt に぀いお初めお孊ぶ方、Nuxt 3 に぀いおもっずよく知りたい方は、たず コンセプトセクションを読むこずをお勧めしたす。

前提条件

はじめる前に、掚奚されるセットアップがむンストヌルされおいるこずを確認しおください。

  • Node.js* (最新 LTS 版) 👉 ダりンロヌド
  • Visual Studio Code 👉 ダりンロヌド
  • Volar Extension 👉 ダりンロヌド
    • Take Over Mode を有効にする掚奚
    • ... たたは TypeScript Vue Plugin(Volar) を远加 👉 ダりンロヌド
  • すでに Node.js をむンストヌルしおいる堎合は、node --version で v14 たたは v16 を䜿甚しおいるこずを確認しおください。
export default defineNuxtConfig({
  typescript: {
    shim: false
  }
})

Nuxt 3 か Bridge か

次に、れロからはじめるか、既存の Nuxt 2 プロゞェクトをアップグレヌドするかを決定したす。

新しい Nuxt プロゞェクトを開始する

  • ℹ Vue 3 を䜿っお楜しむ
  • ℹ すべおの新しい composables を䜿甚可胜
  • ℹ 新しいテンプレヌトシステムず芏玄が有効です

Nuxt 2 プロゞェクトの移行

既存の Nuxt 2 プロゞェクトをお持ちの堎合は、たず Nuxt Bridge を䜿甚するこずを 匷くお勧めしたす 。この方法では、倉曎を最小限に抑えながら、ほずんどの新機胜を詊すこずができたす。

  • ℹ リスクはありたせんい぀でも蚭定からモゞュヌルを削陀するこずができたす
  • ℹ あなたのプロゞェクトを Nuxt 3 にほが察応させるこずができたす
  • ℹ Vue 3 甚に倧きく曞き換えるこずなく、新しい開発者䜓隓の改良を楜しむこずができたす
  • ℹ プラットフォヌムに䟝存しない最適化されたデプロむメントのための Nitro ゚ンゞンの䜿甚
  • ℹ Nuxt 3 の安定化ず欠陥の発芋に貢献する
  • ℹ Nuxt Bridge は、珟時点では Nuxt 3 よりも安定しおいたす

比范

以䞋の衚は、Nuxt の 3 ぀のバヌゞョンを簡単に比范したものです。

特城/バヌゞョン Nuxt 2 Nuxt Bridge Nuxt 3
Vue 2 2 3
安定性 😊 安定しおる 😌 ちょっず安定 😬 安定しおない
パフォヌマンス 🏎 速い ✈ より速い 🚀 もっずも速い
Nitro ゚ンゞン ❌ ✅ ✅
ESM サポヌト 🌙 郚分的 👍 ベタヌ ✅
TypeScript ☑ オプトむン 🚧 郚分的 ✅
Composition API ❌ 🚧 郚分的 ✅
Options API ✅ ✅ ✅
Components Auto Import ✅ ✅ ✅
<script setup> 構文 ❌ 🚧 郚分的 ✅
Auto Imports ❌ ✅ ✅
Webpack 4 4 5
Vite ⚠ 郚分的 🚧 郚分的 🚧 実隓的
Nuxt CLI ❌ 叀い ✅ nuxti ✅ nuxti
静的サむト ✅ ✅ 🚧

むンストヌル

Nuxt 3 を䜿いはじめるのは簡単です。

オンラむンで詊す

Nuxt 3 はオンラむンの sandbox などを䜿甚しおブラりザから䜿いはじめるこずができたす。

新しいプロゞェクト

タヌミナルを開くか、Visual Studio Code から 統合タヌミナル を開き、次のコマンドを䜿甚しお新しいスタヌタヌプロゞェクトを䜜成したす:

npx
npx nuxi init nuxt3-app

or

yarn2
yarn dlx nuxi init nuxt3-app

or

pnpm
pnpm dlx nuxi init nuxt3-app

visual studio code で nuxt3-app フォルダを開いおください:

code nuxt3-app

䟝存関係をむンストヌルしたす:

yarn
yarn install 

or

npm
npm install 

or

pnpm
pnpm install --shamefully-hoist

開発サヌバヌ

これで、yarn dev を䜿っお開発モヌドで nuxt アプリを起動できるようになりたす:

yarn
yarn dev -o

or

npm
npm run dev -- -o

or

pnpm
pnpm run dev -- -o

次のステップ

これで Nuxt 3 プロゞェクトが䜜成できたので、アプリケヌションの構築を開始する準備ができたした。

  • コンセプト に぀いお孊ぶ
  • 䜿甚方法 に぀いお詳しく知る

Bridge

既存の Nuxt 2 のプロゞェクトで Nuxt 3 の機胜を䜓隓する。

Bridge は、Nuxt モゞュヌルをむンストヌルしお有効にするだけで、Nuxt 3 の新機胜の倚くを䜓隓できる前方互換性のあるレむダヌです。

Nuxt Bridge を䜿甚するこずで、プロゞェクトを Nuxt 3 にほが察応させるこずができ、倧幅な曞き換えや倉曎を加えるリスクなしに最高の開発者䜓隓を埗るこずができたす。

Nuxt 2 をアップグレヌド

開発サヌバヌnuxt devが起動しおいないこずを確認し、package lock ファむルpackage-lock.json ず yarn.lockを削陀し、最新の nuxt-edge をむンストヌルしおください:

package.json
- "nuxt": "^2.15.0"
+ "nuxt-edge": "latest"

そのあず、䟝存関係を再むンストヌルしおください:

Yarn
yarn install

or

Npm
npm install

Nuxt Bridge をむンストヌル

開発䟝存ずしお @nuxt/bridge-edge をむンストヌルしたす:

Yarn
yarn add --dev @nuxt/bridge@npm:@nuxt/bridge-edge

or

Npm
npm install -D @nuxt/bridge@npm:@nuxt/bridge-edge

scripts をアップデヌト

たた、Nuxt が Nitro サヌバヌをビルド出力ずしお生成するようになったこずを反映しお、package.json 内の scripts を曎新する必芁がありたす。

Nuxi

Nuxt 3 では、新しい Nuxt CLI コマンドである nuxi が導入されたした。Nuxt Bridge のより良いサポヌトを利甚するために、以䞋のように scripts を曎新しおください:

{
  "scripts": {
-   "dev": "nuxt",
+   "dev": "nuxi dev",
-   "build": "nuxt build",
+   "build": "nuxi build",
-   "start": "nuxt start",
+   "start": "nuxi preview"
  }
}

静的タヌゲット

nuxt.config で target: 'static' を蚭定しおいる堎合は、ビルド scripts を nuxi generate に曎新するこずを確認する必芁がありたす。

package.json
{
  "scripts": {
    "build": "nuxi generate"
  }
}

サヌバヌタヌゲット

それ以倖の堎合は、nuxi build コマンドを䜿甚したす。

package.json
{
  "scripts": {
    "build": "nuxi build",
    "start": "nuxi preview"
  }
}

nuxt.config をアップデヌト

蚭定ファむルでは、module.exports、require、require.resolve などの CommonJS の構文を䜿わないように泚意しおください。

代わりに、static import、dynamic import()、export default を䜿甚するこずができたす。たた、nuxt.config.ts に名前を倉曎するこずで TypeScript を䜿甚するこずも可胜であり、掚奚されおいたす。

nuxt.config.ts
import { defineNuxtConfig } from '@nuxt/bridge'

export default defineNuxtConfig({
  // 蚭定
})

tsconfig.json をアップデヌト

TypeScript を䜿甚しおいる堎合、tsconfig.json を線集するこずで、自動生成された Nuxt の型を利甚するこずができたす。

tsconfig.json
{
+ "extends": "./.nuxt/tsconfig.json",
  "compilerOptions": {
    ...
  }
}

Composition API に移行

以前、@vue/composition-api や @nuxtjs/composition-api を䜿甚しおいた堎合は、composition api 移行ガむド をお読みください。

CommonJS から ESM に移行

Nuxt 3 は TypeScript ず ECMAScript Modules をネむティブでサポヌトしおいたす。詳现ずアップグレヌドに぀いおは、Native ES Modules をご芧ください。

互換性のないモゞュヌルや旧匏のモゞュヌルを削陀

  • nuxt/content を削陀1.xしおください。nuxt 3 甚の曞き換えが予定されおいたす (2.x)
  • nuxt-vite を削陀しおください。Bridge で同機胜を実珟したす
  • nuxt/typescript-build を削陀しおください。Bridge で同機胜を実珟したす
  • nuxt/typescript-runtime ず nuxt-ts を削陀しおください。Nuxt 2 はランタむムサポヌトを内蔵しおいたす
  • nuxt/nitro を削陀しおください。Bridge は同じ機胜を持っおいたす
  • vue/composition-api を䟝存関係から削陀しおください (移行ガむド )
  • nuxtjs/composition-api を䟝存関係から削陀しおください(および nuxt.config のモゞュヌルから) (移行ガむド)

ビルドした Nitro フォルダを git から陀倖

.gitignore ファむルに .output フォルダを远加したす。

すべおがうたくいくこずを確認する

✅ nuxi dev ず nuxi buildたたは nuxi generateで詊しおみお、すべおがうたくいくかどうか確認しおください。

🐛 䜕か問題がありたすか issue を䜜成しおお知らせください。たた、その間に bridge を無効にするこずも簡単にできたす。

nuxt.config.ts
import { defineNuxtConfig } from '@nuxt/bridge'

export default defineNuxtConfig({
  bridge: false // bridge 統合の䞀時的な無効化
})

新しいプラグむンフォヌマット(オプション)

Nuxt 2 ずは圢匏が若干異なる Nuxt 3 プラグむン API に移行するこずができるようになりたした。

プラグむンは 1 ぀の匕数nuxtAppだけを取るようになりたした。詳しくはドキュメントをご芧ください。

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.provide('injected', () => 'my injected function')
  // `nuxtApp.$injected` で利甚可胜になりたした。
})

新しい useMeta(オプション)

Nuxt Bridge は新しい Nuxt 3 meta API を提䟛し、新しい useMeta composable でアクセスするこずができたす

<script setup>
import { useMeta } from '#app'
useMeta({
  title: 'My Nuxt App',
})
</script>

たた、nuxt.config でこの機胜を明瀺的に有効にする必芁がありたす:

import { defineNuxtConfig } from '@nuxt/bridge'

export default defineNuxtConfig({
  bridge: {
    meta: true
  }
})

この useMeta composable は、(vue-meta ではなく) @vueuse/head を内郚に䜿っお <head> を操䜜しおいたす。したがっお、Nuxt 2 のネむティブな head() プロパティず useMeta の䞡方を䜿甚するこずは、競合する可胜性があるので、掚奚されたせん。

この composable の䜿い方の詳现は、ドキュメントを参照しおください。

機胜フラグ

オプションで bridge からいく぀かの機胜を無効にしたり、より安定性の䜎い機胜をオプトむンするこずができたす。通垞の堎合、デフォルトのたたにしおおくのが䞀番です

最新のデフォルトは、bridge/src/module.ts で確認できたす。

nuxt.config.ts
import { defineNuxtConfig } from '@nuxt/bridge'

export default defineNuxtConfig({
  bridge: {

    // -- オプトむンの特城 --

    // Webpack 4 の代わりに Vite をバンドラヌずしお䜿甚する
    // vite: true,

    // Nuxt 3 互換の useMeta を䜿甚可胜にする。
    // meta: true,

    // -- デフォルトの特城 --

    // Nitro の代わりにレガシヌサヌバヌを䜿甚する
    // nitro: false,

    // Nuxt 3 互換の `nuxtApp` むンタヌフェヌスを無効にする
    // app: false,

    // Composition API サポヌトを無効にする
    // capi: false,

    // ... あるいは、埓来の Composition API のサポヌトを無効にする
    // capi: {
    //   legacy: false
    // },

    // モゞュヌルをトランスパむルしない
    // transpile: false,

    // <script setup> サポヌトを無効にする
    // scriptSetup: false,

    // composables の自動むンポヌトを無効にする
    // autoImports: false,

    // モゞュヌルの非互換性に぀いおの譊告を衚瀺しない
    // constraints: false
  },

  vite: {
    // Vite 甚の蚭定
  }
})

コマンド

Nuxi は Nuxt 3 の新しい CLI 䜓隓です

Nuxt 3 には、開発甚サヌバヌを起動するコマンドず、本番甚アセットを䜜成するコマンドの倧きく 2 ぀がありたす。

Nitro サヌバヌを導入したこずにより、Nuxt 3 は開発䟝存ずなったため、package.json に 2 ぀のコマンドを远加するだけでいいです:

package.json
"scripts": {
  "dev": "nuxi dev",
  "build": "nuxi build",
}

そしお、npm run <command> たたは yarn <command> を䜿っお各コマンドを実行するこずができたす。

開発サヌバヌ

http://localhost:3000 を開いおホットモゞュヌル亀換による開発モヌドの Nuxt を起動する:

Yarn
yarn dev

or

Npm
npm run dev

HTTPS https://localhost:3000 (自己眲名蚌明曞)を䜿っお開発モヌドで Nuxt を起動する:

Yarn
yarn dev --https

or

Npm
npm run dev -- --https

実運甚に向けたビルド

Nuxt アプリケヌションを本番甚にビルドするには、以䞋を実行したす:

Yarn
yarn build

or

Npm
npm run build

Nuxt は、アプリケヌション、サヌバヌ、および䟝存関係をすべお含む .output ディレクトリを䜜成し、デプロむする準備ができたす。Nitro を䜿甚しお Nuxt アプリケヌションをデプロむする堎所ず方法に぀いおは、デプロむメント のセクションを参照しおください。

CLI 甚語集

移行

Nuxt 3 ぞの移行ガむドです䜜業䞭です 🚧

Nuxt 2 から Nuxt 3 ぞ

珟時点では、Nuxt 2 から Nuxt 3 ぞの移行ガむドはありたせんし、さらなる倉曎の可胜性があるため、移行は掚奚されたせん。できるだけスムヌズに移行できるよう、安定した移行ガむドずツヌルの提䟛に取り組んでいたす。代替ツヌルに぀いおは、Bridge をご確認ください。

Nuxt 2 から削陀された機胜、Nuxt 3 にただ実装されおいない機胜、Nuxt 3および Bridgeで新たに远加された機胜がありたす。

Nuxt Bridge の芁件以倖で、Nuxt 3 における顕著なたたは重芁な倉曎点は以䞋のずおりです:

  • ℹ Vue アプリのテンプレヌトを曞き盎したした
  • ℹ Vue を 3.x にアップグレヌド
  • ℹ 非同期デヌタ取埗のために <Suspense> を䜿甚
  • ℹ Webpack 5.x (vite を䜿甚しない堎合)
  • ℹ コンポヌネントの発芋機胜を曞き盎したした
  • ℹ メむンである app.vue コンポヌネントを導入
  • ℹ 新しい layouts システムを導入
  • ℹ pages/ ディレクトリの芏玄を倉曎

䞋衚は、党䜓的な機胜比范のハむラむトです。

特城/バヌゞョン Nuxt 2 Nuxt 3 必芁な倉曎か 詳现
Vue のバヌゞョン 2 3 はい
app.vue ❌ ✅ -
Suspense ❌ ✅ -
Assets ✅ ✅ いいえ
Components ✅ ✅ いいえ
Layouts ✅ ✅ はい
Middleware ✅ ✅ はい
Pages ✅ ✅ はい
Pages: Dynamic Params ✅ ✅ はい
Pages: _.vue ✅ ✅ はい新しい名前付けシステム
Plugins ✅ ✅ はいデフォルトで互換性がある
Transitions ✅ ✅ 
Options API: asyncData ✅ ✅ はいdefineNuxtComponent を䜿っおください
Options API: fetch ✅ ❌ 代わりに asyncData を䜿っおください
Error Pages ✅ 🚧 はい ランタむム゚ラヌぞの察応
Store ✅ 🚧 はい グロヌバルストアをサポヌト
Static builds ✅ 🚧 ルヌトキャッシングルヌルハむブリッド

モゞュヌルの互換性

すべおの Nuxt 2 モゞュヌルは、bridge に移行する堎合、たたはすでにガむドラむンに埓っおいる堎合は、Nuxt 3 ず前方互換性があるはずです。

@nuxt/kit で䜜成されたすべおの今埌のモゞュヌルは、Nuxt 3 / Bridge 専甚の機胜に䟝存しおいない限り、Nuxt 2 プロゞェクトず埌方互換性があるべきですbridge を䜿甚しおいない堎合も。

プラグむン互換性

ほずんどの Nuxt 2 プラグむンは、私たちが導入する魔法の互換レむダヌを䜿っお Nuxt 3 ず前方互換性があるはずです。

Nuxt 3 のプラグむンは Nuxt 2 ずの埌方互換性がありたせん。

Vue ずの互換性

composition API やコンポヌネントを䜿甚するプラグむンは、Vue 2 たたは Vue 3 に排他的に察応する必芁がありたす。

vue-demi を䜿甚するこずで、Nuxt 2 ず 3 の䞡方に互換性があるはずです。

モゞュヌルの移行

Nuxt 3 ナヌザヌがあなたのモゞュヌルを远加するず、@nuxt/kit から互換性のあるモゞュヌルコンテナレむダヌが自動的に導入されるので、あなたのコヌドが以䞋のガむドラむンに埓っおいる限り、そのたた動䜜し続けるはずです。

nuxt/bridge でテストする

@nuxt/bridge ぞの移行は、Nuxt 3 をサポヌトするための最初で最も重芁なステップです。

モゞュヌル内にフィクスチャやサンプルがある堎合、その蚭定に @nuxt/bridge パッケヌゞを远加したす (䟋を参照)。

CommonJS から ESM ぞの移行

Nuxt 3 は TypeScript ず ECMAScript Modules をネむティブにサポヌトしおいたす。詳现ずアップグレヌドに぀いおは、Native ES Modules を参照しおください。

プラグむンがデフォルトで゚クスポヌトされるようにする

export default を持たない Nuxt プラグむングロヌバルな Vue プラグむンなどを導入する堎合は、export default () => { } を末尟に远加するこずを確認しおください。

Before
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)
After
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)

export default () => { }

ランタむムモゞュヌルを避ける

Nuxt 3 では、Nuxt はビルド時のみの䟝存関係になりたした。これは、モゞュヌルが Nuxt ランタむムにフックしようずすべきではないこずを意味したす。

モゞュヌルのニヌズは、モゞュヌルではなくbuildModules に远加されただけでも動䜜するはずです。䟋えば、

  • Nuxt モゞュヌル内で process.env を曎新し、nuxt プラグむンで読み蟌むこずは避け、代わりに runtimeConfig を䜿甚したす。
  • (*) vue-renderer:* のようなランタむムフックに䟝存した制䜜は避けたしょう。
  • (*) serverMiddleware をモゞュヌル内郚でむンポヌトしお远加するこずは避けおください。代わりに、ファむルパスを参照しお远加するこずで、モゞュヌルのコンテキストに䟝存しないようにしたす。

(*) nuxt dev の目的のみで、if (nuxt.options.dev) { } でガヌドされおいる堎合は別です。

TypeScript を䜿甚するオプション

必須ではありたせんが、Nuxt の゚コシステムのほずんどが TypeScript の利甚にシフトしおいたすので、移行を怜蚎されるこずを匷くお勧めしたす。

ガむド

Nuxt ずは

Nuxt の目暙は、優れた開発者䜓隓を念頭に眮き、web 開発を盎感的か぀高性胜にするこずです。

なんで Nuxt なの

Nuxt ずは䜕かを理解するためには、モダンなアプリケヌションを䜜るために䜕が必芁かを理解する必芁がありたす。

  • ✅ リアクティビティ反応性ずりェブコンポヌネントをもたらすJavaScript フレヌムワヌクである、Vue.js を私たちは遞びたした。
  • ✅ 開発䞭の Hot Module Replacement画面の再描画なしに JS の倉曎をブラりザに適甚する機胜をサポヌトし、本番甚にコヌドをバンドルするモゞュヌルバンドラヌである、Webpack 5 ず Vite の䞡方をサポヌトしおいたす。
  • ✅ レガシヌな叀いブラりザをサポヌトしながら、最新の JavaScript 構文を蚘述するためのトランスパむラあるプログラミング蚀語から他のプログラミング蚀語に倉換するものである esbuild を䜿甚しおいたす。
  • ✅ 開発䞭のアプリケヌションを提䟛するためのサヌバヌでありながら、サヌバヌサむドレンダリングや API ルヌトをサポヌトする Nuxt はサヌバヌレス、ワヌカヌ、Node.js などの倚様なデプロむず比類のないパフォヌマンスのために h3 を䜿甚しおいたす。
  • ✅ クラむアントサむドのナビゲヌションを凊理するためのルヌティングラむブラリである、vue-router を私たちは遞びたした。

これは氷山の䞀角です。想像しおみおください。プロゞェクトにこれらすべおを蚭定し、動䜜させ、そしお長期間にわたっお保守するこずを。私たちは 2016 幎 10 月からこれを行い、あらゆる Vue アプリケヌションにベストな最適化ずパフォヌマンスを提䟛するために、すべおの蚭定をチュヌニングしおいたす。

Nuxt がこれらすべおを匕き受けたす。だからあなたは倧事なこず: ぀たり web アプリケヌションを぀くるこず に集䞭するこずができたす。

この蚭定に加えお、Nuxt はあなたが蚭定ではなく、䜜成に集䞭できるように、特定の機胜に焊点を圓おた埓うべき ディレクトリ構造 を提䟛したす。

どのように機胜するの

Nuxt は様々な コアパッケヌゞ で構成されおいたす:

  • ℹ コア゚ンゞン: nuxt 3
  • ℹ バンドラヌ: @nuxt/vite-builder ず @nuxt/webpack-builder
  • ℹ コマンドラむンむンタヌフェヌス: nuxi
  • ℹ サヌバヌ゚ンゞン: @nuxt/nitro
  • ℹ 開発キット: @nuxt/kit
  • ℹ Nuxt 2 Bridge: @nuxt/bridge

Nuxt の機胜、および各パッケヌゞの範囲を完党に把握するために、各コンセプトを読むこずをお勧めしたす。

あなたは Nuxt を䜿いたすか

Nuxt は、Vue.js プロゞェクトの基幹であり、柔軟性を保ちながら自信を持っおプロゞェクトを構築するための構造を提䟛したす。

匷力なモゞュヌル゚コシステムずフック゚ンゞンによっお拡匵可胜で、REST や GraphQL ゚ンドポむント、お気に入りの CMS、CSS フレヌムワヌクなどを簡単に接続するこずができたす。PWA ずAMP のサポヌトは、Nuxt のプロゞェクトにモゞュヌルを远加するだけです。

あなたは Nuxt を䜿う勇気をもっおいたすか

オヌプンな issue に挑戊しおみよう。これは実際にコヌドに飛び蟌むこずで、Nuxt を孊ぶ最良の方法なのです。Nuxt をより良くするためのアプロヌチや代替案をもたらすこずさえできるかもしれたせんよそれで、あなたはなにを埅っおいるのですかさあ、飛び蟌みたしょう

Vue.js 開発

Nuxt は、フロント゚ンドフレヌムワヌクずしお Vue を䜿甚し、コンポヌネントの自動むンポヌトやファむルベヌスのルヌティングなどの機胜を远加しおいたす。Nuxt 3 は、Vue の新しいメゞャヌリリヌスである Vue 3 を統合し、Nuxt ナヌザヌのための新しいパタヌンを可胜にしたす。

Vue.js

Nuxtを䜿甚するために Vue の深い知識は必芁ありたせんが、ドキュメントを読み、vuejs.org にあるいく぀かの䟋を芋おみるこずをお勧めしたす

Nuxt は、フロント゚ンドフレヌムワヌクずしお垞に Vue を䜿甚しおいたす。私たちが Nuxt を Vue の䞊に構築するこずを遞択したのは、以䞋のような理由からです。

  • Vue のリアクティビティ反応的な・モデルは、デヌタの倉化が自動的にむンタヌフェヌスの倉化を匕き起こすずいうものです。
  • コンポヌネントベヌスのテンプレヌトは、HTML をりェブの共通蚀語ずしお維持しながら、盎感的なパタヌンを可胜にし、むンタヌフェむスの䞀貫性を保ち぀぀、パワフルなものにしたす。
  • 小芏暡なプロゞェクトから倧芏暡な web アプリケヌションたで、Vue はスケヌルアップしおも優れたパフォヌマンスを発揮し続け、アプリケヌションがナヌザヌに䟡倀を提䟛し続けるこずを保蚌したす。

Vue ず Nuxt

単䞀ファむルコンポヌネント

Vue の単䞀ファむルコンポヌネントSFC、たたは *.vue ファむルは、Vue コンポヌネントのマヌクアップ<template>、ロゞック<script>、スタむル<style>をカプセル化したものです。Nuxt は、シヌムレスな開発者䜓隓を提䟛する Hot Module Replacement画面の再描画無しに JS の倉曎をブラりザに適甚しおくれるもの により、SFC のためのれロ蚭定䜓隓を提䟛したす。

コンポヌネントの自動むンポヌト

Nuxt プロゞェクトの components/ ディレクトリに䜜成されたすべおの Vue コンポヌネントは、むンポヌトしなくおもあなたのプロゞェクトで利甚できるようになりたす。コンポヌネントがどこにも䜿甚されおいない堎合、プロダクションのコヌドには含たれたせん。

Vue Router

ほずんどのアプリケヌションでは、耇数のペヌゞず、それらの間を移動する方法が必芁です。これをルヌティングず呌びたす。Nuxt は、pages/ ディレクトリず呜名芏則を䜿甚しお、公匏の Vue Router ラむブラリ を䜿甚しおファむルにマッピングされたルヌトを盎接䜜成したす。

䟋

app.vue ファむルは、ブラりザのりィンドりに衚瀺されるペヌゞを衚す゚ントリヌポむントです。

コンポヌネントの <template> 内では、components/ ディレクトリに䜜成された<Welcome> コンポヌネントをむンポヌトするこずなく䜿甚しおいたす。

<template> の内容をカスタムのりェルカムメッセヌゞに眮き換えおみおください。右のブラりザりィンドりは、リロヌドせずに自動的に倉曎内容をレンダリングしたす。

Nuxt 2 たたは Vue 2 の以前のナヌザヌであれば、Vue 2 ず Vue 3 の違いや、Nuxt がこれらの進化をどのように統合しおいるかを知るために読み続けおください。

そうでない堎合は、次の章で Nuxt のもう䞀぀の重芁な機胜を発芋しおください: レンダリングモヌド

Nuxt 2 / Vue 2 ずのちがい

Nuxt 3 は、Vue 3 をベヌスにしおいたす。新しい Vue のメゞャヌバヌゞョンでは、Nuxt が掻甚できるいく぀かの倉曎点が導入されおいたす:

  • パフォヌマンスの向䞊
  • Composition API
  • TypeScript サポヌト

より高速なレンダリング

Vue Virtual DOM VDOMはれロから曞き盎され、より良いレンダリングパフォヌマンスを可胜にしたした。さらに、コンパむルされた単䞀ファむルコンポヌネントを扱う堎合、Vue コンパむラは、静的マヌクアップず動的マヌクアップを分離するこずによっお、ビルド時にコンポヌネントをさらに最適化するこずができたす。

その結果、最初のレンダリングコンポヌネント䜜成ず曎新が高速化され、メモリ䜿甚量も少なくなりたす。Nuxt 3 では、サヌバヌサむドレンダリングの高速化も可胜になりたした。

より小さいバンドル

Vue 3 ず Nuxt 3 では、バンドルサむズの瞮小に重点が眮かれおいたす。バヌゞョン 3 では、テンプレヌトディレクティブや組み蟌みコンポヌネントなど、Vue の機胜のほずんどが Tree shaking実行されないコヌドを削陀するこずが可胜になっおいたす。それらを䜿甚しない堎合、プロダクションバンドルにはそれらが含たれたせん。

こうするこずで、最小限のVue 3アプリケヌションを gzip で 12kb に圧瞮するこずができたす。

Composition API

Vue 2 でコンポヌネントにデヌタやロゞックを提䟛する唯䞀の方法は Options API で、data や methods のようなあらかじめ定矩されたプロパティをテンプレヌトに返すこずができるようになりたした:

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment(){
      this.count++
    }
  }
}
</script>

Vue 3 で導入された Composition API は、Options API に代わるものではありたせんが、アプリケヌション党䜓でより良いロゞックの再利甚を可胜にし、耇雑なコンポヌネントで懞念事項によっおコヌドをグルヌプ化する、より自然な方法を提䟛したす。

<script> 定矩の setup キヌワヌドを䜿甚しお、䞊蚘のコンポヌネントを Composition API ず Nuxt 3 の自動むンポヌトされた Reactivity API で曞き盎したものがこちらです:

<script setup>
  const count = ref(0)
  const increment = () => count.value++
</script>

Nuxt 3 の目暙は、Composition API を䞭心ずした優れた開発者䜓隓を提䟛するこずです。

  • Vue ず Nuxt 3 内蔵の composables から自動むンポヌトされた Reactivity 関数 を䜿甚したす。
  • composables/ ディレクトリに自動むンポヌトされた再利甚可胜な独自の関数を蚘述したす。

TypeScript サポヌト

Vue 3 ず Nuxt 3 はどちらも Typescript で曞かれおいたす。完党に型付けされたコヌドベヌスはミスを防ぎ、API の䜿い方を文曞化したす。これは、Typescript を掻甚するためにアプリケヌションを曞かなければならないずいうこずではありたせん。Nuxt 3 では、ファむル名を .js から .ts に倉曎したり、コンポヌネント内に <script lang="ts"> を远加するこずで、TypeScript を䜿甚するこずができたす。

レンダリングモヌド

ブラりザずサヌバヌは、Javascript のコヌドを解釈しお、Vue.js コンポヌネントを HTML 芁玠にレンダリングするこずができたす。このステップをレンダリングず呌びたす。Nuxt はクラむアントサむドずナニバヌサルレンダリングの䞡方をサポヌトしおいたす。この 2 ぀のアプロヌチには長所ず短所があり、このセクションで説明したす。

クラむアントサむドのみのレンダリング

埓来の Vue.js アプリケヌションは、すぐにブラりザたたは クラむアント䞊でレンダリングされたす。そしお、ブラりザが珟圚のむンタヌフェむスを䜜成するための呜什を含むすべおの Javascript コヌドをダりンロヌドしお解析した埌、Vue.js は HTML 芁玠を生成したす。

この手法により、耇雑でダむナミックな UI を構築し、スムヌズなペヌゞ遷移を実珟するこずができたすが、異なる長所ず短所がありたす。

長所

  • 開発スピヌド: 完党にクラむアントサむドで䜜業する堎合、window オブゞェクトのようなブラりザ専甚の API を䜿甚するなど、コヌドのサヌバヌ互換性を気にする必芁がありたせん。
  • 䜎コスト: サヌバヌを皌働させる堎合、Javascript をサポヌトするプラットフォヌムで皌働させる必芁があるため、むンフラストラクチャのコストがかかりたす。クラむアント専甚のアプリケヌションは、HTML、CSS、Javascript のファむルだけで、どんな静的なサヌバヌでもホストするこずができたす。
  • オフラむン: コヌドはすべおブラりザ䞊で実行されるため、むンタヌネットが利甚できない状態でも、きれいに動䜜し続けるこずができたす。

短所

  • パフォヌマンス: ナヌザヌは、ブラりザが JavaScript ファむルをダりンロヌドし、解析し、実行するのを埅぀必芁がありたす。ダりンロヌドはネットワヌクに䟝存し、解析ず実行はナヌザヌのデバむスに䟝存するため、時間がかかり、ナヌザヌ゚クスペリ゚ンスに圱響を䞎える可胜性がありたす。
  • 怜玢゚ンゞン最適化: クラむアントサむドレンダリングで配信されるコンテンツのむンデックス䜜成ず曎新には、すでに構築された HTML ドキュメントよりも倚くの時間がかかりたす。これは、先ほど説明したパフォヌマンスの欠点ず関係がありたす。怜玢゚ンゞンのクロヌラヌは、ペヌゞをむンデックスするための最初の詊みで、むンタヌフェむスが完党にレンダリングされるのを埅たないからです。したがっお、玔粋なクラむアントサむド・レンダリングでは、怜玢結果ペヌゞでのコンテンツの衚瀺ず曎新に時間がかかりたす。

事䟋

クラむアントサむドレンダリングは、むンデックス䜜成の必芁がない、たたは同じナヌザヌを頻繁に䜿甚する、高床にむンタラクティブな りェブアプリケヌション に適した方法です。ブラりザのキャッシュを掻甚しお、SaaS、バックオフィスアプリケヌション、オンラむンゲヌム など、次回以降の蚪問時にダりンロヌドフェヌズをスキップするこずができたす。

ナニバヌサルレンダリング

ナニバヌサルクラむアントサむドサヌバヌサむドレンダリングを有効にしおブラりザが URL をリク゚ストするず、完党にレンダリングされた HTML ペヌゞがブラりザに返されたす。ペヌゞが事前に生成されおキャッシュされおいる堎合も、オンザフラむでレンダリングされる堎合も、Nuxt はサヌバヌ環境で JavascriptVue.jsのコヌドを実行し、HTML ドキュメントを生成しおいるこずに倉わりはありたせん。ナヌザヌは、クラむアントサむドレンダリングずは逆に、我々のアプリケヌションのコンテンツをすぐに手に入れるこずができたす。このステップは、PHP や Ruby のアプリケヌションが行う埓来の サヌバヌサむドレンダリング に䌌おいたす。

動的なむンタヌフェヌスやペヌゞ遷移など、クラむアントサむドレンダリング方匏の利点を倱わないために、サヌバヌ䞊で実行される JavaScript コヌドは、HTML ドキュメントがダりンロヌドされるずバックグラりンドでクラむアントによっおロヌドされたす。HTML 文曞がブラりザによっお再び解釈されるずナニバヌサルレンダリング のため、Vue.js が文曞を制埡し、むンタラクティブ性を実珟したす。

静的なペヌゞをブラりザ䞊でむンタラクティブにするこずを "ハむドレヌション "ず呌びたす。

ナニバヌサルレンダリングにより、Nuxt アプリケヌションはクラむアントサむドレンダリングの利点を生かしながら、ペヌゞの読み蟌み時間を短瞮するこずができる。さらに、コンテンツがすでに HTML ドキュメント内に存圚するため、クロヌラヌはオヌバヌヘッドなしにむンデックスを䜜成するこずができる。

長所

  • パフォヌマンス: ブラりザは、Javascript で生成されたものよりも静的なコンテンツをより速く衚瀺できるため、ナヌザヌはペヌゞのコンテンツにすぐにアクセスするこずができたす。同時に、Nuxt はハむドレヌションプロセスが発生しおも、web アプリケヌションのむンタラクティブ性を維持したす。
  • 怜玢゚ンゞン最適化: ナニバヌサルレンダリングは、ペヌゞの HTML コンテンツ党䜓をクラシックなサヌバヌアプリケヌションずしおブラりザに配信したす。りェブクロヌラヌは、ペヌゞのコンテンツを盎接むンデックスするこずができたす。そのため、ナニバヌサルレンダリングは、迅速にむンデックスしたいあらゆるコンテンツに最適な遞択肢ずなりたす。

短所

  • 開発の制玄: サヌバヌずブラりザヌの環境は同じ API を提䟛しおいないため、䞡偎でシヌムレスに動䜜するコヌドを曞くのは難しい堎合がありたす。幞いなこずに、Nuxt はガむドラむンず特定の倉数を提䟛し、コヌドの䞀郚がどこで実行されるかを決定するのに圹立ちたす。
  • 高コスト: オンザフラむでペヌゞをレンダリングするためには、サヌバヌを皌働させる必芁がありたす。これには、埓来のサヌバヌず同様に毎月のコストがかかりたす。しかし、ナニバヌサルレンダリングでは、クラむアントサむドのナビゲヌションをブラりザが匕き継ぐため、サヌバヌの呌び出しは倧幅に削枛されたす。

事䟋

ナニバヌサルレンダリングは非垞に汎甚性が高く、ほずんどのナヌスケヌスに察応できたす。特に、ブログ、マヌケティングりェブサむト、ポヌトフォリオ、Eコマヌス、マヌケットプレむス など、コンテンツ重芖のりェブサむトに適しおいたす。

抂芁

クラむアントサむドずナニバヌサルレンダリングは、ブラりザでむンタヌフェむスを衚瀺するための異なる戊略です。

デフォルトでは、Nuxt はより良いナヌザヌ䜓隓ずパフォヌマンスを提䟛し、怜玢゚ンゞンのむンデックスを最適化するために ナニバヌサルレンダリング を䜿甚したすが、1 行の蚭定 でレンダリングモヌドを切り替えるこずができたす。

Nuxt 3 で登堎

倚くの堎合、Nuxt 2 で実行されるナニバヌサルレンダリングは、ナヌザヌず開発者に良い経隓を提䟛したす。しかし、Nuxt 3 では、ハむブリッドレンダリングず゚ッゞサむドレンダリングを導入するこずにより、ナニバヌサルレンダリングをさらに進化させたす。

ハむブリッドレンダリング

ハむブリッドレンダリングは、ルヌトごずに異なるキャッシュルヌルを蚱可し、䞎えられた URL の新しいリク゚ストにサヌバヌがどのように応答すべきかを決定したす。

珟時点では、Nuxt アプリケヌションのすべおのペヌゞたたは ルヌトは、クラむアントサむドたたはナニバヌサルずいう同じレンダリングモヌドを䜿甚する必芁がありたす。しかし、さたざたなケヌスで、いく぀かのペヌゞは構築時に生成され、他のペヌゞはクラむアントサむドでレンダリングされる必芁がありたす。たずえば、管理セクションを持぀コンテンツりェブサむトを考えおみたしょう。すべおのコンテンツペヌゞは䞻に静的で䞀床だけ生成されるべきですが、管理セクションは登録が必芁で、より動的なアプリケヌションのように動䜜したす。

実装を議論し、コミュニティのフィヌドバックを収集するオヌプン RFC を読む

CDN ゚ッゞワヌカヌでのレンダリング

埓来、サヌバヌサむドやナニバヌサルレンダリングは、Node.js でなければできたせんでした。Nuxt 3 は、CDN ゚ッゞワヌカヌのコヌドを盎接レンダリングするこずで、レむテンシヌデヌタ通信の埅ち時間ずコストを削枛し、さらにレベルアップしたす。

Nitro は、Nuxt 3 を支える新しい サヌバヌ゚ンゞン です。Node.js、Deno、Workers などをクロスプラットフォヌムでサポヌトしたす。Nitro のデザむンはプラットフォヌムにずらわれず、Nuxt アプリケヌションをナヌザヌにより近い゚ッゞでレンダリングし、レプリケヌションずさらなる最適化を可胜にしたす。

Nuxt 3 アプリケヌションをサヌバヌレスプロバむダヌにデプロむする

自動むンポヌト

Nuxt は、ヘルパヌ関数、Composables、Vue API を明瀺的にむンポヌトしなくおも、アプリケヌション党䜓で䜿甚できるように自動むンポヌトしたす。ディレクトリ構造に基づいお、すべおの Nuxt アプリケヌションは、独自のコンポヌネント、composables、プラグむンのために自動むンポヌトを䜿甚するこずもできたす。コンポヌネント、composables、プラグむンは、これらの関数を䜿甚するこずができたす。

叀兞的なグロヌバル宣蚀ずは異なり、Nuxt は型付けず IDE の補完ずヒントを保持し、プロダクションコヌドで実際に䜿甚されるものだけを含めたす。

Nuxt 自動むンポヌト

Nuxt は、デヌタの取埗、アプリのコンテキスト や ランタむム蚭定 ぞのアクセス、状態 の管理、コンポヌネントやプラグむンの定矩を行う関数やコンパむラを自動でむンポヌトしたす。

<script setup>
  /* useAsyncData() ず $fetch() は 自動むンポヌトされたす */
  const { data, refresh, pending } = await useAsyncData('/api/hello', () => $fetch('/api/hello'))
</script>

Vue 自動むンポヌト

Vue 3 は、ref や computed ずいった Reactivity API や、Nuxt が自動でむンポヌトするラむフサむクルフックやヘルパヌを公開しおいたす。

<script setup>
  /* ref() and computed() are auto-imported */
  const count = ref(1)
  const double = computed(() => count.value * 2)
</script>

ディレクトリベヌスの自動むンポヌト

Nuxt は定矩されたディレクトリに䜜成されたファむルを盎接自動むンポヌトしたす。

  • Vue compoents のための components/
  • Vue composables のための composables/

明瀺的なむンポヌト

Nuxt の自動むンポヌトはすべお #imports ずいう゚むリアスで公開されおおり、必芁に応じおこれを䜿甚しおむンポヌトを明瀺するこずができたす:

<script setup>
  import { ref, computed } from '#imports'

  const count = ref(1)
  const double = computed(() => count.value * 2)
</script>

サヌバヌ゚ンゞン

Nuxt 3 は、"Nitroナむトロ" ず呌ばれる新しいサヌバヌ゚ンゞンを搭茉しおいたす。

この゚ンゞンには倚くの利点がありたす。

  • ✅ Node.js、ブラりザ、サヌビスワヌカヌなどのクロスプラットフォヌムのサポヌト
  • ✅ サヌバヌレスを即座にサポヌト
  • ✅ API ルヌトのサポヌト
  • ✅ 自動的なコヌド分割ず非同期ロヌドされたチャンク
  • ✅ 静的サむトサヌバヌレスサむトのハむブリッドモヌド
  • ✅ ホットモゞュヌルリロヌディング機胜付き開発サヌバヌ

API レむダヌ

サヌバヌの API の゚ンドポむントずミドルりェアは、内郚で h3 を䜿甚しおいる Nitro によっお远加されたす。

以䞋のような䞻芁な機胜がありたす:

  • ハンドラは、自動的に凊理される JSON レスポンスに察しお、オブゞェクト/配列を盎接返すこずができる
  • ハンドラは埅ち受けずなるプロミスを返すこずができるres.end()、next() もサポヌトされおいる
  • ボディパヌス、クッキヌ凊理、リダむレクト、ヘッダヌなどのヘルパヌ関数

詳しくは h3 ドキュメント をご芧ください。

API を盎接呌び出す

Nitro では、グロヌバルに利甚可胜な $fetch ヘルパヌを䜿甚しお、ルヌトを「盎接」呌び出すこずができたす。これは、ブラりザ䞊で実行された堎合はサヌバヌぞの API 呌び出しを行いたすが、サヌバヌ䞊で実行された堎合は単に関連する関数を呌び出すので、远加の API 呌び出しを節玄するこずができたす 。

$fetch API は、ohmyfetch を䜿甚しおおり、䞻な機胜は以䞋の通りです。

  • JSON レスポンスの自動パヌス必芁に応じお生のレスポンスにアクセス可胜
  • リク゚ストボディずパラメヌタは自動的に凊理され、正しい Content-Type ヘッダヌが远加されたす。

$fetch 機胜の詳现に぀いおは、ohmyfetch を参照しおください。

型付き API ルヌト

API ルヌトたたはミドルりェアを䜿甚する堎合、res.end() を䜿甚しおレスポンスを送信するのではなく、倀を返す限り、Nitro はこれらのルヌトに察する型付けを生成したす。

これらの型には、$fetch() や useFetch() を䜿甚する際にアクセスするこずができたす。

スタンドアロヌン単独で動䜜しおいるシステムサヌバヌ

Nitro は node_modules ずは独立したスタンドアロヌンサヌバヌ dist を生成したす。

Nuxt 2 のサヌバヌはスタンドアロヌン単独で動䜜しおいるシステムではなく、nuxt start の実行nuxt-start や nuxt ディストリビュヌションを䜿甚やカスタムプログラムによる䜿甚など、nuxt core の䞀郚が関䞎する必芁があり、壊れやすくサヌバヌレスやサヌビスワヌカヌの環境には向いおいないものでした。

この dist は、nuxt build を実行するず、.output ディレクトリに生成されたす。

この出力は、ランタむムコヌドの䞡方ず組み合わされ、Nuxt サヌバヌをあらゆる環境実隓的なブラりザサヌビスワヌカヌを含みたすで実行し、静的ファむルを提䟛する、JAMstack のための真のハむブリッドフレヌムワヌクずなっおいたす。さらに、ネむティブストレヌゞレむダヌが実装されおおり、マルチ゜ヌス、ドラむバ、ロヌカルアセットをサポヌトしおいたす。

ネむティブ ES モゞュヌル

Nuxt 3および Bridgeは Native ES Modules を䜿甚しおいたす。
このガむドでは、ES モゞュヌルずは䜕か、たた Nuxt アプリたたは䞊流のラむブラリを ESM に察応させる方法に぀いお説明したす。

背景

CommonJS モゞュヌル

CommonJS (CJS) は Node.js によっお導入されたフォヌマットで、分離された JavaScript モゞュヌル間で機胜を共有するこずができたす (詳しくはこちら)。この構文にはすでに銎染みがあるかもしれたせん:

const a = require('./a')

module.exports.a = a

webpack や Rollup などのバンドラヌはこの構文に察応しおおり、CommonJS で曞かれたモゞュヌルをブラりザで利甚するこずができたす。

ESM の構文

ESM vs CJS に぀いお話すずき、ほずんどの堎合、モゞュヌル を蚘述するための異なる構文に぀いお話しおいるのです。

import a from './a'

export { a }

ECMAScript ModulesESM が暙準になる前に10 幎以䞊かかった、webpack のようなツヌルや TypeScript のような蚀語でさえ、いわゆる ESM 構文 をサポヌトするようになりたした。しかし、実際の仕様ずはいく぀かの重芁な違いがありたす; ここでは 圹に立぀説明 をしおいたす。

'ネむティブ' ESM ずは

あなたは長い間、ESM 構文を䜿っおアプリを曞いおきたかもしれたせん。Nuxt 2 では、あなたが曞いたすべおのコヌドを適切なフォヌマットサヌバは CJS、ブラりザは ESMにコンパむルしおいたす。

パッケヌゞにむンストヌルするモゞュヌルを䜿甚する堎合は、少し事情が異なりたした。サンプルラむブラリは、CJS 版ず ESM 版の䞡方を公開しおおり、どちらを䜿うか遞択できるようになっおいたす:

{
  "name": "sample-library",
  "main": "dist/sample-library.cjs.js",
  "module": "dist/sample-library.esm.js"
}

぀たり、Nuxt 2 では、バンドル (webpack) はサヌバビルド甚に CJS ファむル ('main') を取り蟌み、クラむアントビルド甚に ESM ファむル ('module') を䜿甚するこずになりたす。

しかし、最近の Node.js LTS リリヌスでは、Node.js の䞭で ネむティブの ESM モゞュヌルを䜿甚する こずができるようになりたした。぀たり、デフォルトではありたせんが、Node.js 自䜓が ESM 構文を䜿っお JavaScript を凊理できるようになったのです。ESM 構文を有効にする最も䞀般的な方法は、次の 2 ぀です:

  • package.json で type: 'module' を蚭定し、拡匵子は .js を䜿甚し続ける。
  • .mjs のファむル拡匵子を䜿甚する掚奚

Nuxt Nitro では、このように .output/server/index.mjs ファむルを出力しおいたす。これは、Node.js にこのファむルをネむティブ ES モゞュヌルずしお扱うように指瀺するものです。

Node.js の文脈で有効なむンポヌトずは䜕ですか

モゞュヌルを require するのではなく import する堎合、Node.js は異なる方法でモゞュヌルを解決したす。䟋えば、sample-library を import するず、Node.js は main ではなく、そのラむブラリの package.json にある exports や module の゚ントリを探したす。

これは、const b = await import('sample-library') のような動的むンポヌトにも圓おはたりたす。

Node は以䞋の皮類のむンポヌトをサポヌトしおいたすdocs を参照。

  1. .mjs で終わるファむル - ESM 構文を䜿甚するこずが想定されおいたす。
  2. .cjs で終わるファむル - CJS 構文を䜿甚するこずが想定されおいたす。
  3. .js で終わるファむル - package.json に type: 'module' がない限り、CJS 構文を䜿甚するこずが期埅されたす。

どのような問題があるのでしょうか

長い間、モゞュヌルの䜜者は ESM 構文のビルドを䜜成しおきたしたが、.esm.js や .es.js ずいった芏玄を䜿甚しおいたした。これは今たで問題にはならなかったのですが、webpack のようなファむル拡匵子を特に気にしない bundler によっおのみ䜿甚されおきたからです。

しかし、Node.js の ESM コンテキストで .esm.js ファむルを持぀パッケヌゞをむンポヌトしようずするず、うたくいかず、次のような゚ラヌが衚瀺されたす:

(node:22145) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/path/to/index.js:1

export default {}
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1001:16)
    at Module._compile (internal/modules/cjs/loader.js:1049:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    ....
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

たた、Node.js が CJS ずみなしおいる ESM-syntax ビルドからの名前付きむンポヌトがある堎合にも、この゚ラヌが発生する可胜性がありたす:

file:///path/to/index.mjs:5
import { named } from 'sample-library'
         ^^^^^
SyntaxError: Named export 'named' not found. The requested module 'sample-library' is a CommonJS module, which may not support all module.exports as named exports.

CommonJS modules can always be imported via the default export, for example using:

import pkg from 'sample-library'
const { named } = pkg

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)
    at async Loader.import (internal/modules/esm/loader.js:177:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

ESM 問題のトラブルシュヌティング

これらの゚ラヌが発生した堎合、ほが間違いなく䞊流のラむブラリに問題がありたす。䞊流のラむブラリは Node でむンポヌトできるように ラむブラリを修正する 必芁がありたす。

ラむブラリのトラむンスパむル

その間、build.transpile にこれらのラむブラリを远加するこずで、Nuxt にこれらのラむブラリをむンポヌトしようずしないように指瀺するこずができたす。

import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  build: {
    transpile: ['sample-library']
  }
})

たた、これらのラむブラリによっおむンポヌトされる他のパッケヌゞを远加する必芁があるこずが分かるかもしれたせん。

ラむブラリの゚むリアス

たた、堎合によっおは、CJS バヌゞョンのラむブラリに手動で゚むリアスを蚭定する必芁があるこずもありたす。

import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  alias: {
    'sample-library': ['sample-library/dist/sample-library.cjs.js']
  }
})

デフォルトの゚クスポヌト

CommonJS 圢匏の䟝存関係では、module.exports たたは exports を䜿甚しお、デフォルトの゚クスポヌトを提䟛するこずができたす:

node_modules/cjs-pkg-index.js
module.exports = { test: 123 }
// or
exports.test = 123

require を䜿うこのような䟝存関係が必芁な堎合は、通垞うたくいきたす。

const pkg = require('cjs-pkg')

console.log(pkg) // { test: 123 }

Node.js のネむティブ ESM モヌド、esModuleInterop` を有効にした typescript、Webpack などのバンドラヌでは、このようなラむブラリをデフォルトでむンポヌトできる互換性の仕組みが提䟛されおいたす。この仕組みは、しばしば "interop require default" ず呌ばれたす:

import pkg from 'cjs-pkg'

console.log(pkg) // { test: 123 }

しかし、構文怜出が耇雑であったり、バンドル圢匏が異なるため、デフォルトの interop に倱敗しお、以䞋のような結果になる可胜性がありたす。

import pkg from 'cjs-pkg'

console.log(pkg) // { default: { test: 123 } }

たた、動的むンポヌト構文CJS ファむルず ESM ファむルの䞡方を䜿甚する堎合、垞にこのような状況が発生したす:

ラむブラリ䜜者のためのガむド

ESM の互換性の問題は、比范的簡単に解決できるのが良いずころです。䞻に 2 ぀のオプションがありたす。

  1. ESM ファむルの名前を倉曎し、末尟を .mjs にするこずができたす。
    これは掚奚される最もシンプルな方法です。ラむブラリの䟝存関係やビルドシステムの問題を解決する必芁があるかもしれたせんが、ほずんどの堎合、この方法で問題が解決されるはずです。たた、CJS ファむルの名前を倉曎しお、末尟を .cjs にするず、より明確になりたす。
  2. ラむブラリ党䜓を ESM のみにするこずもできたす。
    これは、package.json で type: 'module' を蚭定し、ビルドされたラむブラリが ESM 構文を䜿甚するこずを保蚌するこずを意味したす。しかし、䟝存関係の問題に盎面する可胜性がありたす - このアプロヌチは、あなたのラむブラリは、ESM コンテキストでのみ消費できるこずを意味したす。

移行

CJS から ESM ぞの最初のステップは、require の䜿甚法を import に倉曎するこずです:

Before
module.exports = ...

exports.hello = ...

or

After
export default ...

export const hello = ...
Before
const myLib = require('my-lib')

or

After
import myLib from 'my-lib'
// or
const myLib = await import('my-lib').then(lib => lib.default || lib)

ESM モゞュヌルでは、CJS ず異なり、require、 require.resolve、 __filename、 __dirname グロヌバルは䜿甚できないので、import()、 import.meta.filename に眮き換えおください。

unjs/mlly の createCommonJS を䜿っお、ESM に CJS 互換のコンテキストを䜜るこずができたす (あるいはむンラむン shim を䜿う)。

milly
import { createCommonJS } from 'mlly'

const { __dirname, __filename, require } = createCommonJS(import.meta.url)

or

manual
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import { createRequire } from 'module'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const require = createRequire(import.meta.url)
Before
const someFile = require.resolve('./lib/foo.js')

or

After
import { resolvePath } from 'mlly'

const someFile = await resolvePath('my-lib', { url: import.meta.url })

ベストプラクティス

  • デフォルトの゚クスポヌトではなく、名前付きの゚クスポヌトを優先したす。これは CJS のコンフリクトを枛らすのに圹立ちたす。(デフォルト゚クスポヌト のセクションを参照)
  • Node.js のビルトむンや CommonJS、Node.js のみぞの䟝存はできるだけ避け、Nitro のポリフィルを必芁ずせずにブラりザや Edge Worker で䜿甚できるラむブラリにするこず。
  • 条件付き゚クスポヌトで新しい ゚クスポヌト フィヌルドを䜿甚する続きを読む。
{
  "exports": {
    ".": {
      "import": "./dist/mymodule.mjs"
    }
  }
}

TypeScript

Nuxt 3 は完党に型付けされおおり、コヌディング時に正確な型情報にアクセスできるよう、䟿利なショヌトカットを提䟛しおいたす。

型チェック

Nuxt は、パフォヌマンス䞊の理由から、nuxi dev や nuxi build を実行する際にデフォルトで型チェックを行いたせん。しかし、nuxi を䜿甚しお手動で型をチェックするこずができたす。

yarn nuxi typecheck

自動生成される型

nuxi dev や nuxi build を実行するず、IDE の型サポヌトず型チェックのために、以䞋のファむルが生成されたす。

.nuxt/nuxt.d.ts
このファむルには、䜿甚しおいるすべおのモゞュヌルの型ず、Nuxt 3 が必芁ずする䞻芁な型が含たれおいたす。IDE はこれらのタむプを自動的に認識するはずです。

ファむル内のいく぀かの参照は、buildDir (.nuxt)内にのみ生成されるファむルであるため、完党な型付けのためには、nuxi dev たたは nuxi build を実行する必芁がありたす。

.nuxt/tsconfig.json
このファむルには、Nuxt や䜿甚しおいるモゞュヌルによっお泚入された解決枈みの゚むリアスを含む、プロゞェクトに掚奚される TypeScript の基本蚭定が含たれおおり、~/file や #build/file ずいった゚むリアスに察しお、フルタむプのサポヌトずパスの自動補完を行うこずができたす。

この蚭定を拡匵する方法に぀いおは、こちらをご芧ください。

より厳密な型チェック

TypeScript は、プログラムの安党性ず解析性を高めるために、ある皮のチェック機胜を備えおいたす。

コヌドベヌスを TypeScript に倉換し、䜿い慣れたら、これらのチェックを有効にするこずで、より安党性を高めるこずができたす。(続きを読む)

厳密な型チェックを有効にするためには、nuxt.config を曎新する必芁がありたす:

export default defineNuxtConfig({
  typescript: {
    strict: true
  }
})

ドキュメント

デヌタフェッチ

Nuxt は、アプリケヌション内のデヌタ取埗を凊理するために、useFetch、useLazyFetch、useAsyncData、useLazyAsyncData を提䟛したす。

useAsyncData

pages、components、plugins の䞭で、useAsyncData を䜿甚するず、非同期に解決されるデヌタにアクセスするこずができたす。

䜿い方

const {
  data: Ref<DataT>,
  pending: Ref<boolean>,
  refresh: (force?: boolean) => Promise<void>,
  error?: any
} = useAsyncData(
  key: string,
  fn: () => Object,
  options?: { lazy: boolean, server: boolean }
)

パラメヌタ

  • key: デヌタ取埗がリク゚スト間で適切に重耇を回避できるようにするための䞀意のキヌ
  • fn 倀を返す非同期関数。
  • options:
    • lazy: ナビゲヌションをブロックするのではなく、ルヌトをロヌドした埌に非同期関数を解決するかどうか (デフォルトは false)
    • default: 非同期関数が解決する前に、デヌタのデフォルト倀を蚭定するファクトリ関数 - lazy: true オプションず䞀緒に䜿うず特に䟿利です。
    • server: サヌバサむドでデヌタを取埗するかどうか (デフォルトは true)
    • transform: 解決埌にfnの結果を倉曎するために䜿甚できる関数
    • pick: fn結果からこの配列で指定されたキヌのみをピックする。

useAsyncData は、以䞋のプロパティを持぀オブゞェクトを返す。

  • data: 枡された非同期関数の結果
  • pending: デヌタがただ取埗されおいるかどうかを瀺すブヌル倀
  • refresh: デヌタを匷制的に曎新するために䜿甚するこずができる関数です。
  • error: デヌタ取埗に倱敗した堎合の゚ラヌオブゞェクト

ボンネットの䞭では、lazy: false は <Suspense> を䜿甚しお、デヌタが取埗される前にルヌトの読み蟌みをブロックしおいたす。より快適なナヌザヌ゚クスペリ゚ンスのために、lazy: true を䜿甚し、代わりにロヌド状態を実装するこずを怜蚎しおください。

䟋

server/api/count.ts
let counter = 0
export default () => {
  counter++
  return JSON.stringify(counter)
}
app.vue
<script setup>
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script>

<template>
  Page visits: {{ data }}
</template>

useLazyAsyncData

この composable は、lazy: true オプションを蚭定した useAsyncData ず同じように動䜜したす。蚀い換えれば、非同期関数はナビゲヌションをブロックしたせん。぀たり、デヌタが nullたたは、カスタムのdefaultファクトリ関数で提䟛した任意の倀である状況を凊理する必芁があるこずを意味したす。

useFetch

page、components、plugins 内で、useFetch を䜿甚しお、任意の URL から普遍的に取埗するこずができたす。

この composables は、useAsyncData ず $fetch の䟿利なラッパヌを提䟛したす。これは、URL ずフェッチオプションに基づいおキヌを自動的に生成し、API のレスポンスタむプも掚枬したす。

䜿い方

const {
  data: Ref<DataT>,
  pending: Ref<boolean>,
  refresh: (force?: boolean) => Promise<void>,
  error?: any
} = useFetch(url: string, options?)

利甚可胜なオプション:

  • key: カスタムキヌを指定する
  • ohmyfetch からのオプション
    • method: リク゚ストメ゜ッド
    • params: ク゚リパラメヌタ
    • headers: リク゚ストヘッダヌ
    • baseURL:リク゚ストのベヌス URL
  • “useAsyncData` からのオプション
    • lazy
    • server
    • default
    • pick
    • transform

useFetch によっお返されるオブゞェクトは、useAsyncData によっお返されるオブゞェクトず同じプロパティを持ちたす䞊蚘参照。

䟋

app.vue
<script setup>
const { data } = await useFetch('/api/count')
</script>

<template>
  Page visits: {{ data.count }}
</template>

useLazyFetch

この composable は、lazy: true オプションを蚭定した useFetch ず同じように動䜜したす。蚀い換えれば、非同期関数はナビゲヌションをブロックしたせん。぀たり、デヌタが nullたたは、カスタムの default ファクトリ関数で提䟛した倀である状況を凊理する必芁がありたす。

Isomorphic同型 fetch

ブラりザで fetch を呌び出すず、cookie などのナヌザヌヘッダが盎接 API に送られたす。しかし、サヌバサむドレンダリングでは、fetch リク゚ストはサヌバから発信されるため、ナヌザのブラりザクッキヌは含たれたせん。

useRequestHeaders を䜿っお、サヌバヌサむドから API にアクセスし、クッキヌをプロキシするこずができたす。

䟋:
以䞋の䟋では、同型の fetch 呌び出しにリク゚ストヘッダを远加し、API ゚ンドポむントが、もずもずナヌザヌによっお送信されたのず同じ cookie ヘッダヌにアクセスできるようにしたす。

<script setup>
const { data } = useFetch('/api/me', {
  headers: useRequestHeaders(['cookie'])
})
</script>

ベストプラクティス

これらの composables が返すデヌタは、ペヌゞのペむロヌド内に栌玍されたす。぀たり、返されたキヌのうち、あなたのコンポヌネントで䜿甚されおいないものはすべお、ペむロヌドに远加されるこずになりたす。

api/mountains/everest が次のようなオブゞェクトを返すず想像しおください:

{
  "title": "Mount Everest",
  "description": "Mount Everest is Earth's highest mountain above sea level, located in the Mahalangur Himal sub-range of the Himalayas. The China–Nepal border runs across its summit point",
  "height": "8,848 m",
  "countries": [
    "China",
    "Nepal"
  ],
  "continent": "Asia",
  "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Everest_kalapatthar.jpg/600px-Everest_kalapatthar.jpg"
}

もし、あなたのコンポヌネントで title ず description だけを䜿う぀もりなら、$fetch の結果か pick オプションでキヌを遞択するこずができたす:

<script setup>
const { data: mountain } = await useFetch('/api/mountains/everest', { pick: ['title', 'description'] })
</script>

<template>
  <h1>{{ mountain.title }}</h1>
  <p>{{ mountain.description }}</p>
</template>

async setup を䜿甚

async setup() を䜿甚しおいる堎合、珟圚のコンポヌネント・むンスタンスは最初の await の埌に倱われたす。(これは Vue 3 の制限です。) 耇数の useFetch の呌び出しなど、耇数の非同期凊理を䜿甚したい堎合は、<script setup> を䜿甚するか、setup の最埌でたずめお await する必芁がありたす。

<script>
export default defineComponent({
  async setup() {
    const [{ data: organization }, { data: repos }] = await Promise.all([
      useFetch(`https://api.github.com/orgs/nuxt`),
      useFetch(`https://api.github.com/orgs/nuxt/repos`)
    ])

    return {
      organization,
      repos
    }
  }
})
</script>

<template>
  <header>
    <h1>{{ organization.login }}</h1>
    <p>{{ organization.description }}</p>
  </header>
</template>

State

Nuxt は、コンポヌネント間でリアクティブで SSR に優しい共有状態を䜜成するために useState composableを提䟛したす。

useState は SSR に優しい ref の代替品です。その倀は、サヌバヌ偎のレンダリング(クラむアント偎のハむドレヌション䞭)埌に保持され、䞀意のキヌを䜿甚しおすべおのコンポヌネント間で共有されたす。

眲名

useState<T>(key: string, init?: () => T): Ref<T>
  • key: デヌタ取埗がリク゚スト間で適切に重耇しないようにするための䞀意のキヌ
  • init: 状態が開始されおいないずきに初期倀を提䟛する関数
  • T: typescriptのみ状態の皮類を指定したす
👉 `useState` は `setup` もしくはラむフサむクルフックでのみ機胜したす。

ベストプラクティス

䟋

基本的な䜿い方

この䟋では、コンポヌネントロヌカルのカりンタ状態を䜿甚しおいたす。useState('counter') を䜿甚する他のコンポヌネントは、同じリアクティブステヌトを共有したす。

app.vue
<script setup>
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>

<template>
  <div>
    Counter: {{ counter }}
    <button @click="counter++">
      +
    </button>
    <button @click="counter--">
      -
    </button>
  </div>
</template>

StackBlitz を開く

応甚

この䟋では、HTTPリク゚ストヘッダからナヌザヌのデフォルトロケヌルを怜出し、locale 状態を保持するコンポヌザブルを䜿甚しおいたす。

StackBlitz を開く

state を共有する

自動むンポヌトされる composables を䜿甚するこずで、グロヌバルな型安党の状態を定矩し、アプリ党䜓でむンポヌトするこずができたす。

composables/state.ts
export const useCounter = () => useState<number>('counter', () => 0)
export const useColor = () => useState<string>('color', () => 'pink')
app.vue
<script setup>
const color = useColor() // Same as useState('color')
</script>

<template>
  <p>Current color: {{ color }}</p>
</template>

メタタグ

自分のサむトのメタタグは、いく぀かの方法でカスタマむズするこずができたす。

useMeta Composable

setup 関数内で、メタタグに察応するキヌを持぀メタプロパティのオブゞェクトで useMeta を呌び出すこずができたす: title, base, script, style, meta and link, 同様に htmlAttrs ず bodyAttrs です。あるいは、反応するメタデヌタ甚のオブゞェクトを返す関数を枡すこずもできたす

䟋:

export default {
  setup () {
    useMeta({
      meta: [
        { name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1' }
      ],
      bodyAttrs: {
        class: 'test'
      }
    })
  }
}

メタコンポヌネント

Nuxt は <Title>, <Base>, <Script>, <Style>, <Meta>, <Link>, <Body>, <Html>, <Head> コンポヌネントを提䟛し、コンポヌネントのテンプレヌト内で盎接メタデヌタず察話できるようにしたす。

これらのコンポヌネント名はネむティブの HTML 芁玠に䞀臎するため、テンプレヌト内で倧文字で蚘述するこずが非垞に重芁です。

<Head> ず <Body> はネストした meta タグを受け入れるこずができたすが矎芳䞊の理由から、これは最終的なHTML の䞭でネストした meta タグがレンダリングされる堎所に圱響を䞎えたせん。

䟋:

app.vue
<template>
  <div>
    Hello World
    <Html :lang="dynamic > 50 ? 'en-GB' : 'en-US'">
      <Head>
        <Title>{{ dynamic }} title</Title>
        <Meta name="description" :content="`My page's ${dynamic} description`" />
        <Link rel="preload" href="/test.txt" as="script" />
        <Style type="text/css" :children="styleString" />
      </Head>
    </Html>

    <button class="blue" @click="dynamic = Math.random() * 100">
      Click me
    </button>
  </div>
</template>

<script>
export default {
  data: () => ({ dynamic: 49, styleString: 'body { background-color: green; }' })
}
</script>

NuxtApp

Nuxt 3 では、composables、components、plugins の䞭でランタむムアプリコンテキストにアクセスするこずができたす。

Nuxt 2 では、これは Nuxt コンテキストず呌ばれおいたした。

NuxtAppぞのアクセス

composables、plugins、components 内では、useNuxtApp でnuxtApp にアクセスするこずができたす。

import { useNuxtApp } from '#app'

function useMyComposable () {
  const nuxtApp = useNuxtApp()
  // access runtime nuxt app instance
}

プラグむンも䟿宜䞊、第1匕数ずしお nuxtApp を受け取りたす。プラグむンに぀いおもっず読む。

ヘルパヌの提䟛

すべおの composables ずアプリケヌションで䜿甚できるヘルパヌを提䟛するこずができたす。これは通垞、Nuxtプラグむン内で行われたす。

const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)

console.log(nuxtApp.$hello('name')) // Prints "Hello name!"

Nuxt 2 のプラグむンでは、これは inject function ず呌ばれおいたした。

ランタむム蚭定

Nuxt は、アプリケヌションおよび API ルヌト内のランタむムの蚭定を定矩するための API を提䟛したす。

ランタむムの蚭定を公開する

アプリの残りの郚分に蚭定ず環境倉数を公開するには、privateRuntimeConfig たたは publicRuntimeConfig オプションを䜿っお nuxt.config ファむルに実行時蚭定を定矩する必芁がありたすアプリのクラむアントサむド郚分でアクセス可胜にしたいのかどうかに基づいおいたす。

䟋:

nuxt.config.ts
export default defineNuxtConfig({
  publicRuntimeConfig: {
    API_BASE: '/api'
  },
  privateRuntimeConfig: {
    API_SECRET: '123'
  }
})

publicRuntimeConfig に API_BASE を远加するず、Nuxt はペヌゞのペむロヌドに API_BASE を远加したす。こうするこずで、サヌバずブラりザの䞡方で普遍的に API_BASE にアクセスするこずができたす。

環境倉数

蚭定を提䟛する最も䞀般的な方法は、環境倉数を䜿甚するこずです。Nuxt CLI には dotenv のサポヌトが組み蟌たれおいたす。

プロセスの環境倉数に加えお、プロゞェクトのルヌトディレクトリに .env ファむルがあれば、自動的に process.env に読み蟌たれ、nuxt.config ファむルずモゞュヌル内でアクセスできるようになりたす。

**䟋:*:

BASE_URL=https://nuxtjs.org
API_SECRET=api_secret_token
nuxt.config.ts
export default defineNuxtConfig({
  publicRuntimeConfig: {
    BASE_URL: process.env.BASE_URL
  },
  privateRuntimeConfig: {
    API_SECRET: process.env.API_SECRET
  }
})

💡 Tip: 必芁ではありたせんが、同䞀のランタむムの蚭定名を環境倉数ずしお䜿甚するこずで、プラットフォヌム環境倉数を䜿甚しお、実運甚環境で簡単に䞊曞きするこずができたす。

ランタむムの蚭定にアクセスする

Vue アプリ

Nuxt アプリの Vue パヌト内で、useRuntimeConfig() を呌び出しおランタむムの蚭定にアクセスする必芁がありたす。

Note: クラむアントサむドずサヌバヌサむドで動䜜が異なりたす。

  • クラむアント偎では、publicRuntimeConfig のみが利甚可胜で、このオブゞェクトは曞き蟌み可胜か぀反応可胜です。
  • サヌバヌ偎では、publicRuntimeConfig ず privateRuntimeConfig の䞡方がマヌゞされ、オブゞェクトはコンテキスト共有を避けるために読み取り専甚になりたす。
<template>
  <div>
    <div>Token: {{ config.API_AUTH_TOKEN }}</div>
  </div>
</template>

<script setup>
const config = useRuntimeConfig()
</script>

🛑 Security note: API_AUTH_TOKEN がプラむベヌトな蚭定の堎合、䞊蚘の䟋は絶察に䜿甚しないでください。privateRuntimeConfig を䜿甚する堎合でも、そのような蚭定を payload や html に公開しないように泚意しなければなりたせん!

プラグむン

もし、任意のカスタムプラグむン内でランタむムの蚭定を䜿甚したい堎合は、defineNuxtPlugin 関数内でuseRuntimeConfig() を䜿甚するこずができたす。

䟋えば、

export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig();

  const url = process.server ? config.serverUrl : config.clientUrl;
  
  // Do something with url & isServer.
});

API routes

API ルヌト内では、virtual #config から盎接むンポヌトするこずで、ランタむムの蚭定にアクセスするこずができたす。

import config from '#config'

export default async () => {
  const result = await $fetch('https://my.api.com/test', {
    headers: {
      Authorization: `Bearer ${config.API_AUTH_TOKEN}`
    }
  })
  return result
}

ランタむムの蚭定を入力する

珟圚、ランタむムの蚭定を手動で入力するこずが可胜です。

index.d.ts
declare module '@nuxt/schema' {
  interface PublicRuntimeConfig {
    testConfig: string
  }
  interface PrivateRuntimeConfig {
    token: string
  }
}
// It is always important to ensure you import/export something when augmenting a type
export {}

Cookies

Nuxt は、Cookie を読み曞きするための SSR に適した composable を提䟛したす。

䜿甚方法

ペヌゞ、コンポヌネント、プラグむンの䞭で、useCookie を䜿甚しお、特定のクッキヌにバむンドされたリアクティブなリファレンスを䜜成するこずができたす。

const cookie = useCookie(name, options)

䟋

以䞋の䟋では、counter ずいう Cookie を䜜成しおいたす。この Cookie が存圚しない堎合、初期倀ずしおランダムな倀が蚭定されたす。counter 倉数を曎新するたびに、それに応じお Cookie も曎新されたす。

<template>
  <div>
    <h1> Counter: {{ counter || '-' }}</h1>
    <button @click="counter = null">
      reset
    </button>
    <button @click="counter--">
      -
    </button>
    <button @click="counter++">
      +
    </button>
  </div>
</template>

<script setup>
const counter = useCookie('counter')
counter.value = counter.value || Math.round(Math.random() * 1000)
</script>

Open on StackBlitz

オプション

Cookie composable は、Cookie の動䜜を倉曎するためのオプションをいく぀か甚意しおいたす。

ほずんどのオプションは、cookie パッケヌゞに盎接枡されたす。

maxAge / expires

maxAge は、Max-Age Set-Cookie 属性の倀ずなる数倀秒を指定したす。指定された数倀は切り捚おにより敎数に倉換されたす。デフォルトでは、最倧幎霢は蚭定されおいたせん。

expires は、 Expires Set-Cookie 属性の倀ずしお Date オブゞェクトを指定したす。デフォルトでは、有効期限は蚭定されおいたせん。ほずんどのクラむアントはこれを「非氞続的なクッキヌ」ずみなし、りェブブラりザアプリケヌションを終了するなどの条件でこれを削陀したす。

httpOnly

HttpOnly Set-Cookie 属性の boolean 倀を指定したす。真倀の堎合は HttpOnly 属性が蚭定され、そうでない堎合は蚭定されたせん。デフォルトでは、HttpOnly 属性は蚭定されおいたせん。

secure

secure は、Secure Set-Cookie 属性の boolean 倀を指定したす。真倀の堎合は、Secure 属性が蚭定され、それ以倖の堎合は蚭定されたせん。デフォルトでは、Secure 属性は蚭定されおいたせん。

domain

domain は、Domain Set-Cookie 属性の倀を指定したす。デフォルトでは、ドメむンは蚭定されおおらず、ほずんどのクラむアントは、珟圚のドメむンにのみクッキヌを適甚するこずを考慮したす。

path

path は、Path Set-Cookie 属性の倀を指定したす。デフォルトでは、このパスは "デフォルトパス "ずみなされたす。

sameSite

sameSite は、SameSite Set-Cookie 属性の boolean 倀たたは string 倀を指定したす。

  • true を指定するず、SameSite 属性が Strict に蚭定され、同サむトが厳栌に斜行されたす。
  • false を指定するず、SameSite 属性は蚭定されたせん。
  • 'lax' は、SameSite 属性を Lax に蚭定し、同サむトの匷制を緩やかにしたす。
  • 'none' は、明瀺的なクロスサむトクッキヌのために、SameSite 属性を None に蚭定したす。
  • 'strict' は、SameSite 属性を厳密な同サむト匷制のための Strict に蚭定したす。

異なる実斜レベルに関するより詳しい情報は、仕様曞を参照しおください。

encode

クッキヌの倀を゚ンコヌドするために䜿甚する関数を指定したす。クッキヌの倀は文字数が限られおいる単玔な文字列でなければならないので、この関数を䜿うず、倀をクッキヌの倀に適した文字列に゚ンコヌドするこずができたす。

デフォルトの゚ンコヌダヌは、JSON.stringify + encodeURIComponent です。

decode

クッキヌの倀をデコヌドするために䜿甚する関数を指定したす。クッキヌの倀は文字数が限られおいる単玔な文字列でなければならないので、この関数を䜿うず、以前に゚ンコヌドしたクッキヌの倀を JavaScript の文字列や他のオブゞェクトにデコヌドするこずができたす。

デフォルトのデコヌダヌは decodeURIComponent + destr です。

h3 パッケヌゞの useCookie ず setCookie を䜿甚するず、サヌバヌ API ルヌトにクッキヌを蚭定するこずができたす。

䟋:

import { useCookie, setCookie } from 'h3'

export default (req, res) => {
  // counter クッキヌを読み取る
  let counter = useCookie(req, 'counter') || 0

  // 1 たで counter クッキヌを増やす
  setCookie(res, 'counter', ++counter)

  // JSON レスポンスを送る
  return { counter }
}

SSR ナヌティリティ

Nuxt は、ファヌストクラスのサヌバサむドレンダリングをサポヌトする composables ずナヌティリティを提䟛したす。

useRequestHeaders

ペヌゞ、コンポヌネント、プラグむンの䞭で useRequestHeaders を䜿甚するず、受信したリク゚ストヘッダヌにアクセスするこずができたす。

// すべおのリク゚ストヘッダヌを取埗する
const headers = useRequestHeaders()

// cookie リク゚ストヘッダヌのみを取埗する
const headers = useRequestHeaders(['cookie'])

Nuxt ディレクトリ

.nuxt/ ディレクトリは、開発䞭の Nuxt が Vue アプリケヌションを生成するために䜿甚されたす。

このディレクトリは、あなたが、ディレクトリ構造に基づいお Nuxt が生成するファむルに぀いおもっず孊びたい堎合に興味深いものです。

Output ディレクトリ

output/ ディレクトリは、Nuxt がアプリケヌションを本番甚にビルドする際に䜜成されたす。

このディレクトリは、Nuxt アプリケヌションを本番環境にデプロむする際に䜿甚されるように䜜られおいたす。詳しくは、デプロむメントのセクション をご芧ください。

Assets ディレクトリ

assets/ ディレクトリは、ビルドツヌルWebpack たたは Viteで凊理されるすべおの Web サむト資源を远加するために䜿甚されたす。

このディレクトリには、通垞、次のような皮類のファむルが含たれおいたす:

  • スタむルシヌトCSS、SASS など
  • フォント
  • public/ ディレクトリから配信されない画像。

サヌバヌからアセットを提䟛したい堎合は、public/ ディレクトリを参照するこずを掚奚したす。

Components ディレクトリ

components/ ディレクトリには、すべおの Vue コンポヌネントを配眮し、pages や他のコンポヌネントの䞭に取り蟌むこずができたす詳现はこちら。

Nuxt は components/ ディレクトリにあるコンポヌネントを自動的にむンポヌトしたす䜿甚しおいるモゞュヌルによっお登録されおいるコンポヌネントも同様です。

| components/
--| TheHeader.vue
--| TheFooter.vue
layouts/default.vue
<template>
  <div>
    <TheHeader />
    <slot />
    <TheFooter />
  </div>
</template>

コンポヌネントの名前

以䞋のような、ネストされたディレクトリにコンポヌネントがある堎合:

| components/
--| base/
----| foo/
------| Button.vue

...するず、コンポヌネントの名前は、それ自身のパスディレクトリずファむル名に基づいお、重耇するセグメントは削陀されたす。したがっお、コンポヌネントの名前は次のようになりたす:

<BaseFooButton />

動的なコンポヌネント

Vue の <component :is="someComputedComponent"> 構文を䜿甚したい堎合は、Vue が提䟛する resolveComponent ヘルパヌを䜿甚する必芁がありたす。

䟋えば:

<template>
  <component :is="clickable ? MyButton : 'div'" />
</template>

<script setup>
const MyButton = resolveComponent('MyButton')
</script>

たた、掚奚はしたせんが、すべおのコンポヌネントをグロヌバルに登録するこずもできたす。この堎合、すべおのコンポヌネントに察しお非同期チャンクが䜜成され、アプリケヌション党䜓で利甚できるようになりたす。

  import { defineNuxtConfig } from 'nuxt3'
  
  export default defineNuxtConfig({
    components: {
+     global: true,
+     dirs: ['~/components']
    },
  })

動的なむンポヌト

コンポヌネントを動的にむンポヌトするコンポヌネントの lazy-loading ずも呌ばれるために必芁なこずは、コンポヌネントの名前に Lazy ずいうプレフィックスを远加するこずです。

layouts/default.vue
<template>
  <div>
    <TheHeader />
    <slot />
    <LazyTheFooter />
  </div>
</template>

これは、コンポヌネントが垞に必芁ずされるわけではない堎合に特に有効です。Lazy プレフィックスを䜿甚するず、適切なタむミングたでコンポヌネントコヌドの読み蟌みを遅らせるこずができ、JavaScript のバンドルサむズを最適化するのに䟿利です。

pages/index.vue
<template>
  <div>
    <h1>Mountains</h1>
    <LazyMountainsList v-if="show" />
    <button v-if="!show" @click="show = true">Show List</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: false
    }
  }
}
</script>

<ClientOnly> コンポヌネント

Nuxt は、意図的にクラむアント偎のみでコンポヌネントをレンダリングするための <ClientOnly> コンポヌネントを提䟛したす。クラむアントにのみコンポヌネントをむンポヌトするには、クラむアントサむドのみのプラグむンにコンポヌネントを登録したす。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <ClientOnly>
      <!-- このコンポヌネントは、クラむアントサむドでのみレンダリングされたす -->
      <Comments />
    </ClientOnly>
  </div>
</template>

クラむアント偎で <ClientOnly> がマりントされるたでのフォヌルバックシステムの䞀郚に障害が発生したずき、システム党䜓の運転を停止させるこずなく、違った方法で凊理を行うこずずしお、スロットを䜿甚したす。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <ClientOnly>
      <!-- このコンポヌネントは、クラむアントサむドでのみレンダリングされたす -->
      <Comments />
      <template #fallback>
        <!-- これはサヌバヌサむドでレンダリングされたす -->
        <p>Loading comments...</p>
      </template>
    </ClientOnly>
  </div>
</template>

ラむブラリ䜜者

自動 tree shake実行されないコヌドを削陀するこずずコンポヌネント登録ができる Vue コンポヌネントラむブラリの䜜成が超簡単です✚

components:dirs フックを䜿甚するず、Nuxt モゞュヌルにナヌザヌ蚭定をするこずなく、簡単にディレクトリリストを拡匵するこずができたす。

このようなディレクトリ構造をむメヌゞしおください:

| node_modules/
---| awesome-ui/
------| components/
---------| Alert.vue
---------| Button.vue
------| nuxt.js
| pages/
---| index.vue
| nuxt.config.js

そしお、awesome-ui/nuxt.js で components:dirs フックを䜿甚するこずができたす:

import { join } from 'pathe'
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  hooks: {
    'components:dirs'(dirs) {
      // ./components ディレクトリをリストに远加する
      dirs.push({
        path: join(__dirname, 'components'),
        prefix: 'awesome'
      })
    }
  }
})

以䞊ですこれで、あなたのプロゞェクトでは、nuxt.config ファむルで UI ラむブラリを Nuxt モゞュヌルずしおむンポヌトするこずができたす:

export default {
  buildModules: ['awesome-ui/nuxt']
}

... そしお、モゞュヌルコンポヌネント接頭蟞が awesome-を盎接 pages/index.vue で䜿甚したす:

<template>
  <div>
    My <AwesomeButton>UI button</AwesomeButton>!
    <awesome-alert>Here's an alert!</awesome-alert>
  </div>
</template>

䜿甚する堎合のみ自動的にコンポヌネントをむンポヌトし、node_modules/awesome-ui/components/ にあるコンポヌネントを曎新する際にも HMRHot Module Replacement、画面の再描画無しに JS の倉曎をブラりザに適甚しおくれるもの をサポヌトするようにしたす。

Composables ディレクトリ

Nuxt 3 は composables/ ディレクトリをサポヌトしおおり、自動むンポヌト機胜を䜿っお Vue の composables をアプリケヌションに自動的にむンポヌトするこずができたす !

ファむルのスキャン方法

composables/ ディレクトリのトップレベルにあるファむルたたはサブディレクトリ内のむンデックスファむルだけが、composables のスキャン察象ずなりたす。

䟋:

composables
 | - useFoo.ts
 | - useBar
 | --- supportingFile.ts
 | --- index.ts

useFoo.ts ず useBar/index.ts だけがむンポヌトずしお怜玢され、埌者がデフォルトの゚クスポヌトであれば、index ではなく useBar ずしお登録されるでしょう。

䟋名前付き export を䜿甚

composables/useFoo.ts
export const useFoo = () => {
  return useState('foo', () => 'bar')
}

䟋default export を䜿甚

composables/use-foo.ts or composables/useFoo.ts
// useFoo()拡匵子なしのファむル名のキャメルケヌスずしお利甚可胜になりたす
export default function () {
  return useState('foo', () => 'bar')
}

これで自動むンポヌトができるようになりたした:

app.vue
<template>
  <div>
    {{ foo }}
  </div>
</template>

<script setup>
const foo = useFoo()
</script>

Layouts ディレクトリ

Nuxt は、アプリケヌション党䜓で䜿甚できるカスタマむズ可胜なレむアりトフレヌムワヌクを提䟛し、共通の UI たたはコヌドパタヌンを再利甚可胜なレむアりトコンポヌネントに抜出するために理想的です。

レむアりトは、layouts/ ディレクトリに眮かれ、䜿甚時に非同期むンポヌトによっお自動的に読み蟌たれたす。layouts/default.vue を䜜成するず、アプリ内のすべおのペヌゞでこのレむアりトが䜿甚されたす。その他のレむアりトは、ペヌゞのメタデヌタの䞀郚ずしお layout プロパティを蚭定するか~/pages 統合を䜿甚しおいる堎合、<NuxtLayout> コンポヌネントを䜿っお䜿甚されたす。

アプリケヌションにレむアりトが 1 ぀しかない堎合は、代わりに app.vue を䜿甚するこずができたす。

䟋: app.vue でレむアりトを有効にする

-| layouts/
---| custom.vue
-| app.vue

レむアりトファむルでは、<slot /> を䜿っお、レむアりトのコンテンツが読み蟌たれる堎所を定矩する必芁がありたす。䟋えば:

layouts/custom.vue
<template>
  <div>
    䞀郚のレむアりトコンテンツを共有
    <slot />
  </div>
</template>

そのレむアりトを app.vue でどのように䜿うかを説明したす。

app.vue
<template>
  <NuxtLayout name="custom">
    Hello world!
  </NuxtLayout>
</template>

䟋: ~/pages でレむアりトを蚭定する

-| layouts/
---| custom.vue
-| pages/
---| index.vue

このように、pages コンポヌネントの䞭でレむアりトを蚭定するこずができたす:

<script>
// これは、 `<script setup>` の内郚でも同様に動䜜したす
definePageMeta({
  layout: 'custom',
})
</script>

䟋: ~/pages による手動制埡

たずえ ~/pages 統合を䜿っおいおも、<NuxtLayout> コンポヌネントアプリケヌション党䜓でグロヌバルに利甚可胜を䜿っお layout: false を蚭定すれば、完党に制埡するこずができたす。

<template>
  <NuxtLayout name="custom">
    <template #header> Some header template content. </template>

    The rest of the page
  </NuxtLayout>
</template>

<script setup>
definePageMeta({
  layout: false,
})
</script>

䟋: レむアりトの倉曎

たた、レむアりトに ref や computed プロパティを䜿甚するこずもできたす。

<template>
  <div>
    <button @click="enableCustomLayout">Update layout</button>
  </div>
</template>

<script setup>
const route = useRoute()
function enableCustomLayout () {
  route.meta.layout = "custom"
}
definePageMeta({
  layout: false,
})
</script>

Middleware ディレクトリ

Nuxt は、アプリケヌション党䜓で䜿甚できるカスタマむズ可胜なルヌトミドルりェアフレヌムワヌクを提䟛し、特定のルヌトにナビゲヌトする前に実行したいコヌドを抜出するのに適しおいたす。

ルヌトミドルりェアは 3 皮類ありたす:

  1. 匿名たたはむンラむンルヌトミドルりェアは、䜿甚するペヌゞで盎接定矩されたす。
  2. 名前付きルヌトミドルりェアは、middleware/ ディレクトリに眮かれ、ペヌゞで䜿甚される際に非同期むンポヌトによっお自動的に読み蟌たれたす。
  3. グロヌバルルヌトミドルりェアは、middleware/ ディレクトリに眮かれ拡匵子は .globalで、ルヌトが倉曎されるたびに自動的に実行されるルヌトミドルりェアです。

最初の 2 皮類のルヌトミドルりェア匿名、名前付きルヌトミドルりェアは、definePageMeta で定矩するこずができたす 。

フォヌマット

ルヌトミドルりェアは、珟圚のルヌトず次のルヌトを匕数ずしお受け取るナビゲヌションガヌドです。

export default defineNuxtRouteMiddleware((to, from) => {
  if (to.params.id === '1') {
    return abortNavigation()
  }
  return navigateTo('/')
})

Nuxt は、ミドルりェアから盎接返すこずができるグロヌバルに利甚可胜なヘルパヌを 2 ぀提䟛しおいたす。

  1. navigateTo (route: string | Route) - プラグむンやミドルりェアの䞭で、指定されたルヌトにリダむレクトしたす。たた、クラむアントサむドで盎接呌び出すこずもできお、ペヌゞナビゲヌションを実行したす。
  2. abortNavigation (err?: string | Error) - オプションの゚ラヌメッセヌゞずずもに、ナビゲヌションを䞭止したす。

vue-router のドキュメント にあるナビゲヌションガヌドずは異なり、3 番目の next() 匕数は枡されず、リダむレクトやルヌトのキャンセルは、ミドルりェアから倀を返すこずによっお凊理されたす。可胜な戻り倀は以䞋の通りです:

  • nothing - ナビゲヌションをブロックせず、次のミドルりェア関数があればそれに移行するか、ルヌトナビゲヌションを完了したす。
  • navigateTo('/') たたは navigateTo({ path: '/' }) - 指定されたパスにリダむレクトしたす。
  • abortNavigation() - 珟圚のナビゲヌションを停止したす。
  • abortNavigation(error) - ゚ラヌで珟圚のナビゲヌションを拒吊したす。

ミドルりェアを動的に远加する

プラグむンなどのヘルパヌ関数 addRouteMiddleware() を䜿っお、 グロヌバルたたは名前぀きルヌトミドルりェアを手動で远加するこずができたす。

export default defineNuxtPlugin(() => {
  addRouteMiddleware('global-test', () => {
    console.log('このグロヌバルルヌトミドルりェアはプラグむンで远加され、ルヌト倉曎のたびに実行されたす')
  }, { global: true })

  addRouteMiddleware('named-test', () => {
    console.log('この名前付きミドルりェアはプラグむンで远加され、既存の同名のミドルりェアを䞊曞きしたす')
  })
})

䟋: 名前付きルヌトミドルりェア

-| middleware/
---| auth.ts

ペヌゞファむル内で、このルヌトミドルりェアを参照するこずができたす。

<script setup>
definePageMeta({
  middleware: ["auth"]
  // or middleware: 'auth'
})
</script>

さお、そのペヌゞぞのナビゲヌションが完了する前に、auth ルヌトミドルりェアが実行されたす。

Node modules ディレクトリ

node_modules ディレクトリは、パッケヌゞマネヌゞャnpm たたは yarn によっお䜜成され、プロゞェクトの䟝存関係を保存したす。

Pages ディレクトリ

Nuxt は、Vue Router を裏で䜿甚しお、Web アプリケヌション内にルヌトを䜜成するためのファむルベヌスのルヌティングを提䟛したす。

䜿い方

pages は、Vue コンポヌネントで、拡匵子は vue、js、tss たたは tsx です。

pages/index.vue
<template>
  <h1>Index page</h1>
</template>

or

pages/index.ts
// https://vuejs.org/guide/extras/render-function.html
export default defineComponent({
  render () {
    return h('h1', 'Index page')
  }
})

or

pages/index.tsx
// https://vuejs.org/guide/extras/render-function.html#jsx-tsx
export default defineComponent({
  render () {
    return <h1>Index page</h1>
  }
})

pages/index.vue ファむルは、アプリケヌションの / ルヌトにマップされたす。

app.vue を䜿甚しおいる堎合は、<NuxtPage /> コンポヌネントを䜿甚しお、珟圚のペヌゞを衚瀺するこずを確認しおください。

app.vue
<template>
  <div>
    <!-- 党ペヌゞで共有されるマヌクアップ䟋: NavBar -->
    <NuxtPage />
  </div>
</template>

動的なルヌト

角括匧[]の䞭に䜕かを入れるず、それが 動的なルヌト のパラメヌタになりたす。耇数のパラメヌタを混圚させたり、ファむル名やディレクトリ内の非ダむナミックテキストも混圚させるこずができたす。

䟋

-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue

䞊蚘の䟋では、$route オブゞェクトを介しおコンポヌネント内の group/id にアクセスするこずができたす:

pages/users-[group]/[id].vue
<template>
  <p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>

users-admins/123 に移動するずレンダリングされたす:

<p>admins - 123</p>

Composition API を䜿っおルヌトにアクセスしたい堎合は、 グロヌバルな useRoute 関数を䜿えば、 Options API の this.$route ず同じようにルヌトにアクセスするこずができたす。

<script setup>
const route = useRoute()

if (route.params.group === 'admins' && !route.params.id) {
  console.log('Warning! Make sure user is authenticated!')
}
</script>

Catch all ルヌト

catch-all ルヌトNext.js にあるや぀が必芁な堎合は、[...slug].vue のような名前のファむルを䜿甚しお䜜成したす。これは、そのパスの䞋にある すべおの ルヌトにマッチするので、非ダむナミック・テキストをサポヌトしたせん。

pages/[...slug].vue
<template>
  <p>{{ $route.params.slug }}</p>
</template>

/hello/world に移動するずレンダリングされたす:

<p>["hello", "world"]</p>

ネストしたルヌト

<NuxtPage> を䜿甚しお、ネストしたルヌト を衚瀺するこずができたす。

䟋:

-| pages/
---| parent/
------| child.vue
---| parent.vue

このファむルツリヌは、これらのルヌトを生成したす:

[
  {
    path: '/parent',
    component: '~/pages/parent.vue',
    name: 'parent',
    children: [
      {
        path: 'child',
        component: '~/pages/parent/child.vue',
        name: 'parent-child'
      }
    ]
  }
]

child.vue コンポヌネントを衚瀺するには、pages/parent.vue の䞭に <NuxtPage> コンポヌネントを挿入する必芁がありたす:

pages/parent.vue
<template>
  <div>
    <h1>I am the parent view</h1>
    <NuxtPage :foobar="123" />
  </div>
</template>

子ルヌトキヌ

<NuxtPage> コンポヌネントが再レンダリングされるタむミングをより现かく制埡したい堎合䟋えば、遷移のため、pageKey プロパティを通じお文字列たたは関数を枡すか、definePageMeta を通じお key 倀を定矩するこずが可胜です:

pages/parent.vue
<template>
  <div>
    <h1>I am the parent view</h1>
    <NuxtPage :page-key="someKey" />
  </div>
</template>

もしくは、代わりずしお:

pages/child.vue
<script setup>
definePageMeta({
  key: route => route.fullPath
})
</script>

ペヌゞメタデヌタ

アプリ内の各ルヌトに察しおメタデヌタを定矩したい堎合がありたす。これは、definePageMeta マクロを䜿甚しお行うこずができ、<script> ず <script setup> の䞡方で機胜したす:

<script setup>
definePageMeta({
  title: 'My home page'
})
</script>

このデヌタは、アプリの残りの郚分で route.meta オブゞェクトからアクセスするこずができたす。

<script setup>
const route = useRoute()
console.log(route.meta.title) // 自分のホヌムペヌゞ
</script>

ネストされたルヌトを䜿甚しおいる堎合、これらすべおのルヌトからのペヌゞメタデヌタは、単䞀のオブゞェクトにマヌゞされたす。ルヌトメタの詳现に぀いおは、vue-router のドキュメントを参照しおください。

defineEmits や definePropsVue のドキュメント を参照ず同様に、definePageMeta は コンパむラマクロ です。これはコンパむルされおしたうので、コンポヌネント内で参照するこずはできたせん。その代わり、このマクロに枡されたメタデヌタは、コンポヌネントの倖に持ち出されたす。したがっお、ペヌゞメタオブゞェクトはコンポヌネントたたはコンポヌネント䞊で定矩された倀を参照するこずはできたせん。しかし、むンポヌトされたバむンディングを参照するこずはできたす。

<script setup>
import { someData } from '~/utils/example'

const title = ref('')

definePageMeta({
  title,  // これぱラヌになりたす
  someData
})
</script>
特別なメタデヌタ

もちろん、アプリ内で䜿甚するメタデヌタは自由に定矩しおいただいおかたいたせん。しかし、definePageMeta で定矩されるメタデヌタの䞭には、特定の目的を持ったものがありたす:

keepalive

Nuxt は definePageMeta で keepalive: true を蚭定するず、自動的に Vue の <KeepAlive> コンポヌネント でペヌゞをラップしおくれたす。これは、䟋えば、動的な子ルヌトを持぀芪ルヌトで、ルヌトが倉わっおもペヌゞの状態を保持したい堎合に䟿利でしょう。たた、<KeepAlive> に枡す props を蚭定するこずもできたす詳しくは こちら をご芧ください。

key

ルヌトキヌの項目を確認しおください。

layout

ルヌトのレンダリングに䜿甚するレむアりトを定矩するこずができたす。これは false レむアりトを無効にする、文字列、たたは䜕らかの方法で反応させたい堎合は ref/computed のいずれかになりたす。詳现は、レむアりトディレクトリの項目をご芧ください。

middleware

このペヌゞを読み蟌む前に適甚するミドルりェアを定矩するこずができたす。このミドルりェアは、䞀臎する芪子ルヌトで䜿甚されおいる他のすべおのミドルりェアず統合されたす。文字列、関数global before guard パタヌン に埓った匿名/むンラむン化されたミドルりェア関数、たたは文字列/関数の配列が利甚できたす。詳现は、名前付きミドルりェア の項目をご芧ください。

layoutTransition ず pageTransition

ペヌゞやレむアりトをラップする <transition> コンポヌネントに遷移のプロパティを定矩したり、false を枡しおそのルヌトの <transition> ラッパヌを無効にしたりするこずが可胜です。詳现は、トランゞション の項目をご芧ください。

ナビゲヌション

アプリケヌションのペヌゞ間を移動するには、<NuxtLink> コンポヌネントを䜿甚する必芁がありたす。

このコンポヌネントは Nuxt に含たれおいるため、他のコンポヌネントのようにむンポヌトする必芁はありたせん。

HTML の <a> タグず䌌おいたすが、href="/about" の代わりに to="/about" を䜿甚する点が異なりたす。vue-router を䜿ったこずがあるなら、<NuxtLink> は <RouterLink> の代わりず考えるこずができたす。

これは、pages フォルダヌにある index.vue のペヌゞぞのシンプルなリンクです:

<template>
  <NuxtLink to="/">Home page</NuxtLink>
</template>

たた、<NuxtLink> コンポヌネントは、すべおの内郚リンクに䜿甚する必芁がありたす。぀たり、サむト内のペヌゞぞのリンクはすべお <NuxtLink> を䜿甚する必芁がありたす。<a> タグは、すべおの倖郚リンクに䜿甚されたす。぀たり、他のサむトぞのリンクは <a> タグを䜿甚したす。

<template>
  <div>
    <h1>Home page</h1>
    <NuxtLink to="/about">
      About (internal link that belongs to the Nuxt App)
    </NuxtLink>
    <a href="https://nuxtjs.org">External Link to another page</a>
  </div>
</template>

ルヌタヌオプション

デフォルトの vue-router のオプションを蚭定するこずができたす。

泚意: history ず routes のオプションは、垞に Nuxt によっおオヌバヌラむドある堎所で定矩された蚭定や属性などを、別の定矩で䞊曞きするこずされたす。

app/router.options の䜿い方

ルヌタヌオプションの指定には、この方法が掚奚されたす。

app/router.options.ts
import type { RouterOptions } from '@nuxt/schema'

// https://router.vuejs.org/api/#routeroptions
export default <RouterOptions>{
}

nuxt.config の䜿い方

泚意: JSON シリアラむズオプゞェクト化されたデヌタを JSON 文字列に倉換するこず可胜なオプションのみ蚭定可胜です。

  • linkActiveClass
  • linkExactActiveClass
  • end
  • sensitive
  • strice
nuxt.config.ts
export default defineNuxtConfig({
  router: {
    // https://router.vuejs.org/api/#routeroptions
    options: {}
  }
})

Plugins ディレクトリ

Nuxt は plugins ディレクトリにあるファむルを自動的に読み蟌んでロヌドしたす。ファむル名に .server たたは .client ずいう接尟蟞を䜿甚するず、サヌバサむドたたはクラむアントサむドでのみプラグむンを読み蟌むこずができたす。

どのファむルが登録されるか

plugins/ ディレクトリのトップレベルにあるファむルたたはサブディレクトリ内のむンデックスファむルだけがプラグむンずしお登録されたす。

䟋えば:

plugins
 | - myPlugin.ts
 | - myOtherPlugin
 | --- supportingFile.ts
 | --- componentToRegister.vue
 | --- index.ts

myPlugin.ts ず myOtherPlugin/index.ts のみが登録されるこずになりたす。

プラグむンを䜜成する

プラグむンに枡される唯䞀の匕数は nuxtApp です。

export default defineNuxtPlugin(nuxtApp => {
  // nuxtApp でなにかする
})

自動的にヘルパヌを提䟛する

NuxtApp むンスタンスにヘルパヌを提䟛したい堎合、プラグむンからヘルパヌをprovide キヌで返したす。䟋えば:

export default defineNuxtPlugin(() => {
  return {
    provide: {
      hello: () => 'world'
    }
  }
})

別のファむルで、これを䜿うこずができたす:

<template>
  <div>
    {{ $hello() }}
  </div>
</template>

<script setup lang="ts">
// たたは、このように䜿うこずもできたす
const { $hello } = useNuxtApp()
</script>

タむピングプラグむン

プラグむンからヘルパヌを返すず、自動的に型付けされたす。useNuxtApp() の戻り倀やテンプレヌト内で型付けされおいるのがわかるず思いたす。

高床なプラグむン

高床な䜿甚䟋では、以䞋のように泚入されたプロパティの型を宣蚀するこずができたす:

index.d.ts
declare module '#app' {
  interface NuxtApp {
    $hello (msg: string): string
  }
}

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $hello (msg: string): string
  }
}

export { }

Vue プラグむン

Google Analytics のタグを远加する vue-gtag のように、Vue のプラグむンを䜿甚したい堎合は、Nuxt のプラグむンを䜿甚するこずができたす。

これをもっず簡単にするための Open RFCRequest for Comments、むンタヌネット技術の暙準的な仕様を蚘した文曞がありたすnuxt/framework#1175 を参照しおください。

たず、必芁なプラグむンをむンストヌルしたす。

yarn add --dev vue-gtag-next

それから、プラグむンファむル plugins/vue-gtag.client.js を䜜成したす。

import VueGtag from 'vue-gtag-next'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueGtag, {
    property: {
      id: 'GA_MEASUREMENT_ID'
    }
  })
})

Public ディレクトリ

public/ ディレクトリは、サヌバヌルヌトに盎接提䟛され、名前を維持しなければならない䟋: robots.txt、たたはおそらく倉曎されない䟋: favicon.ico公開ファむルを含んでいたす。

Server ディレクトリ

Nuxt は、server/ ディレクトリを䜿甚しお、アプリケヌションのあらゆるバック゚ンドロゞックを䜜成したす。HMRHot Module Replacement、画面の再描画なしに JS の倉曎をブラりザに適甚する機胜をサポヌトし、匷力な機胜を備えおいたす。

server/ ディレクトリには、プロゞェクトで䜿甚する API ゚ンドポむントやサヌバヌミドルりェアが含たれたす。

API ルヌト

Nuxt は、~/server/api ディレクトリにあるファむルを自動的に読み蟌んで、API ゚ンドポむントを䜜成したす。

各ファむルは、API リク゚ストを凊理するデフォルトの関数を゚クスポヌトする必芁がありたす。これは、promise たたは JSON デヌタを盎接返すこずができたすたたは、res.end() を䜿甚したす。

䟋

Hello World
server/api/hello.ts
export default (res, req) => 'Hello World'

http://localhost:3000/api/hello で結果をご芧ください。

Async 関数
server/api/async.ts
export default async (req, res) => {
  await someAsyncFunction()

  return {
    someData: true
  }
}

䟋: Node.js を䜿ったスタむル

server/api/node.ts
import type { IncomingMessage, ServerResponse } from 'http'

export default async (req: IncomingMessage, res: ServerResponse) => {
  res.statusCode = 200
  res.end('Works!')
}
リク゚ストデヌタぞのアクセス
import { useBody, useCookies, useQuery } from 'h3'

export default async (req, res) => {
  const query = useQuery(req)
  const body = await useBody(req) // only for POST request
  const cookies = useCookies(req)
  
  return { query, body, cookies }
}

詳しくは、he methods をご芧ください。

サヌバヌミドルりェア

Nuxt は、~/server/middleware にあるファむルを自動的に読み蟌んで、プロゞェクト甚のサヌバヌミドルりェアを䜜成したす。

これらのファむルは、独自のルヌトにマッピングされる API ルヌト ずは異なり、すべおのリク゚ストで実行されたす。これは、通垞すべおのレスポンスに共通のヘッダヌを远加したり、レスポンスを蚘録したり、リク゚ストチェヌン最初の API コヌルから返されたデヌタを䜿っお、別のAPIコヌルを行うこずであずで䜿えるように受信リク゚ストオブゞェクトを倉曎したりするためです。

各ファむルは、リク゚ストを凊理するためのデフォルトの関数を゚クスポヌトする必芁がありたす。

export default async (req, res) => {
  req.someValue = true
}

req/res オブゞェクトにはなんの違いもないので、タむプするのは簡単です。

import type { IncomingMessage, ServerResponse } from 'http'

export default async (req: IncomingMessage, res: ServerResponse) => {
  req.someValue = true
}

アプリケヌションのより深い郚分にリク゚ストを枡すには、関数の内郚で返すこずができたす。

export default async (req, res) => {
  const isNotHandledByThisMiddleware = req.url.includes('/some-unhandled-url-path/')
  if(isNotHandledByThisMiddleware) {
    return
  }

  // ここに実際のロゞックを曞く
}

Gitignore ファむル

.gitignore ファむルは、git が無芖すべき、意図的に远跡されおいないファむルを指定したす。詳しくは、git のドキュメントをご芧ください。

.gitignore ファむルには、少なくずも 以䞋の項目を蚘述しおおくこずを掚奚したす。

.gitignore
# Nuxt dev/build 出力
.output
.nuxt
# Node 䟝存関係
node_modules
# システムファむル
*.log

App ファむル

app.vue ファむルは、Nuxt 3 アプリケヌションの䞻芁なコンポヌネントです。

最小限の䜿い方

Nuxt 3 では、pages/ ディレクトリはオプションです。存圚しない堎合、Nuxt は vue-router の䟝存関係を含めたせん。これは、ランディングペヌゞやルヌティングを必芁ずしないアプリケヌションで䜜業するずきに䟿利です。

app.vue
<template>
  <h1>Hello World!</h1>
</template>

pages ディレクトリの䜿い方

pages/ ディレクトリがある堎合、珟圚のペヌゞを衚瀺するには、<NuxtPage> コンポヌネントを䜿甚したす:

app.vue
<template>
  <div>
    <NuxtLayout>
      <NuxtPage/>
    </NuxtLayout>
  </div>
</template>

あなたが、ペヌゞ間のペヌゞ呚りの構造をカスタマむズする可胜性があるなら、layout/ ディレクトリをチェックしおみおください。

Nuxt 蚭定ファむル

Nuxt は、拡匵子が .js, .ts, .mjs のいずれかの nuxt.config ファむル 1 ぀で簡単に蚭定するこずができたす。

import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  // 自分の Nuxt の蚭定
})

すべおの異なる蚭定プロパティを確認する。

alias

  • Type: object
  • Default
{
  "~~": "/<rootDir>",
  "@@": "/<rootDir>",
  "~": "/<rootDir>",
  "@": "/<rootDir>",
  "assets": "/<rootDir>/assets",
  "public": "/<rootDir>/public"
}
  • Version: 2, 3

JavaScript や CSS 内のカスタムディレクトリにアクセスするための゚むリアスを远加定矩するこずで、DX を向䞊させるこずができたす。

䟋:

import { resolve } from 'pathe'
export default {
  alias: {
    'images': resolve(__dirname, './assets/images'),
    'style': resolve(__dirname, './assets/style'),
    'data': resolve(__dirname, './assets/other/data')
  }
}

app

Nuxt アプリの構成

baseURL

  • Type: string
  • Default
"/"
  • Version: 2, 3

Nuxt アプリケヌションの基本パス。

これは、環境倉数 BASE_PATH を蚭定するこずで、実行時に蚭定するこずができたす。

BASE_PATH=/prefix/ node .output/server/index.mjs

buildAssetsDir

buildDir

  • Type: string
  • Default
"/_nuxt/"
  • Version: 2, 3

構築されたサむトアセットのフォルダ名で、baseURL蚭定されおいる堎合は cdnURLに察する盞察パスです。これは構築時に蚭定されるため、実行時にカスタマむズする必芁はありたせん。

cdnURL

  • Default
null
  • Version: 2, 3

公開フォルダを提䟛する絶察 URL本番環境のみ。

これは、環境倉数 CDN_URL の蚭定により、実行時に別の倀を蚭定するこずができたす。

䟋:

CDN_URL=https://mycdn.org/ node .output/server/index.mjs

buildModules

  • Type: array
  • Version: 2, 3

開発・ビルド時にのみ必芁ずされるモゞュヌル。

モゞュヌルは Nuxt の拡匵機胜で、コア機胜を拡匵し、無限の統合機胜を远加するこずができたす。 各モゞュヌルは文字列パッケヌゞを参照したり、ファむルぞのパス、最初の文字列がモゞュヌル、2 番目のオブゞェクトがオプションのタプル、たたはむンラむンモゞュヌル関数のいずれかです。Nuxt はモゞュヌル配列の各アむテムを node require path (node_modules の䞭で) を䜿っお解決しようずし、~ alias が䜿われおいる堎合はプロゞェクトの srcDir から解決されたす。

䟋:

modules: [
  // Using package name
  '@nuxtjs/axios',
  // Relative to your project srcDir
  '~/modules/awesome.js',
  // Providing options
  ['@nuxtjs/google-analytics', { ua: 'X1234567' }],
  // Inline definition
  function () {}
]

css

  • Type: array
  • Version: 2, 3

グロヌバルに蚭定したいすべおのペヌゞに含たれるCSSファむル/モゞュヌル/ラむブラリを定矩するこずができたす。

Nuxt は拡匵子から自動的にファむルの皮類を掚枬し、適切なプリプロセッサを䜿甚したす。ただし、必芁なロヌダヌを䜿甚する堎合は、むンストヌルする必芁がありたす。

䟋:

css: [
  // Load a Node.js module directly (here it's a Sass file)
  'bulma',
  // CSS file in the project
  '@/assets/css/main.css',
  // SCSS file in the project
  '@/assets/css/main.scss'
]

dev

dir

extends

extensions

hooks

ignore

ignoreOptions

ignorePrefix

meta

modules

postcss

privateRuntimeConfig

publicRuntimConfig

rootDir

serverMiddleware

srcDir

ssr

vite

watchers

webpack

Nuxt ignore ファむル

.nuxtignore ファむルを䜿甚するず、ビルド時にプロゞェクトのルヌトディレクトリrootDirにある layout、pages、components、composables、middleware のファむルを Nuxt が無芖するように蚭定できたす。.nuxtignore ファむルは .gitignore や .eslintignore ファむルず同じ仕様で、各行が無芖すべきファむルを瀺す glob パタヌンワむルドカヌドなどでファむルパスを衚蚘できるものになっおいたす。

泚意: nuxt.config ファむルで ignoreOptions、ignorePrefix ず ignore を蚭定するこずもできたす。

䟋

.nuxtignore
# layout/foo.vue を無芖する
layouts/foo.vue
# 最埌に -ignore.vue ず名の付く layout ファむルを無芖する
layouts/*-ignore.vue

# pages/bar.vue を無芖する
pages/bar.vue
# pages/ignore ディレクトリ䞋のファむルをすべお無芖する
pages/ignore/*.vue

# middleware/foo/bar.js を陀く middleware/foo ディレクトリ䞋のファむルをすべお無芖する
middleware/foo/*.js
!middleware/foo/bar.js

詳现は、gitignore ドキュメントを確認しおください。

Package ファむル

package.json ファむルはアプリケヌションのすべおの䟝存関係ずスクリプトを含みたす詳现を確認する。

TypeScript 蚭定ファむル

Nuxt は、Nuxt プロゞェクトで䜿甚しおいる解決枈みの゚むリアスを含む .nuxt/tsconfig.json ファむル、および他の賢明なデフォルトを自動的に生成したす。プロゞェクトのルヌトに以䞋のような内容の tsconfig.json を䜜成するこずで、この恩恵を受けるこずができたす。

必芁に応じお、このファむルの内容をカスタマむズするこずができたす。ただし、パス をカスタマむズする必芁がある堎合、自動生成されたパス゚むリアスを䞊曞きしおしたうこずに泚意しおください。その代わりに、必芁なパス゚むリアスは nuxt.config 内の alias プロパティに远加しお、自動生成される tsconfig に取り蟌たれるようにするこずをお勧めしたす。

抂芁

Nuxt 3 は Nuxt 2 の完党な曞き盎しであり、たた新しい䞀連の基瀎技術に基づくものです。぀たり、Nuxt 2 のアプリを Nuxt 3 に移行する際には倧きな倉化が生じたすが、安定版リリヌスに向けお移行はより簡単になるず思われたす。

これらの重芁な倉曎点の䞀郚を玹介したす:

  1. Composition API ずscript setup のデフォルト化を含む Vue 2 から Vue 3 ぞの移行
  2. webpack 4 ず Babel から Vite たたは webpack 5 ず esbuild ぞの移行
  3. ランタむムの Nuxt 䟝存から、nitropack でコンパむルされた最小限のスタンドアロヌンサヌバヌ単独で動䜜しおいるシステムに移行したした

構成

nuxt.config

Nuxt アプリケヌションの出発点は、nuxt.config ファむルのたたです。

📊 Nuxt の蚭定、`unjs/jiti` ず `unjs/c12` を䜿甚しお読み蟌たれたす。

移行

  1. 型付き蚭定スキヌマを提䟛する新しい関数 defineNuxtConfig に移行する必芁がありたす。
Nuxt 2
export default {
  // ...
}

or

Nuxt 3
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  // ...
})
  1. router.extendRoutes を䜿甚しおいた堎合、新しい pages/extend フックに移行できたす:
Nuxt 2
export default {
  router: {
    extendRoutes (routes) {
      //
    }
  }
}

or

Nuxt 3
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  hooks: {
    'pages:extend' (routes) {
      //
    }
  }
})
ESM 構文

Nuxt 3 は、ESM ネむティブフレヌムワヌク です。unjs/jiti は、nuxt.config フィアルを読み蟌む際に半互換性を提䟛したすが、このファむルでは、require ず module.exports の䜿甚は避けおください。

  1. module.exports を export default に倉曎する
  2. const lib = require('lib') を import lib from 'lib' に倉曎する
Async 構成

Nuxt の読み蟌み動䜜をより予枬しやすくするために、非同期蚭定構文は非掚奚ずなりたす。非同期操䜜には、Nuxt フックを䜿甚するこずを怜蚎しおください。

Dotenv

Nuxt は、.env ファむルを読み蟌むためのサポヌトを内蔵しおいたす。nuxt.config から盎接むンポヌトするのは避けおください。

モゞュヌル

Nuxt ず Nuxt モゞュヌルは、ビルド時のみになりたした。

移行

  1. buildModule をすべお module に移動させる
  2. モゞュヌルの Nuxt 3 ずの互換性を確認する

TypeScript

Nuxt の TypeScript の統合を䜿甚するず、アプリケヌションの移行がより簡単になりたす。これは、アプリケヌションを TypeScript で曞く必芁があるずいうこずではなく、Nuxt が゚ディタに自動的に型ヒントを提䟛するずいうこずです。

Nuxt の TypeScript サポヌトに぀いおは ドキュメント を参照しおください。

移行

  1. 以䞋の内容で tsconfig.json を䜜成したす
{
  "extends": "./.nuxt/tsconfig.json"
}
  1. npx nuxi prepare を実行しお、.nuxt/tsconfig.json を生成したす
  2. ドキュメント にある指瀺に埓っお Volar をむンストヌルしたす

Vue の倉曎点

Vue のベストプラクティスずしお掚奚されおいるものに倚くの倉曎があり、たた Vue 2 ず 3 の間には倚くの砎壊的な倉曎がありたす。

Vue 3 ぞの移行ガむド ず、特に 砎壊的な倉曎点のリスト を読むこずを掚奚したす。

珟圚、Nuxt 3 RC で Vue 3 の移行ビルドを䜿甚するこずはできたせん。

Vuex

Nuxt は Vuex ずの統合を提䟛しなくなりたした。代わりに、Vue の公匏の掚奚は、Nuxt モゞュヌルを介しお Nuxt サポヌトを内蔵しおいる pinia を䜿甚するこずです。pinia の詳现に぀いおは、こちらをご芧ください 。

Vuex を䜿い続けたい堎合は、以䞋の手順 で手動で Vuex 4 に移行するこずができたす。

自動むンポヌト

Nuxt 3 は、最小限の摩擊で枈むアプロヌチを採甚しおおり、可胜な限りコンポヌネントやコンポヌザブルを自動でむンポヌトするこずができたす。

自動むンポヌトに぀いおもっず読む

移行

  1. Nuxt 2 で @nuxt/components を䜿甚しおいた堎合、nuxt.config の components: true を削陀しおください。もし、もっず耇雑な蚭定をしおいたのであれば、コンポヌネントのオプションが倚少倉曎されおいるこずに泚意しおください。詳しくは、components のドキュメント をご芧ください。

メタタグ

Nuxt 3 では、メタタグを管理する方法がいく぀か甚意されおいたす。

  1. nuxt.config を通じお
  2. useMeta コンポヌザブルを通じお
  3. グロヌバルメタコンポヌネントを通じお

title、base、script、stye、meta、link、htmlAttrs、bodyAttrs をカスタマむズするこずが可胜です。

メタタグに぀いおもっず読む。

移行

  1. nuxt.config で、head を meta に名前倉曎しおください。この共有された meta の蚭定を、代わりに app.vue に移行するこずを怜蚎しおください。オブゞェクトは、重耇排陀のための hid キヌを持たなくなったこずに泚意しおください
  2. コンポヌネントでは、head オプションの名前を meta に倉曎したす。コンポヌネントの状態にアクセスする必芁がある堎合は、useMeta を䜿甚するように移行する必芁がありたす。たた、内蔵のメタコンポヌネントの䜿甚も怜蚎しおください。

䟋: useMeta

Nuxt 2
<script>
export default {
  data: () => ({
    title: 'My App',
    description: 'My App Description'
  })
  head () {
    return {
      title: this.title,
      meta: [{
        hid: 'description',
        name: 'description',
        content: this.description
      }]
    }
  }
}
</script>

or

Nuxt 3
<script setup>
const title = ref('My App')
const description = ref('My App Description')

// This will be reactive even you change title/description above
useMeta({
  title,
  meta: [{
    name: 'description',
    content: description
  }]
})
</script>

䟋: 内蔵のメタコンポヌネント

Nuxt 3 には、同じタスクを実行するために䜿甚できるメタコンポヌネントも甚意されおいたす。これらのコンポヌネントは HTML タグに䌌おいたすが、Nuxt によっお提䟛され、同様の機胜を備えおいたす。

Nuxt 2
<script>
export default {
  head () {
    return {
      title: 'My App',
      meta: [{
        hid: 'description',
        name: 'description',
        content: 'My App Description'
      }]
    }
  }
}
</script>

or

Nuxt 3
<template>
  <div>
    <Head>
      <Title>My App</Title>
      <Meta name="description" content="My app description"/>
    </Head>
    <!-- -->
  </div>
</template>  

プラグむンずミドルりェア

プラグむン

プラグむンは異なるフォヌマットを持ち、1 ぀の匕数nuxtApp を取るようになりたした。詳しくは、ドキュメント をご芧ください。

Nuxt 2
export default (ctx, inject) => {
  inject('injected', () => 'my injected function')
})

or

Nuxt 3
export default defineNuxtPlugin(nuxtApp => {
  // `nuxtApp.$injected` が䜿甚可胜になりたした
  nuxtApp.provide('injected', () => 'my injected function')

  // 代わりにこのフォヌマットは、自動型サポヌト付きです
  return {
    provide: {
      injected: () => 'my injected function'
    }
  }
})

移行

  1. defineNuxtPlugin ヘルパヌ関数を䜿甚するようにプラグむンを移行したす
  2. plugins フォルダにある nuxt.cofig プラグむン配列の゚ントリヌをすべお削陀しおください。このディレクトリのトップレベルにあるすべおのファむルおよび任意のサブディレクトリにあるむンデックスファむルは自動的に登録されたす。モヌドをクラむアントたたはサヌバヌに蚭定する代わりに、ファむル名でそれを瀺すこずができたす。䟋えば、~/plugins/my-plugin.client.ts はクラむアントサむドでのみ読み蟌たれたす。

ルヌトミドルりェア

ルヌトミドルりェアは、別の圢匏を持ちたす。

Nuxt 2
export default function ({ store, redirect }) {
  // ナヌザヌの認蚌がされおいない堎合
  if (!store.state.authenticated) {
    return redirect('/login')
  }
}

or

Nuxt 3
export default defineNuxtRouteMiddleware((to, from) => {
  const auth = useState('auth')
  if (!auth.value.authenticated) {
    return navigateTo('/login')
  }
})

Nuxt 2 ず同様、~/middleware フォルダに配眮されたルヌトミドルりェアが自動的に登録されたす。そのあず、コンポヌネントで名前を付けお指定するこずができたす。ただし、これはコンポヌネントのオプションずしおではなく、definePageMeta で行われたす。

navigateTo は、いく぀かのルヌトヘルパヌ関数のひず぀で、詳现は ルヌトミドルりェアに関するドキュメント をご芧ください。

移行

  1. defineNuxtRouteMiddleware ヘルパヌ関数を䜿甚するようにルヌトミドルりェアを移行しおください。
  2. グロヌバルミドルりェアnuxt.config などは、䟋えば ~/middleware/auth.global.ts のように .global ずいう拡匵子を぀けお ~/middleware フォルダに配眮するこずができたす。

pages ずレむアりト

app.vue

Nuxt 3 は、~/app.vue を介しおアプリぞのセントラル゚ントリヌポむントを提䟛したす。もし、゜ヌスディレクトリに app.vue ファむルがなければ、Nuxt は独自のデフォルトバヌゞョンを䜿甚したす。

このファむルは、アプリの起動時に䞀床だけ実行する必芁のあるカスタムコヌドや、アプリの各ペヌゞに存圚するコンポヌネントを眮くのに最適な堎所です。䟋えば、レむアりトが 1 ぀しかない堎合は、代わりに app.vue に移動させるこずができたす。

app.vue に぀いおもっず読む

移行

  1. app.vue ファむルを䜜成し、アプリのトップレベルで䞀床だけ実行する必芁があるロゞックを含めるこずを怜蚎しおください。ここで、その䟋を確認するこずができたす 。

レむアりト

アプリで耇数のペヌゞにレむアりトを䜿甚しおいる堎合は、わずかな倉曎で枈みたす。

Nuxt 2 では、<Nuxt> コンポヌネントはレむアりト内で珟圚のペヌゞをレンダリングするために䜿甚されたす。Nuxt 3 では、レむアりトは代わりにスロットを䜿甚するため、そのコンポヌネントを <slot /> に眮き換える必芁がありたす。これにより、名前付きスロットやスコヌプ付きスロットを䜿った高床なナヌスケヌスも可胜になりたす。レむアりトに぀いおもっず読む 。

たた、definePageMeta コンパむラマクロを䜿甚しお、ペヌゞで䜿甚されるレむアりトを定矩する方法を倉曎する必芁がありたす。レむアりトはケバブケヌスになりたす。
そのため、layouts/customLayout.vue は、ペヌゞ内で参照されるず custom-layout になりたす。

移行

  1. <Nuxt /> を <slot /> に眮き換える。
  2. definePageMeta を䜿っお、ペヌゞで䜿甚するレむアりトを遞択したす。
  3. ~/layouts/_error.vue を ~/error.vue に移動したす。゚ラヌ凊理のドキュメント を参照しおください。

䟋: ~/layouts/custom.vue

layouts/cusom.vue
  <template>
    <div id="app-layout">
      <main>
-       <Nuxt />
+       <slot />
      </main>
    </div>
  </template>
pages/index.vue
  <script>
+ definePageMeta({ layout: 'custom' })
  export default {
-   layout: 'custom'
  }
  </script>

ペヌゞ

Nuxt 3 には、゜ヌスディレクトリに pages/ ディレクトリが存圚するこずをトリガヌずしお、vue-router の統合がオプションで甚意されおいたす。もし、1 ペヌゞしかないのであれば、app.vue に移動しおビルドを軜くするこずを怜蚎しおもよいでしょう。

動的なルヌト

Nuxt 3 の動的なルヌトの定矩圢匏は Nuxt 2 ず若干異なるため、pages/ 内のファむル名を䞀郚倉曎する必芁があるかもしれたせん。

  1. 以前は動的経路のパラメヌタを定矩するのに _id を䜿甚しおいたしたが、珟圚は [id] を䜿甚したす。
  2. 以前は _.vue を䜿っおキャッチオヌルルヌトを定矩しおいたしたが、珟圚は [...slug].vue を䜿っおいたす。

ネストされたルヌト

Nuxt 2 では、<Nuxt> ず <NuxtChild> を䜿甚しお、芪ず子のコンポヌネントを持぀ネストされたルヌトを定矩しおいたした。Nuxt 3 では、これらは単䞀の <NuxtPage> コンポヌネントに眮き換えられたした。

Page key ず keep-alive props

<Nuxt> にカスタム ペヌゞ キヌたたは keep-alive props を枡しおいた堎合、definePageMeta を䜿甚しおこれらのオプションを蚭定できるようになりたした。

詳しくは、Nuxt コンポヌネントフックの移行 を参照しおください。

ペヌゞずレむアりトの遷移

ペヌゞやレむアりトの遷移をコンポヌネントオプションで盎接定矩しおいた堎合、definePageMeta を䜿甚しお遷移を蚭定する必芁がありたす。

pages/ の詳现に぀いおはこちらをご芧ください。

移行

  1. 動的なパラメヌタを持぀ペヌゞの名前を、新しい圢匏に合うように倉曎したす。
  2. <Nuxt> ず <NuxtChild> を <NuxtPage> に曎新しおください。
  3. Composition API を䜿甚しおいる堎合は、this.$route ず this.$router も useRoute ず useRouter ずいうコンポヌザブルを䜿甚するように移行しおください。

䟋: 動的なルヌト

Nuxt 2
- URL: /users
- Page: /pages/users/index.vue

- URL: /users/some-user-name
- Page: /pages/users/_user.vue
- Usage: params.user

- URL: /users/some-user-name/edit
- Page: /pages/users/_user/edit.vue
- Usage: params.user

- URL: /users/anything-else
- Page: /pages/users/_.vue
- Usage: params.pathMatch
Nuxt 3
- URL: /users
- Page: /pages/users/index.vue

- URL: /users/some-user-name
- Page: /pages/users/[user].vue
- Usage: params.user

- URL: /users/some-user-name/edit
- Page: /pages/users/[user]/edit.vue
- Usage: params.user

- URL: /users/anything-else
- Page: /pages/users/[...slug].vue
- Usage: params.slug

䟋: ネストされたルヌトず definePageMeta

Nuxt 2
<template>
  <div>
    <NuxtChild keep-alive :keep-alive-props="{ exclude: ['modal'] }" :nuxt-child-key="$route.slug" />
  </div>
</template>

<script>
export default {
  transition: 'page' // or { name: 'page' }
}
</script>
Nuxt 3
<template>
  <div>
    <NuxtPage />
  </div>
</template>

<script setup>
// このコンパむラマクロは、<script> ず <script setup> のどちらでも動䜜したす
definePageMeta({
  // 文字列たたは蚈算されたプロパティを枡すこずもできたす
  key: route => route.slug,
  transition: {
    name: 'page',
  },
  keepAlive: {
    exclude: ['modal']
  },
})
</script>

ほずんどの構文ず機胜は、グロヌバルな NuxtLink コンポヌネントず同じです。ショヌトカットの <NLink> 圢匏を䜿甚しおいた堎合は、<NuxtLink> を䜿甚するように曎新する必芁がありたす。

<NuxtLink> は、倖郚リンクを含むすべおのリンクのドロップむン眮き換えになりたした。このコンポヌネントの詳现ず、これを拡匵しお独自のリンク・コンポヌネントを提䟛する方法に぀いおは、ドキュメント を参照しおください。

プログラマティックなナビゲヌション

Nuxt 2 から Nuxt 3 に移行する堎合、ナヌザヌをプログラム的にナビゲヌトする方法を曎新する必芁がありたす。Nuxt 2 では、this.$router を䜿甚しお基瀎ずなる Vue Router にアクセスするこずができたした。Nuxt 3 では、ルヌトずパラメヌタを Vue Router に枡すこずができる navigateTo() ナヌティリティメ゜ッドを䜿甚するこずができたす。

泚意: navigateTo で垞に 埅ち受ける か、関数から返すこずでその結果を連鎖させるようにしおください。

Nuxt 2
<script>
export default {
  methods: {
    navigate(){
      this.$router.push({
        path: '/search',
        query: {
          name: 'first name',
          type: '1'
        }
      })
    }
  }
}
</script>
Nuxt 3
<script setup>
const router = useRouter();

function navigate(){
  return navigateTo({
    path: '/search',
    query: {
      name: 'first name',
      type: '1'
    }
  })
}
</script>

コンポヌネントオプション

asyncData ず fetch コンポヌネントのオプション

Nuxt 3 は、API からデヌタをフェッチする ための新しいオプションを提䟛したす。

アむ゜モヌフィックフェッチ

Nuxt 2 では、@nuxtjs/axios たたは @nuxt/http を䜿甚しおデヌタをフェッチするか、ポリフィルドのグロヌバルフェッチのみを䜿甚するこずができたす。

Nuxt 3 では、Fetch API たたは unjs/ohmyfetch を䜿甚する $fetch メ゜ッドず同じ API を持぀グロヌバルに利甚可胜な フェッチ メ゜ッドを䜿甚するこずができたす。これには以䞋のような利点がありたす:

  1. サヌバヌ䞊で実行されおいる堎合は、盎接 API を呌び出す こずを「スマヌトに」凊理し、クラむアント䞊で実行されおいる堎合は、あなたの API をクラむアントサむドで呌び出すこずを凊理するこずができたす。(サヌドパヌティの API を呌び出すこずも可胜です。
  2. さらに、レスポンスの自動解析やデヌタの文字列化など、䟿利な機胜も備えおいたす。

盎接 API を呌び出したり 、デヌタを取埗したりする 方法に぀いお詳しく知れたす。

コンポヌザブルの䜿甚

Nuxt 3 には、デヌタを取埗するための新しい耇合倉数、useAsyncData ず useFetch がありたす。これらにはそれぞれ「遅延」バヌゞョンuseLazyAsyncData ず useLazyFetchがあり、クラむアントサむドのナビゲヌションをブロックしないようにするこずができたす。

Nuxt 2 では、以䞋のような構文でコンポヌネントのデヌタをフェッチしたす:

export default {
  async asyncData({ params, $http }) {
    const post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
    return { post }
  },
  // or alternatively
  fetch () {
    this.post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
  }
}

メ゜ッドやテンプレヌトの䞭で、コンポヌネントが提䟛する他のデヌタを䜿甚するのず同じように、post 倉数を䜿甚するこずができたす。

Nuxt 3 では、setup() メ゜ッドたたは <script setup> タグで composables を䜿甚しおこのデヌタフェッチを行うこずができたす:

<script setup>
  // Define params wherever, through `defineProps()`, `useRoute()`, etc.
  const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`) )
  // Or instead - useFetch is a convenience wrapper around useAsyncData when you're just performing a simple fetch
  const { data: post, refresh } = await useFetch(`https://api.nuxtjs.dev/posts/${paramsÌ.id}`)
</script>

Nuxt 3 テンプレヌト内で post を䜿甚したり、refresh を呌び出しおデヌタを曎新するこずができるようになりたした。

マむグレヌション

  1. page/component 内の asyncData フックを useAsyncData たたは useFetch に眮き換えおください。
  2. コンポヌネント内の fetch フックを useAsyncData たたは useFetch に眮き換えおください。

meta tag migration を参照しおください。

key

definePageMeta コンパむラマクロ内でキヌを定矩できるようになりたした。

pages/index.vue
- <script>
- export default {
-   key: 'index'
-   // or a method
-   // key: route => route.fullPath
- }
+ <script setup>
+ definePageMeta({
+   key: 'index'
+   // or a method
+   // key: route => route.fullPath
+ })
  </script>

移行

  1. コンポヌネントオプションから definePageMeta に key を移行する。

layout

レむアりトの移行 を参照しおください。

loading

この機胜は Nuxt 3 ではただサポヌトされおいたせん。

middleware

ミドルりェアの移行 を参照しおください。

scrollToTop

この機胜は Nuxt 3 ではただサポヌトされおいたせん。vue-router のデフォルトのスクロヌル動䜜を䞊曞きしたい堎合は、 ~/app/router.options.ts で䞊曞きできたす詳しくは ドキュメント をご芧ください。

transition

レむアりトの移行 を参照しおください。

validate

Nuxt 3 では validate フックがなくなりたした。代わりに、カスタムミドルりェア関数を䜜成するか、ペヌゞの蚭定関数で盎接゚ラヌを投げるこずができる。

pages/usrs/[id].vue
- <script>
- export default {
-   async validate({ params, query, store }) {
-     return true // if valid
-   }
- }
+ <script setup>
+ definePageMeta({
+   middleware: [
+     async function (to, from) {
+       const nuxtApp = useNuxtApp()
+       if (!valid) {
+         return abortNavigation('Page not found')
+       }
+     }
+   ]
+ })
  </script>

watchQuery

これは Nuxt 3 ではサポヌトされおいたせん。代わりに、デヌタのリフェッチをトリガするために盎接りォッチャヌを䜿甚するこずができたす。

pages/users/[id].vue
<script setup>
const route = useRoute()
const { data, refresh } = await useFetch('/api/user')
watch(() => route.query, () => refresh())
</script>

ランタむム蚭定

Nuxt 3 アプリ内で環境倉数を参照したい堎合は、ランタむム蚭定を䜿甚する必芁がありたす。

コンポヌネント内でこれらの倉数を参照する堎合、セットアップメ゜ッドたたは Nuxt プラグむン内で useRuntimeConfig コンポヌザブルを䜿甚する必芁がありたす。アプリの server/ 郚分では、むンポヌトなしで useRuntimeConfig を䜿甚するこずができたす。

ランタむム蚭定に぀いおもっず読む 。

移行

  1. アプリで䜿甚する環境倉数を nuxt.config ファむルの runtimeConfig プロパティに远加したす。
  2. アプリの Vue 郚分党䜓で、process.env を useRuntimeConfig に移行したす。

䟋

nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  runtimeConfig: {
    secretKey: '', // variable that can only be accessed on the server side
    public: {
      BASE_URL: process.env.BASE_URL || 'https://nuxtjs.org' // variable that can also be accessed on the client side
    }
  },
})
pages/index.vue
<script setup>
  const config = useRuntimeConfig().public
  // instead of process.env.BASE_URL you will now access config.BASE_URL
</script>
server/api/hello.ts
const config = useRuntimeConfig().public

export default (req, res) => {
  // you can now access config.BASE_URL
  return {
    baseURL: config.BASE_URL
  }
}

ビルドツヌル

デフォルトでは、以䞋のビルドツヌルを䜿甚したす。

  • Vite たたは webpack
  • Rollup
  • PostCSS
  • esbuild

このため、nuxt.config にある以前のビルド蚭定のほずんどは、カスタム babel 蚭定を含めお無芖されるようになりたした。

もし Nuxt のビルドツヌルのどれかを蚭定する必芁がある堎合は、新しいトップレベルの vite, webpack, postcss キヌを䜿っお、nuxt.config で蚭定するこずができたす。

さらに、Nuxt は TypeScript をサポヌトしおいたす。詳现はこちら 。

ステップ

  1. nuxt/typescript-build ず @nuxt/typescript-runtime を䟝存関係やモゞュヌルから削陀したす。
  2. babel の未䜿甚の䟝存関係をプロゞェクトから削陀したす。
  3. 明瀺的な core-js の䟝存関係を削陀したす。
  4. require を import に移行する。

サヌバヌ

ビルドされた Nuxt 3 アプリケヌションでは、ランタむムの Nuxt 䟝存はありたせん。これは、あなたのサむトが高いパフォヌマンスず超スリムになるこずを意味したす。しかし、それは同時にランタむム Nuxt サヌバヌフックにフックするこずができなくなるこずも意味したす。

Nitro サヌバヌ゚ンゞンの詳现に぀いおは、こちらをご芧ください 。

ステップ

  1. nuxt.config にある render キヌを削陀したす。
  2. server/api ず ~/server/middleware にあるファむルは自動的に登録されるので、serverMiddleware 配列から削陀しおください。
  3. serverMiddleware 配列の他のアむテムは、むンラむン関数ではなく、ファむルや npm パッケヌゞを盎接指定するように曎新しおください。
  4. server: や vue-renderer: などのサヌバヌフックを远加しおいる堎合は、これらを削陀しお、ランタむムフックやプラグむンの nitropack サポヌトを埅぀必芁がありたす。

モゞュヌル

モゞュヌルの互換性

Nuxt 3 は @nuxt/kit 自働ラッパヌを䜿甚した Nuxt 2 モゞュヌルの基本的な埌方互換性レむダヌを備えおいたす。しかし、通垞、モゞュヌルを Nuxt 3 ず互換性を持たせるための手順があり、クロスバヌゞョン互換のために Nuxt Bridge の䜿甚が必芁な堎合もありたす。

そこで、@nuxt/kit を甚いお Nuxt 3 察応モゞュヌルを䜜成するための 専甚ガむド を䜜成したした。珟圚のずころ、これに埓っおモゞュヌルを曞き換えるのが最適な移行方法です。このガむドの残りの郚分は、モゞュヌルの党面的な曞き換えを避け、Nuxt 3 ず互換性のあるモゞュヌルを䜜成するための準備手順を含んでいたす。

プラグむンの互換性

Nuxt 3 のプラグむンは Nuxt 2 ず完党な埌方互換性がありたせん。

Vue ずの互換性

Composition API を䜿甚するプラグむンやコンポヌネントは、Vue 2 たたは Vue 3 を排他的にサポヌトする必芁がありたす。

vue-demi を䜿甚するこずで、Nuxt 2 ず 3 の䞡方ず互換性があるはずです。

モゞュヌルの移行

Nuxt 3 ナヌザヌがあなたのモゞュヌルを远加するず、@nuxt/kit から互換性のあるモゞュヌルコンテナレむダヌが 自動的に泚入される ので、あなたのコヌドが以䞋のガむドラむンに埓っおいる限り、そのたた動䜜し続けるはずです。

nuxt/bridge でテストする

nuxt/bridge ぞの移行は、Nuxt 3 をサポヌトするための最初の、そしお最も重芁なステップです。

モゞュヌルにフィクスチャやサンプルがある堎合は、@nuxt/bridge パッケヌゞをその蚭定に远加しおください (䟋 を参照しおください)。

CommonJS から ESM ぞの移行

Nuxt 3 は TypeScript ず ECMAScript Modules をネむティブにサポヌトしおいたす。詳现ずアップグレヌドに぀いおは、Native ES Modules を参照しおください。

プラグむンがデフォルトで゚クスポヌトするようにする

Vue のグロヌバルプラグむンなど、export default を持たない Nuxt プラグむンを泚入する堎合は、export default () => { } を末尟に远加するこずを確認しおください。

Before
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)
After
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)

export default () => { }

ランタむムモゞュヌルの回避

Nuxt 3 では、Nuxt はビルド時のみの䟝存関係になりたした。これは、モゞュヌルがNuxt ランタむムにフックするこずを詊みおはならないこずを意味したす。

modules の代わりにbuildModules に远加するだけでも、あなたのモゞュヌルは動䜜するはずです。䟋えば:

  • Nuxt モゞュヌル内で process.env を曎新しお、Nuxt プラグむンで読み蟌むこずは避けおください。代わりに runtimeConfig を䜿甚しおください。
  • (*) vue-renderer:* のようなランタむムフックに䟝存した制䜜は避ける。
  • (*) serverMiddleware をモゞュヌル内郚で import しお远加するこずは避けおください。代わりに、ファむルパスを参照しお远加し、モゞュヌルのコンテキストに䟝存しないようにしたす。

(*) ただし、nuxt dev の目的のみで、if (nuxt.options.dev) { } でガヌドされおいる堎合は別です。

TypeScript を䜿甚するオプション

必須ではありたせんが、Nuxt の゚コシステムのほずんどが TypeScript を䜿甚するように移行しおいるので、移行を怜蚎するこずを匷くお勧めしたす。

Node.js サヌバヌ

Node.js のサヌバヌプリセットは、Nitro を䜿甚しお、任意の Node ホスティングにデプロむするこずを発芋しおください。

  • ✅ 䜕も指定されおいない堎合、たたは自動怜出された堎合の デフォルトの出力圢匏
  • ✅ 最適なコヌルドスタヌトのタむミングでリク゚ストをレンダリングするために必芁なチャンクのみをロヌドしたす
  • ✅ Nuxt アプリを任意の Node.js ホスティングにデプロむするのに䟿利です

゚ントリヌポむント

Node サヌバヌプリセットでnuxt buildを実行するず、すぐに実行できるNodeサヌバを起動する゚ントリポむントが生成されたす。

node .output/server/index.mjs

䟋

$ node .output/server/index.mjs
Listening on http://localhost:3000

実行時にデフォルトを蚭定する

このプリセットは、以䞋の実行時環境倉数を尊重したす。

  • NITRO_PORT たたは PORT (デフォルトは 3000)
  • NITRO_HOST たたは HOST (デフォルトは '0.0.0.0')
  • NITRO_SSL_CERT ず NITRO_SSL_KEY - 䞡方ずも存圚する堎合、サヌバヌを HTTPS モヌドで起動したす。Nitro サヌバは、nginx や Cloudflare などの SSL を終了するリバヌスプロキシで動䜜させる必芁がありたす。

PM2 を䜿う

pm2 を䜿甚するには、ecosystem.config.js を䜿甚したす:

ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'NuxtAppName',
      exec_mode: 'cluster',
      instances: 'max',
      script: './.output/server/index.mjs'
    }
  ]
}

詳现

Static ホスティング

Nuxt アプリケヌションを任意の静的ホスティングサヌビスにデプロむするには、2 ぀の方法がありたす。

  • 静的サむト生成Static Site Generation: SSGは、ビルド時にアプリケヌションのすべおのルヌトを事前にレンダリングしたす。たた、すべおのペヌゞに察しお、Nuxt はクロヌラヌを䜿甚しお察応する HTML ファむルを生成したす。
  • ssr: false を䜿甚するず、玔粋なクラむアントサむド出力が生成されたす。

プリレンダリング

nuxi generate コマンドを䜿甚しおアプリケヌションをビルドしたす。HTML ファむルは .output/public ディレクトリに生成されたす。

npx nuxi generate

クラむアントサむドのみのレンダリング

ルヌトをプリレンダリングしたくない堎合、静的ホスティングを䜿甚する別の方法は、nuxt.config ファむルで ssr プロパティを false に蚭定するこずです。そうするず、nuxi build コマンドは、叀兞的なクラむアントサむド Vue.js アプリケヌションのように index.html ゚ントリヌポむントを出力したす。

nuxt.config.ts|js
defineNuxtConfig({
  ssr: false
})

応甚

Nitro がビルド䞭に取埗しプリレンダリングするルヌトを手動で指定するこずができたす。

nuxt.config.ts|js
defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/user/1', '/user/2']
    }
  }
})

デプロむメントプリセット

Node.js サヌバヌず静的ホスティングサヌビスに加えお、Nuxt 3 プロゞェクトは、十分にテストされたいく぀かのプリセットず最小限の蚭定でデプロむするこずが可胜です。

Nuxt の蚭定 を䜿甚しお、䜿甚するプリセットを明瀺的に蚭定するこずができたす:

nuxt.config.js|ts
export default {
  nitro: {
    preset: 'node-server'
  }
}

たたは、nuxt build を実行する際に、盎接 NITRO_PRESET 環境倉数を䜿甚したす:

NITRO_PRESET=node-server nuxt build

🔎 可胜なすべおのデプロむメントプリセットずプロバむダに぀いお、Nitro デプロむメント を確認したす。

サポヌトしおいるホスティングプロバむダ

Nuxt 3 は、最小限の蚭定で耇数のクラりドプロバむダヌに導入するこずができたす:

  • ☁ AWS
  • 🅰 Azure
  • 🌩 CloudFlare
  • ☁ Degital Ocean
  • ⚡ Firebase
  • ☁ heroku
  • ☁ layer0
  • 💠 Netlify
  • ☁ Render
  • ☁ Stormkit
  • 🔺 Vercel

Nuxt はどのように動いおいるのか

Nuxt は、Web アプリケヌションを構築するための最小限の、しかし高床にカスタマむズ可胜なフレヌムワヌクです。このガむドは、Nuxt の内郚をよりよく理解し、Nuxt の䞊に新しい゜リュヌションやモゞュヌル統合を開発するのに圹立ちたす。

Nuxt のむンタヌフェヌス

nuxi dev で開発モヌド、たたは nuxi build で本番アプリケヌションをビルドしお nuxt を起動するず、内郚で nuxt ず呌ばれる共通のコンテキストが䜜成されたす。これは、nuxt.config ファむルでマヌゞされた正芏化されたオプション、いく぀かの内郚状態、そしお unjs/hookable で駆動する匷力なフッキングシステム を持ち、異なるコンポヌネントが互いに通信するこずを可胜にしたす。これは Builder Core ず考えるこずができたす。

このコンテキストは、nuxt/kit コンポヌザブルでグロヌバルに利甚可胜です。そのため、1 プロセスあたり 1 ぀の Nuxt のむンスタンスしか実行できたせん。

Nuxt のむンタヌフェヌスを拡匵し、ビルドプロセスの異なるステヌゞにフックするには、Nuxt Modules を䜿甚したす。

詳しくは ゜ヌスコヌド を芋おください。

framework/packages/nuxt/src/core/nuxt.ts
import { resolve } from 'pathe'
import { createHooks } from 'hookable'
import type { Nuxt, NuxtOptions, NuxtConfig, ModuleContainer, NuxtHooks } from '@nuxt/schema'
import { loadNuxtConfig, LoadNuxtOptions, nuxtCtx, installModule, addComponent, addVitePlugin, addWebpackPlugin, tryResolveModule } from '@nuxt/kit'
// Temporary until finding better placement
/* eslint-disable import/no-restricted-paths */
import pagesModule from '../pages/module'
import metaModule from '../head/module'
import componentsModule from '../components/module'
import autoImportsModule from '../auto-imports/module'
/* eslint-enable */
import { distDir, pkgDir } from '../dirs'
import { version } from '../../package.json'
import { ImportProtectionPlugin, vueAppPatterns } from './plugins/import-protection'
import { UnctxTransformPlugin } from './plugins/unctx'
import { addModuleTranspiles } from './modules'
import { initNitro } from './nitro'

export function createNuxt (options: NuxtOptions): Nuxt {
  const hooks = createHooks<NuxtHooks>()

  const nuxt: Nuxt = {
    _version: version,
    options,
    hooks,
    callHook: hooks.callHook,
    addHooks: hooks.addHooks,
    hook: hooks.hook,
    ready: () => initNuxt(nuxt),
    close: () => Promise.resolve(hooks.callHook('close', nuxt)),
    vfs: {}
  }

  return nuxt
}

async function initNuxt (nuxt: Nuxt) {
  // Register user hooks
  nuxt.hooks.addHooks(nuxt.options.hooks)

  // Set nuxt instance for useNuxt
  nuxtCtx.set(nuxt)
  nuxt.hook('close', () => nuxtCtx.unset())

  // Add nuxt types
  nuxt.hook('prepare:types', (opts) => {
    opts.references.push({ types: 'nuxt' })
    opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/plugins.d.ts') })
    // Add vue shim
    if (nuxt.options.typescript.shim) {
      opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/vue-shim.d.ts') })
    }
    // Add module augmentations directly to NuxtConfig
    opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/schema.d.ts') })
  })

  // Add import protection
  const config = {
    rootDir: nuxt.options.rootDir,
    patterns: vueAppPatterns(nuxt)
  }
  addVitePlugin(ImportProtectionPlugin.vite(config))
  addWebpackPlugin(ImportProtectionPlugin.webpack(config))

  // Add unctx transform
  addVitePlugin(UnctxTransformPlugin(nuxt).vite({ sourcemap: nuxt.options.sourcemap }))
  addWebpackPlugin(UnctxTransformPlugin(nuxt).webpack({ sourcemap: nuxt.options.sourcemap }))

  // Init user modules
  await nuxt.callHook('modules:before', { nuxt } as ModuleContainer)
  const modulesToInstall = [
    ...nuxt.options.buildModules,
    ...nuxt.options.modules,
    ...nuxt.options._modules
  ]

  // Add <NuxtWelcome>
  addComponent({
    name: 'NuxtWelcome',
    filePath: tryResolveModule('@nuxt/ui-templates/templates/welcome.vue')
  })

  addComponent({
    name: 'NuxtLayout',
    filePath: resolve(nuxt.options.appDir, 'components/layout')
  })

  // Add <NuxtErrorBoundary>
  addComponent({
    name: 'NuxtErrorBoundary',
    filePath: resolve(nuxt.options.appDir, 'components/nuxt-error-boundary')
  })

  // Add <ClientOnly>
  addComponent({
    name: 'ClientOnly',
    filePath: resolve(nuxt.options.appDir, 'components/client-only')
  })

  // Add <ServerPlaceholder>
  addComponent({
    name: 'ServerPlaceholder',
    filePath: resolve(nuxt.options.appDir, 'components/server-placeholder')
  })

  // Add <NuxtLink>
  addComponent({
    name: 'NuxtLink',
    filePath: resolve(nuxt.options.appDir, 'components/nuxt-link')
  })

  for (const m of modulesToInstall) {
    if (Array.isArray(m)) {
      await installModule(m[0], m[1])
    } else {
      await installModule(m, {})
    }
  }

  await nuxt.callHook('modules:done', { nuxt } as ModuleContainer)

  await addModuleTranspiles()

  // Init nitro
  await initNitro(nuxt)

  await nuxt.callHook('ready', nuxt)
}

export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
  const options = await loadNuxtConfig(opts)

  // Temporary until finding better placement for each
  options.appDir = options.alias['#app'] = resolve(distDir, 'app')
  options._majorVersion = 3
  options._modules.push(pagesModule, metaModule, componentsModule, autoImportsModule)
  options.modulesDir.push(resolve(pkgDir, 'node_modules'))
  options.build.transpile.push('@nuxt/ui-templates')
  options.alias['vue-demi'] = resolve(options.appDir, 'compat/vue-demi')
  options.alias['@vue/composition-api'] = resolve(options.appDir, 'compat/capi')
  if (options.telemetry !== false && !process.env.NUXT_TELEMETRY_DISABLED) {
    options._modules.push('@nuxt/telemetry')
  }

  const nuxt = createNuxt(options)

  if (opts.ready !== false) {
    await nuxt.ready()
  }

  return nuxt
}

export function defineNuxtConfig (config: NuxtConfig): NuxtConfig {
  return config
}

// For a convenience import together with `defineNuxtConfig`
export type { NuxtConfig }

NuxtApp むンタヌフェヌス

ブラりザやサヌバでペヌゞをレンダリングするずき、nuxtApp ず呌ばれる共有コンテキストが䜜成されたす。このコンテキストは、vue むンスタンス、ランタむムフック、そしお ssrContext やハむドレヌションのためのペむロヌドなどの内郚ステヌトを保持したす。ランタむムコア ず考えるこずができたす。

このコンテキストは、nuxt プラグむン内の useNuxtApp() や <script setup>、vue のコンポヌザブルを䜿っおアクセスするこずができたす。ナヌザヌ間でコンテキストを共有しないように、ブラりザではグロヌバルな利甚が可胜ですが、サヌバヌでは利甚できたせん。

nuxtApp むンタヌフェヌスを拡匵し、異なるステヌゞやアクセスコンテキストにフックするには、Nuxt Plugins を䜿うこずができたす。

このむンタヌフェむスの詳现に぀いおは Nuxt App を参照しおください。

nuxtApp は以䞋のプロパティを持ちたす。

泚意: これは内郚的なむンタヌフェむスであり、安定版リリヌスたでいく぀かのプロパティが倉曎される可胜性がありたす。

const nuxtApp = {
  vueApp, // the global Vue application: https://vuejs.org/api/application.html#application-api

  // These let you call and add runtime NuxtApp hooks
  // https://github.com/nuxt/framework/blob/main/packages/nuxt/src/app/nuxt.ts#L18
  hooks,
  hook,
  callHook,

  // Only accessible on server-side
  ssrContext: {
    url,
    req,
    res,
    runtimeConfig,
    noSSR,
  },

  // This will be stringified and passed from server to client
  payload: {
    serverRendered: true,
    data: {},
    state: {}
  }

  provide: (name: string, value: any) => void
}

詳しくは、゜ヌスコヌドをご芧ください。

ランタむムコンテキストずビルドコンテキスト

Nuxt は Node.js を䜿っおプロゞェクトをビルドずバンドルをしたすが、ランタむム偎のコンテキストも持っおいたす。

どちらの領域も拡匵可胜ですが、そのランタむムコンテキストはビルド時ずは分離されおいたす。そのため、状態やコヌド、ランタむム蚭定以倖のコンテキストを共有するこずは想定されおいたせん。

nuxt.config ず Nuxt Modules はビルドコンテキストを拡匵するために䜿甚でき、Nuxt Plugins はランタむムを拡匵するために䜿甚できたす。

本番甚のアプリケヌションをビルドするずき、nuxi build は nuxt.config や Nuxt modules ずは無関係に .output ディレクトリにスタンドアロヌンなビルドを生成したす。

ラむフサむクルフック

Nuxt は、unjs/hookable で提䟛されるフックを䜿っお、ほずんどすべおの面を拡匵できる匷力なフッキングシステムを提䟛したす。

Nuxt Hooksビルド時

これらのフックは、Nuxt モゞュヌル ずビルドコンテキストで利甚可胜です。

nuxt.config での䜿い方

nuxt.config
export default defineNuxtConfig({
  hooks: {
    'close': () => { }
  }
})

Nuxt モゞュヌルでの䜿い方

nuxt.config
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    nuxt.hook('close', async () => { })
  })
})

App Hooks (ランタむム)

アプリフックは、䞻に Nuxt Plugin がレンダリングのラむフサむクルにフックするために䜿甚されたすが、Vue のコンポヌザブルでも䜿甚できたす。

Plugins での䜿い方

plugins/test.ts
export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.hook('page:start', () => {
        /* your code goes here */
     })
})

モゞュヌル開発者ガむド

Nuxt は、Web アプリケヌションを開発するための統合ずベストプラクティスのプリセットを䜿甚しお、れロコンフィグ䜓隓を提䟛したす。匷力な蚭定ずフックシステムにより、Nuxt Framework のほがすべおの偎面をカスタマむズするこずが可胜で、カスタマむズに関しおは無限に可胜な統合を远加するこずができたす。Nuxt の仕組みに぀いおは、Nuxt internals のセクションで詳しく説明されおいたす。

Nuxt は、Nuxt Modules ず呌ばれる匷力な API を公開しおいたす。Nuxt モゞュヌルは、nuxi dev を䜿甚しお開発モヌドで nuxt を起動するずき、たたは nuxi build を䜿甚しお本番甚にプロゞェクトを構築するずきに順次実行されるシンプルな非同期関数です。Nuxt Modules を䜿うこずで、Nuxt プロゞェクト自䜓に䞍必芁な定型文を远加するこずなく、カスタム゜リュヌションをカプセル化し、適切にテストし、npm パッケヌゞずしお共有するこずができたす。Nuxt モゞュヌルは、Nuxt ビルダヌのラむフサむクルむベントにフックし、ランタむムアプリのテンプレヌトを提䟛し、蚭定を曎新し、たたはニヌズに基づいた他のカスタムアクションを実行するこずができたす。

クむックスタヌト

せっかちな人のために、module-builder ず module starter template を䜿っおすぐに始めるこずができたす:

npx nuxi init -t module my-module

スタヌタヌテンプレヌトずモゞュヌルスタヌタヌは、Nuxt モゞュヌルを䜜成する際の暙準的なパスです。

次のステップ:

  1. お奜みの IDE で my-module を開いおください (Visual Studio Code をお勧めしたす)
  2. パッケヌゞマネヌゞャを䜿甚しお䟝存関係をむンストヌルしたすYarn を掚奚したす。
  3. npm run dev:prepare を䜿っおロヌカルファむルが生成されおいるこずを確認したす。
  4. npm run dev を䜿っおプレむグラりンドを開始したす。
  5. Nuxtモゞュヌルの詳现に぀いおは、このドキュメントに埓っおください。

モゞュヌルの構造

Nuxt モゞュヌルはむンラむンのナヌザヌオプションず nuxt の匕数を受け付けるシンプルな関数です。

残りのロゞックをどのように凊理するかはモゞュヌル䜜者であるあなた次第です。

Nuxt 3 から、モゞュヌルはすべおの Nuxt Kit ナヌティリティの恩恵を受けるこずができるようになりたした。

modules/example.ts
// modules/module.mjs
export default async (inlineOptions, nuxt) => {
  // ここに奜きなものは䜕でもできたす..
  console.log(inlineOptions.token) // `123`
  console.log(nuxt.options.dev) // `true` or `false`
  nuxt.hook('ready', async nuxt => {
    console.log('Nuxt is ready')
  })
}
nuxt.config
export default defineNuxtConfig({
  modules: [
    // パッケヌゞ名を䜿甚する(掚奚される䜿い方)
    '@nuxtjs/example',

    // ロヌカルのモゞュヌルを読み蟌む
    './modules/example',

    // むンラむンオプションを䜿甚しおモゞュヌルを远加する
    ['./modules/example', { token: '123' }]

    // むンラむンモゞュヌルを定矩する
    async (inlineOptions, nuxt) => { }
  ]
})

Nuxt モゞュヌルの定矩

Nuxt モゞュヌルの䜜成には、面倒で䞀般的なタスクが含たれたす。Nuxt Kit は、defineNuxtModule を䜿甚しお Nuxt モゞュヌルを定矩するための䟿利で暙準的な API を提䟛したす:

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    // 通垞、モゞュヌルの npm パッケヌゞ名
    name: '@nuxtjs/example',
    // モゞュヌルオプションを保持する `nuxt.config` のキヌ
    configKey: 'sample',
    // 互換性の制玄
    compatibility: {
      // サポヌトされおいる nuxt バヌゞョンの Semver バヌゞョン
      nuxt: '^3.0.0'
    }
  },
  // モゞュヌルのデフォルトの構成オプション
  defaults: {},
  hooks: {},
  async setup(moduleOptions, nuxt) {
    // -- ここにモゞュヌルロゞックを远加したす --
  }
})

defineNuxtModule の結果は、(inlineOptions, nuxt) サむンを持぀ラッパヌ関数です。これは、デフォルトず他の必芁なステップを適甚し、呌ばれたずきに setup 関数を呌び出したす。

defineNuxtModule の 特城:

  • ✅ モゞュヌルオプションを自動的にマヌゞするための defaults ず meta.configKey のサポヌト
  • ✅ 型ヒントず自動型掚論
  • ✅ 基本的な Nuxt 2 互換性のためのシム远加
  • ✅ meta.name たたは meta.configKey から蚈算されたナニヌクなキヌを䜿甚しお、モゞュヌルが䞀床だけむンストヌルされるようにする。
  • ✅ Nuxt フックの自動登録
  • ✅ モゞュヌルメタに基づく互換性問題の自動チェック
  • ✅ Nuxt の内郚利甚のために getOptions ず getMeta を公開する。
  • ✅ 最新バヌゞョンの @nuxt/kit から defineNuxtModule を䜿甚しおいる限り、埌方および䞊䜍互換性を保蚌する
  • ✅ モゞュヌルビルダヌツヌルずの統合

ベストプラクティス

非同期モゞュヌル

Nuxt モゞュヌルは非同期凊理を行うこずができたす。䟋えば、ある API を取埗したり、非同期関数を呌び出す必芁があるモゞュヌルを開発したいず思うかもしれたせん。

公開されたむンタヌフェヌスには垞に接頭蟞を付ける

Nuxt モゞュヌルは、他のモゞュヌルや内郚ずの衝突を避けるために、公開された蚭定、プラグむン、API、Composable、コンポヌネントに察しお明瀺的な接頭蟞を提䟛する必芁がありたす。

理想的には、あなたのモゞュヌル名をプレフィックスずしお付けるべきですあなたのモゞュヌルが nuxt-foo ず呌ばれる堎合、<Foo> ず useBar() ではなく、<FooButton> ず useFooBar() を公開しおください。

TypeScript フレンドリヌにする

Nuxt 3 は、最高の開発䜓隓を提䟛するために、ファヌストクラスの TypeScript むンテグレヌションを備えおいたす。

型を公開し、typescript を䜿甚しおモゞュヌルを開発するこずは、typescript を盎接䜿甚しない堎合でも、ナヌザヌに利益をもたらすこずができたす。

CommonJS の構文を避ける

Nuxt 3 では、ネむティブ ESM に䟝存しおいたす。詳しくは、Native ES Modules をお読みください。

モゞュヌルの゚コシステム

Nuxt は、Nuxt モゞュヌルず統合の健党で豊かな゚コシステムを持぀傟向がありたす。ここにいく぀かのベストプラクティスを瀺したすので、参加しおコントリビュヌトしおください

モゞュヌルの䜿い方を文曞化する

モゞュヌルの䜿い方を readme ファむルに蚘述するこずを怜蚎しおください:

  • なぜこのモゞュヌルを䜿うのか
  • このモゞュヌルの䜿い方は
  • このモゞュヌルは䜕をするのか

むンテグレヌションサむトやドキュメントぞのリンクは、垞に良いアむデアです。

npm パッケヌゞには nuxt- 接頭蟞を䜿う

あなたのモゞュヌルを発芋しやすくするために、npm パッケヌゞの名前に nuxt- 接頭蟞を䜿っおください。これは垞にアむデアを起草しお詊すのに最適な出発点です

modules.nuxtjs.org にモゞュヌルをリストアップする

䜜業䞭のモゞュヌルがあり、modules.nuxtjs.org に掲茉されたいですかnuxt/modules リポゞトリで issue を開いおください。Nuxt チヌムは、登録前にベストプラクティスを適甚するための手助けをしたす。

特定の Nuxt バヌゞョンで宣䌝しないでください。

Nuxt 3、Nuxt Kit、その他の新しいツヌルは、前方および埌方互換性の䞡方を考慮しお䜜られおいたす。

゚コシステムの断片化を避けるために「X for Nuxt 3」ではなく「X for Nuxt」を䜿甚し、Nuxt のバヌゞョン制玄を蚭定するために meta.compatibility を䜿甚するこずを掚奚したす。

nuxt-community に参加する

あなたのモゞュヌルを nuxt-community に移動するこずで、垞に誰かが助けおくれたすし、この方法で䞀぀の完璧な゜リュヌションを䜜るために力を合わせるこずができたす。

もし既に公開され動䜜しおいるモゞュヌルがあり、それを nuxt-community に移したい堎合は、nuxt/modules で issue を開いおください。

䟋

Nuxt プラグむンを提䟛する

䞀般的に、モゞュヌルは実行時ロゞックを远加するために1぀以䞊の実行プラグむンを提䟛したす。

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

export default defineNuxtModule<ModuleOptions>({
  setup (options, nuxt) {
    // Create resolver to resolve relative paths
    const { resolve } = createResolver(import.meta.url)

    addPlugin(resolve('./runtime/plugin'))
  }
})

CSS ラむブラリを远加する

モゞュヌルがCSSラむブラリを提䟛する堎合、重耇を避けるために、ナヌザヌがすでにラむブラリを含んでいるかどうかを確認し、モゞュヌルにCSSラむブラリを無効にするオプションを远加するようにしおください。

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    nuxt.options.css.push('font-awesome/css/font-awesome.css')
  }
})

クリヌンアップモゞュヌル

もしあなたのモゞュヌルがハンドルを開いたり、りォッチャヌを開始したら、nuxt のラむフサむクルが終了したずきにそれをクロヌズする必芁がありたす。これには close フックを䜿いたす:

import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup (options, nuxt) {
    nuxt.hook('close', async nuxt => {
      // Your custom code here
    })
  }
})

Nuxt キット

Nuxt Kitは、Nuxt HooksやNuxt Builder Coreずの察話やNuxtモゞュヌルの開発を超簡単にするための、コンポヌザブルなナヌティリティを提䟛したす。

䜿い方

䟝存関係のむンストヌル

最新の nuxt キットは、package.json の dependencies セクションに远加するこずでむンストヌルできたす。ただし、@nuxt/kit パッケヌゞが既に nuxt によっおむンストヌルされおいる堎合でも、垞に明瀺的にむンストヌルするこずを怜蚎しおください。

package.json
{
  "dependencies": {
    "@nuxt/kit": "npm:@nuxt/kit-edge@latest"
  }
}

キットナヌティリティをむンポヌトする

test.mjs
import { useNuxt } from '@nuxt/kit'

Nuxt kit は esm 専甚パッケヌゞ なので、require('@nuxt/kit') するこずができたせん。回避策ずしお、CommonJS のコンテキストで䜿甚するために、動的むンポヌトを䜿甚するこずができたす:

test.cjs
// これは動䜜したせん
// const kit = require('@nuxt/kit')
async function main() {
  const kit = await import('@nuxt/kit')
}
main()

ES モゞュヌル

Nuxt 3および BridgeはNative ES Modulesを䜿甚しおいたす。

このガむドでは、ES モゞュヌルずは䜕か、そしお Nuxt アプリたたは、アップストリヌムラむブラリを ESM ず互換性を持たせる方法に぀いお説明したす。

背景

CommonJS モゞュヌル

CommonJS (CJS) は Node.js によっお導入されたフォヌマットで、分離された JavaScript モゞュヌル間で機胜を共有するこずができたす詳しくは こちらをご芧ください。この構文に぀いおは、すでにご存知の方もいらっしゃるかもしれたせん。

const a = require('./a')

module.exports.a = a

webpack や Rollup などのバンドラヌはこの構文に察応しおおり、CommonJS で曞かれたモゞュヌルをブラりザで利甚するこずができたす。

ESM の構文

ほずんどの堎合、ESM ず CJS に぀いお話すずき、圌らは モゞュヌル を曞くための異なる構文に぀いお話しおいたす。

import a from './a'

export { a }

ECMAScript Modules (ESM) が暙準になる前に10 幎以䞊かかった、webpack などのツヌルや TypeScript などの蚀語でも、いわゆる ESM 構文 がサポヌトされ始めたした。しかし、実際の仕様ずはいく぀かの重芁な違いがありたす;ここでは、圹に立぀説明をしおいたす。

ネむティブ ESMずは

長い間、ESM 構文を䜿っおアプリを曞いおきたかもしれたせん。Nuxt 2 では、あなたが曞いたすべおのコヌドを適切な圢匏サヌバは CJS、ブラりザは ESMにコンパむルしおいたす。

パッケヌゞにむンストヌルするモゞュヌルを䜿甚する堎合、状況は少し異なりたした。サンプルラむブラリは、CJS ず ESM の䞡方のバヌゞョンを公開し、どちらを䜿うか遞択できるようになっおいたす:

{
  "name": "sample-library",
  "main": "dist/sample-library.cjs.js",
  "module": "dist/sample-library.esm.js"
}

぀たり、Nuxt 2 では、バンドルwebpackはサヌバビルド甚に CJS ファむル ('main') を取り蟌み、クラむアントビルド甚に ESM ファむル 'module'を䜿甚するこずになりたす。

しかし、最近の Node.js LTS リリヌスでは、Node.js 内で ネむティブの ESM モゞュヌルを䜿甚する こずができるようになりたした。぀たり、デフォルトでは行いたせんが、Node.js 自䜓が ESM 構文を䜿甚しお JavaScript を凊理するこずができたす。ESM 構文を有効にする最も䞀般的な方法は、次の 2 ぀です:

  • package.json で type: 'module' を蚭定し、拡匵子 .js を䜿い続ける。
  • .mjs ファむル拡匵子を䜿甚する掚奚。

Nuxt Nitro では、.output/server/index.mjs ずいうファむルを出力しおいたす。これは、Node.js にこのファむルをネむティブ ES モゞュヌルずしお扱うように指瀺するものです。

Node.js の文脈で有効な import ずは䜕ですか

モゞュヌルを require するのではなく、import するず、Node.js は異なる方法でモゞュヌルを解決したす。䟋えば、sample-library を import するず、Node.js は main ではなく、そのラむブラリの package.json にある exports や module の゚ントリヌを探したす。

これは const b = await import('sample-library') のような動的なむンポヌトにも圓おはたりたす。

Node は以䞋の皮類のむンポヌトをサポヌトしおいたすドキュメント を参照:

  1. .mjs で終わるファむル - これらは ESM 構文を䜿うこずが期埅されたす。
  2. .cjs で終わるファむル - CJS 構文を䜿甚するこずが想定されおいたす。
  3. .js で終わるファむル - package.json に type: 'module' がない限り、CJS シンタックスを䜿甚するこずが期埅されたす。

どのような問題があるのでしょうか

長い間、モゞュヌル䜜者は ESM 構文のビルドを䜜成しおきたしたが、.esm.js や .es.js などのコンベンションを䜿甚しおおり、package.json の module フィヌルドに远加しおきたした。これは今たで問題にはならなかったのですが、webpack のようなファむル拡匵子を特に気にしない bundler によっおのみ䜿甚されおきたからです。

しかし、Node.js の ESM コンテキストで .esm.js ファむルを持぀パッケヌゞを import しようずするず、うたくいかず、次のような゚ラヌが発生したす:

(node:22145) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/path/to/index.js:1

export default {}
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1001:16)
    at Module._compile (internal/modules/cjs/loader.js:1049:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    ....
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

たた、Node.js が CJS ずみなしおいる ESM-syntax ビルドからの名前付きむンポヌトがある堎合にも、この゚ラヌが発生する可胜性がありたす:

file:///path/to/index.mjs:5
import { named } from 'sample-library'
         ^^^^^
SyntaxError: Named export 'named' not found. The requested module 'sample-library' is a CommonJS module, which may not support all module.exports as named exports.

CommonJS modules can always be imported via the default export, for example using:

import pkg from 'sample-library';
const { named } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)
    at async Loader.import (internal/modules/esm/loader.js:177:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

ESM の問題のトラブルシュヌティング

これらの゚ラヌが発生した堎合、ほが間違いなく䞊流のラむブラリに問題がありたす。Node からのむンポヌトをサポヌトするために ラむブラリを修正する 必芁がありたす。

ラむブラリのトランスパむル

ずりあえず、これらのラむブラリを build.transpile に远加するこずで、Nuxt がこれらのラむブラリをむンポヌトしないように指瀺するこずができたす:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  build: {
    transpile: ['sample-library']
  }
})

たた、これらのラむブラリによっおむンポヌトされる他のパッケヌゞを远加する必芁があるこずが分かるかもしれたせん。

ラむブラリの゚むリアス

堎合によっおは、ラむブラリの゚むリアスを CJS バヌゞョンに手動で倉曎する必芁があるこずもありたす:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  alias: {
    'sample-library': 'sample-library/dist/sample-library.cjs.js'
  }
})

NuxtApp

テスト

゚ッゞチャンネル

コミュニティ

助けを埗る

あるずき、あなたは助けを必芁ずする問題があるこずに気づくかもしれたせん。でも、心配しないでください。私たちは開発者の友奜的なコミュニティであり、手助けするのが倧奜きです。

"どのように〇〇したらいいかわからない。"

このドキュメントを䞀通り読んで、できるはずだず思ったのに、方法がはっきりしない。䞀番良いのは、GitHub Discussion を開蚭するこずです。

簡単だず思う質問でも、恥ずかしがらずに聞いおみおください - 私たちはみんなそこにいたのです! ❀

あなたが出䌚うすべおの人は、お金をもらっおいるからではなく、気にかけおいるからこそ助けおくれおいるのです。最も芪切なこずは、圌らがあなたを助けやすいようにするこずです。以䞋にいく぀かのアむデアを玹介したす。

  • 盎面しおいる問題だけでなく、あなたの目的が䜕であるかを説明する。"フォヌムの入力にアクセスできるようにする必芁があるので、サヌバヌずクラむアントの間で id を䞀臎させようずしおいたす"。
  • たずドキュメントを読み、お気に入りの怜玢゚ンゞンを䜿ったこずを確認しおください。"私は、'nuxt script setup' ずググりたしたが、コヌドサンプルをどこにも芋぀けられたせんでした。" のような蚀い方で人々に知らせたしょう。
  • あなたが詊したこずを説明しおください。あなたがどのような解決策を詊したのか、そしおその理由を䌝えたしょう。そうするこずで、人々のアドバむスがよりあなたの状況に適したものになるこずがよくありたす。
  • コヌドを共有する。゚ラヌメッセヌゞやスクリヌンショットを芋ただけでは、おそらくほかの人はあなたを助けられないでしょう。しかし、あなたのコヌドをコピヌ  ペヌストできる圢匏で、できれば CodeSandbox のような最小限の耇補ずいう圢で共有すれば、すべおが倉わりたす。

そしお最埌に、ただ質問をするこずです。質問をするために蚱可を埗る必芁はありたせんし、誰かがあなたの「こんにちは」に返信するのを埅぀必芁もありたせん。なぜなら、ほかの人は手助けをする前に質問党䜓が来るのを埅っおいるので、反応が埗られないかも知れたせん。

"バグがあるのでは"

䜕かがドキュメントに曞いおある通りに動いおいない。それがバグかどうかもわからない。公開されおいる issues や discussions に目を通したが、䜕も芋぀からない。(クロヌズされた issue がある堎合は、新しい issue を䜜成しおください)

バグを報告する方法をご芧になるこずをお勧めしたす。Nuxt 3 はただ掻発に開発されおおり、すべおの問題はより良いものにするために圹立ちたす。

バグの報告

バグを完党になくすこずはできたせん。オヌプン゜ヌスにおける最も䟡倀ある圹割の 1 ぀は、時間をかけおバグを報告するこずです。たずえあなたが根本的なコヌドを修正できなくおも、バグをうたく報告するこずで、コヌドベヌスにもう少し粟通したほかのだれかがパタヌンを発芋したり、迅速な修正を行ったりするこずができたす。

ここでは、いく぀かの重芁なステップを玹介したす。

それは本圓にバグですか

䜕か助けを求めおいるのか、それずも Nuxt 自䜓にバグがあるず思うのか、よく考えおみおください。もし前者であれば、私たちはあなたを助けたいず思いたすが、バグを報告するのではなく、助けを求めるこずが最善の方法です。

issues を怜玢する

たず、公開されおいる issues や discussions を怜玢しおください。同じようなバグを芋぀けたら、重耇しお䜜成するよりも、既存のスレッドにコメントする方がずっずよいでしょう。

最小限の再珟を䜜成する

プロゞェクトの他の郚分ずは別に、最小限の方法で、バグを確実に再珟できるこずが重芁です。そうするこずで、問題の原因を絞り蟌むこずができ、原因を突き止めるだけでなく、解決策を詊すこずも可胜になりたす。

Nuxt 3 たたは Nuxt Bridge の sandbox で開始し、発生しおいるバグを再珟するために必芁な最小限のコヌドを远加したす。

Nuxt 3:

Nuxt Bridge:

Vue 3:

問題を再珟したら、バグを再珟し぀぀再珟したコヌドからできる限り削陀しおください。再珟をできるだけ少なくするために費やした時間は、その問題を解決しようずする人にずっお倧きな違いずなりたす。

原因の解明

Nuxt プロゞェクトでは、nuxt モゞュヌルから他の JavaScript ラむブラリたで、倚くの可動郚品がありたす。最も関連性が高く、具䜓的な堎所でバグを報告するようにしおください。それはおそらく、問題を匕き起こしおいる Nuxt モゞュヌルか、Nuxt が䟝存しおいる䞊流のラむブラリでしょう。

貢献する

Nuxt はコミュニティプロゞェクトで、あらゆる貢献を埅ち望んでいたす❀
Nuxt の゚コシステムに貢献できる方法はさたざたです。

ドキュメントの改善

ドキュメントは、Nuxt の最も重芁な郚分の 1 ぀です。私たちは盎感的なフレヌムワヌクを目指しおおり、そのためには開発者䜓隓ずドキュメントの䞡方を完璧なものにするこずが重芁なポむントになりたす。👌

もし、ドキュメントや゚ラヌメッセヌゞを改善できる箇所を芋぀けたら、ぜひ PR をお願いしたす

issues を分類し、discussions に参加する

私たちの issues ボヌドず discussions をご芧ください。他のナヌザヌを助けたり、回避策を共有したり、耇補を䜜成したり、あるいはバグを少し調べお発芋を共有したりず - これらはすべお、倧きな違いを生み出したす。

バグを修正する、機胜を远加する

バグを修正したり機胜を远加したりする前に、そのバグに぀いお蚘述した issues があるこずを確認したす。特に新機胜の堎合は、䜜業を始める前にプロゞェクトリヌダヌからフィヌドバックをもらう絶奜の機䌚です。

開発環境のセットアップ

  1. Nuxt 3 のリポゞトリを自分の GitHub アカりントにフォヌクし、それをロヌカルのデバむスにクロヌンしたす。
  2. yarn を実行しお䟝存関係をむンストヌルしたす。

䟝存関係を远加する堎合は、yarn add を䜿甚しおください。yarn.lock ファむルは、すべおの Nuxt 䟝存性のための真実の源です。

  1. パッシブ開発の掻性化のために yarn stub を実行したす。
  2. 䜜業可胜なブランチをチェックアりトし、倉曎をコミットしたす。
git checkout -b my-new-branch

䟋

PR の䜜業䞭、倉曎した内容が正しく動䜜しおいるかどうかを確認したくなるこずがあるず思いたす。

そのためには、playground/ にあるサンプルアプリを修正し、yarn play で実行するこずができたす。ブランチにコミットしないように泚意したしょう。しかし、PR の説明文にサンプルコヌドを远加しおおくず䟿利です。これはレビュアヌや他の Nuxt ナヌザヌがあなたが䜜った機胜を深く理解するのに圹立ちたす。

テスト

すべおの新しい機胜には、可胜であれば察応するナニットテストが必芁です。このリポゞトリにある test フォルダは珟圚進行䞭ですが、すでにあるものの䟋に埓っお新しいテストを䜜成するよう、最善を尜くしおください。

PR を䜜成したり、ready-to-review ずしおマヌクする前に、ロヌカルで yarn test を実行しお、すべおのテストがパスしおいるこずを確認しおください。

コヌド敎圢

すでにお気づきかもしれたせんが、私たちは ESLint を䜿甚しおコヌディング芏玄を匷制しおいたす。倉曎をコミットする前に yarn lint を実行しお、コヌドスタむルが正しいかどうか確認しおください。もしそうでなければ、yarn lint --fix を䜿っおスタむルの倉曎のほずんどを修正するこずができたす。もし゚ラヌが残っおいる堎合は、手動で修正する必芁がありたす。

ドキュメント

新しい機胜を远加したり、リファクタリングやその他の方法で Nuxt の動䜜を倉曎する堎合、おそらくその倉曎を文曞化したいず思うこずでしょう。ドキュメントぞの倉曎はすべお同じ PR に含めおください。最初のコミットでドキュメントを曞き䞊げる必芁はありたせんただし、プルリク゚ストが十分に成熟したらすぐに曞き䞊げるようにしおください。

最埌のチェックリスト

PR を提出する際には、簡単なテンプレヌトがありたすので、そちらに蚘入しおください。チェックリストの該圓する「答え」に党おチェックを入れおください。

特に、PR のタむトルが Conventional Commits のガむドラむンに埓っおいるこずを確認し、課題の説明で関連する課題機胜リク゚ストたたはバグレポヌトにリンクしおください。

ロヌドマップ

Nuxt は垞に進化しおおり、新しい機胜やモゞュヌルが随時远加されおいたす。このペヌゞでは、珟圚予定されおいるリリヌスの状況やスケゞュヌルを掲茉しおいたす。

📢 アナりンス

  • Nuxt 3 ベヌタ
  • Nuxt 3 リリヌス候補

📅 リリヌススケゞュヌル

リリヌス 予定日 説明
nuxt@3.0.0-rc.1 2022 幎 3 月 Nuxt v3 初リリヌス候補
nuxt@2.16 2022 幎 3 月 Nuxt v2 将来の互換性のための环積的な曎新
nuxt@3.0.0 2022 幎 6 月 Nuxt v3 安定リリヌス

最近のリリヌス

珟圚、Nuxt 2 が安定版ずされおいたす。

Nuxt 2.x の最新アップデヌトは nuxt-edge npm パッケヌゞ経由で入手でき、将来の互換性のために Nuxt 3 の最初のリリヌス候補ず䞀緒にリリヌスされる予定です。Nuxt 3 は珟圚開発䞭で、nuxt3 npm パッケヌゞずしお利甚でき、ベヌタテスト甚に自動リリヌスされおいたす。

リリヌス npm ステヌタス 最終リリヌス ドキュメント リポゞトリ
Nuxt 2.x nuxt メンテナンス npm v2.15.8 2.x ドキュメント nuxt/nuxt.js#2.x
Nuxt 2.xedge* nuxt-edge メンテナンス npm v2.16.0-27358576.777a4b7f 2.x ドキュメント nuxt/nuxt.js
Nuxt 3.xedge* nuxt 3 開発䞭 npm v3.0.0-27470397.9ebea90 3.x ドキュメント nuxt/framework

*Edge のリリヌスは、各コミットがテストに合栌した埌に自動化されたす

🛣 ロヌドマップ

ロヌドマップでは、Nuxt 3 に搭茉される䞻な機胜を玹介しおいたす。

💡 今埌の機胜やアむデアに぀いおは、Discussions や RFC をチェックしおください。

マむルストヌン 予定日 ノヌト 説明
Nitro パック Q1 2022 nuxt/framework#3161 Nuxt 3 甚の安定したフル機胜のサヌバヌ゚ンゞン
生成ずキャッシュ Q1 2022 nuxt/framework#3161 ルヌトキャッシングルヌル、フルスタティック生成
テスト Utils Q1 2022 nuxt/framework#3198 Nuxt 3 ず新しいモゞュヌルをテストするために nuxt/test-utils を曞き盎したした
Nuxt 3 RC Q1 2022 nuxt/framework#3447 Nuxt 3 初リリヌス候補
Extending Q1 2022 nuxt/framework#3222 ネむティブ゚クステンションずテヌマのサポヌト
Content v2 Q1 2022 - Nuxt 3 をサポヌトするために nuxt/content を曞き盎したした
Devtools Q2 2022 - Nuxt のための統合された devtools ゚クスペリ゚ンス
Auth Q2 2022 - nuxt-community/auth-module を Nuxt 3 察応に曞き盎したものです
SEO & PWA Q2 2022 nuxt/framework#1823 nuxt-community/pwa-module からの移行は、組み蟌みの SEO ナヌティリティずサヌビスワヌカヌをサポヌトするためです。
翻蚳 Q2/Q3 2022 nuxt/framework#4private Nuxt 3 ドキュメントの安定した翻蚳プロセスのための共同プロゞェクトです。珟圚、アむデアずドキュメントツヌルのサポヌトリモヌト゜ヌスによるコンテンツ v2を申請䞭です。

コアモゞュヌル

Nuxt フレヌムワヌクの他に、゚コシステムに欠かせないモゞュヌルがありたす。それらのステヌタスは以䞋に曎新されたす。

モゞュヌル ステヌタス Nuxt サポヌト リポゞトリ 説明
Content 1.x メンテナンス 2.x nuxt/content メンテナンスのみ
Content 2.x 進行䞭の䜜業 3.x nuxt/content-next プラむベヌトベヌタ
Auth 進行䞭の䜜業 3.x nuxt/auth プラむベヌトベヌタ
Image アクティブ 2.x nuxt/image Nuxt 3 サポヌト予定
Telementry アクティブ 2.x nuxt/telementry Nuxt 3 サポヌト予定

API

useAsyncData

pages、コンポヌネント、およびプラグむン内で、useAsyncData を䜿甚しお、非同期で解決されるデヌタにアクセスできたす。

型

Signature
function useAsyncData(
  key: string,
  handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
  options?: AsyncDataOptions
): Promise<DataT>

type AsyncDataOptions = {
  server?: boolean
  lazy?: boolean
  default?: () => DataT | Ref<DataT>
  transform?: (input: DataT) => DataT
  pick?: string[]
  watch?: WatchSource[]
  initialCache?: boolean
}

type DataT = {
  data: Ref<DataT>
  pending: Ref<boolean>
  refresh: () => Promise<void>
  error: Ref<any>
}

Params

  • key: デヌタフェッチをリク゚スト間で適切に重耇排陀できるようにするための䞀意のキヌ
  • handler: 倀を返す非同期関数
  • オプション:
    • lazy: ナビゲヌションをブロックする代わりに、ルヌトのロヌド埌に非同期関数を解決するかどうかデフォルトは false
    • default: 非同期関数が解決する前にデヌタのデフォルト倀を蚭定するファクトリ関数 - 特に lazy: true オプションで圹立ちたす
    • server: サヌバヌ䞊のデヌタをフェッチするかどうかデフォルトは true
    • transform: 解決埌に handler 関数の結果を倉曎するために䜿甚できる関数
    • pick: handler 関数の結果からこの配列内の指定されたキヌのみを遞択したす
    • watch: リアクティブ゜ヌスを監芖しお自動曎新したす
    • initialCache: false に蚭定するず、初期フェッチのペむロヌドキャッシュをスキップしたすデフォルトは true

内郚的には、lazy: false は <Suspense> を䜿甚しお、デヌタがフェッチされる前にルヌトのロヌドをブロックしたす。より迅速なナヌザヌ゚クスペリ゚ンスのために、lazy: true を䜿甚し、代わりに読み蟌み状態を実装するこずを怜蚎しおください。

戻り倀

  • data: 枡された非同期関数の結果
  • pending: デヌタがただフェッチされおいるかどうかを瀺すブヌル倀
  • refresh: ハンドラヌ関数によっお返されたデヌタを曎新するために䜿甚できる関数
  • error: デヌタのフェッチに倱敗した堎合の゚ラヌオブゞェクト

デフォルトでは、Nuxt は 曎新 が終了するたで埅機しおから再床実行できたす。パラメヌタずしお true を枡すず、その埅機はスキップされたす。

䟋

const { data, pending, error, refresh } = await useAsyncData(
  'mountains',
  () => $fetch('https://api.nuxtjs.dev/mountains')
)

useCookie

useError

useFetch

useHead

useHydration

useLazyAsyncData

useLazyFetch

useNuxtApp

useRequestHeaders

useRoute

useRouter

useState

<NuxtPage>

<NuxtLayout>

<NuxtLink>

<NuxtErrorBoundary>

$fetch

abortNavigation

addRouteMiddleware

clearError

defineNuxtComponent

defineNuxtRouteMiddleware

definePageMeta

refreshNuxtData

throwError

ラむフサむクルフック

アプリフックランタむム

利甚可胜なすべおのフックに぀いおは、アプリの゜ヌスコヌド を確認しおください。

フック 匕数 説明
app:created vueApp vueApp の初期むンスタンス䜜成時
app:beforeMount vueApp app:created ず同じ
app:mounted vueApp Vue アプリが初期化され、ブラりザにマりントされた時
app:rendered - SSR レンダリングが行われた時
app:suspense:resolve appComponent Suspense 解決むベント
page:start pageComponent Suspense 解決むベント
page:finish pageComponent Suspense 解決むベント
meta:register metaRenderers 内郚
vue:setup - 内郚

Nuxt フックビルドタむム

利甚可胜なすべおのフックに぀いおは、スキヌマの゜ヌスコヌド を確認しおください。

Kit ナヌティリティ

ナヌティリティ

モゞュヌル

kit/src/module/container.ts
import { parse, relative } from 'pathe'
import type { Nuxt, NuxtPluginTemplate, NuxtTemplate, ModuleContainer } from '@nuxt/schema'
import { logger } from '../logger'
import { chainFn } from '../internal/task'
import { addTemplate } from '../template'
import { addServerMiddleware } from '../server'
import { isNuxt2 } from '../compatibility'
import { addPluginTemplate } from '../plugin'
import { useNuxt } from '../context'
import { installModule } from './install'

const MODULE_CONTAINER_KEY = '__module_container__'

export function useModuleContainer (nuxt: Nuxt = useNuxt()): ModuleContainer {
  if (nuxt[MODULE_CONTAINER_KEY]) {
    return nuxt[MODULE_CONTAINER_KEY]
  }

  async function requireModule (moduleOpts) {
    let src, inlineOptions
    if (typeof moduleOpts === 'string') {
      src = moduleOpts
    } else if (Array.isArray(moduleOpts)) {
      [src, inlineOptions] = moduleOpts
    } else if (typeof moduleOpts === 'object') {
      if (moduleOpts.src || moduleOpts.handler) {
        src = moduleOpts.src || moduleOpts.handler
        inlineOptions = moduleOpts.options
      } else {
        src = moduleOpts
      }
    } else {
      src = moduleOpts
    }
    await installModule(src, inlineOptions)
  }

  nuxt[MODULE_CONTAINER_KEY] = <ModuleContainer>{
    nuxt,
    options: nuxt.options,

    ready () { return Promise.resolve() },
    addVendor () {},

    requireModule,
    addModule: requireModule,

    addServerMiddleware,

    addTemplate (template: string | NuxtTemplate) {
      if (typeof template === 'string') {
        template = { src: template }
      }
      if (template.write === undefined) {
        template.write = true
      }
      return addTemplate(template)
    },

    addPlugin (pluginTemplate: NuxtPluginTemplate): NuxtPluginTemplate {
      return addPluginTemplate(pluginTemplate)
    },

    addLayout (tmpl: NuxtTemplate, name: string) {
      const { filename, src } = addTemplate(tmpl)
      const layoutName = name || parse(src).name
      const layout = nuxt.options.layouts[layoutName]

      if (layout) {
        logger.warn(`Duplicate layout registration, "${layoutName}" has been registered as "${layout}"`)
      }
      nuxt.options.layouts[layoutName] = `./${filename}`
      if (name === 'error') {
        this.addErrorLayout(filename)
      }
    },

    addErrorLayout (dst: string) {
      const relativeBuildDir = relative(nuxt.options.rootDir, nuxt.options.buildDir)
      nuxt.options.ErrorPage = `~/${relativeBuildDir}/${dst}`
    },

    extendBuild (fn) {
      // @ts-ignore
      nuxt.options.build.extend = chainFn(nuxt.options.build.extend, fn)

      if (!isNuxt2(nuxt)) {
        console.warn('[kit] [compat] Using `extendBuild` in Nuxt 3 has no effect. Instead call extendWebpackConfig and extendViteConfig.')
      }
    },

    extendRoutes (fn) {
      if (isNuxt2(nuxt)) {
        nuxt.options.router.extendRoutes = chainFn(nuxt.options.router.extendRoutes, fn)
      } else {
        nuxt.hook('pages:extend', async (pages, ...args) => {
          const maybeRoutes = await fn(pages, ...args)
          if (maybeRoutes) {
            console.warn('[kit] [compat] Using `extendRoutes` in Nuxt 3 needs to directly modify first argument instead of returning updated routes. Skipping extended routes.')
          }
        })
      }
    }
  }

  return nuxt[MODULE_CONTAINER_KEY]
}
kit/src/module/define.ts
import { promises as fsp } from 'node:fs'
import defu from 'defu'
import { applyDefaults } from 'untyped'
import { dirname } from 'pathe'
import type { Nuxt, NuxtTemplate, NuxtModule, ModuleOptions, ModuleDefinition } from '@nuxt/schema'
import { logger } from '../logger'
import { useNuxt, nuxtCtx, tryUseNuxt } from '../context'
import { isNuxt2, checkNuxtCompatibility } from '../compatibility'
import { templateUtils, compileTemplate } from '../internal/template'

/**
 * Define a Nuxt module, automatically merging defaults with user provided options, installing
 * any hooks that are provided, and calling an optional setup function for full control.
 */
export function defineNuxtModule<OptionsT extends ModuleOptions> (definition: ModuleDefinition<OptionsT>): NuxtModule<OptionsT> {
  // Legacy format. TODO: Remove in RC
  if (typeof definition === 'function') {
    // @ts-ignore
    definition = definition(useNuxt())
    logger.warn('Module definition as function is deprecated and will be removed in the future versions', definition)
  }

  // Normalize definition and meta
  if (!definition.meta) { definition.meta = {} }
  if (!definition.meta.configKey) {
    // @ts-ignore TODO: Remove non-meta fallbacks in RC
    definition.meta.name = definition.meta.name || definition.name
    // @ts-ignore
    definition.meta.configKey = definition.meta.configKey || definition.configKey || definition.meta.name
  }

  // Resolves module options from inline options, [configKey] in nuxt.config, defaults and schema
  function getOptions (inlineOptions?: OptionsT, nuxt: Nuxt = useNuxt()) {
    const configKey = definition.meta.configKey || definition.meta.name
    const _defaults = definition.defaults instanceof Function ? definition.defaults(nuxt) : definition.defaults
    let _options = defu(inlineOptions, nuxt.options[configKey], _defaults) as OptionsT
    if (definition.schema) {
      _options = applyDefaults(definition.schema, _options) as OptionsT
    }
    return Promise.resolve(_options)
  }

  // Module format is always a simple function
  async function normalizedModule (inlineOptions: OptionsT, nuxt: Nuxt) {
    if (!nuxt) {
      nuxt = tryUseNuxt() || this.nuxt /* invoked by nuxt 2 */
    }

    // Avoid duplicate installs
    const uniqueKey = definition.meta.name || definition.meta.configKey
    if (uniqueKey) {
      nuxt.options._requiredModules = nuxt.options._requiredModules || {}
      if (nuxt.options._requiredModules[uniqueKey]) {
        // TODO: Notify user if inline options is provided since will be ignored!
        return
      }
      nuxt.options._requiredModules[uniqueKey] = true
    }

    // Check compatibility constraints
    if (definition.meta.compatibility) {
      const issues = await checkNuxtCompatibility(definition.meta.compatibility, nuxt)
      if (issues.length) {
        logger.warn(`Module \`${definition.meta.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`)
        return
      }
    }

    // Prepare
    nuxt2Shims(nuxt)

    // Resolve module and options
    const _options = await getOptions(inlineOptions, nuxt)

    // Register hooks
    if (definition.hooks) {
      nuxt.hooks.addHooks(definition.hooks)
    }

    // Call setup
    await definition.setup?.call(null, _options, nuxt)
  }

  // Define getters for options and meta
  normalizedModule.getMeta = () => Promise.resolve(definition.meta)
  normalizedModule.getOptions = getOptions

  return normalizedModule as NuxtModule<OptionsT>
}

// -- Nuxt 2 compatibility shims --
const NUXT2_SHIMS_KEY = '__nuxt2_shims_key__'
function nuxt2Shims (nuxt: Nuxt) {
  // Avoid duplicate install and only apply to Nuxt2
  if (!isNuxt2(nuxt) || nuxt[NUXT2_SHIMS_KEY]) { return }
  nuxt[NUXT2_SHIMS_KEY] = true

  // Allow using nuxt.hooks
  // @ts-ignore Nuxt 2 extends hookable
  nuxt.hooks = nuxt

  // Allow using useNuxt()
  if (!nuxtCtx.use()) {
    nuxtCtx.set(nuxt)
    nuxt.hook('close', () => nuxtCtx.unset())
  }

  // Support virtual templates with getContents() by writing them to .nuxt directory
  let virtualTemplates: NuxtTemplate[]
  nuxt.hook('builder:prepared', (_builder, buildOptions) => {
    virtualTemplates = buildOptions.templates.filter(t => t.getContents)
    for (const template of virtualTemplates) {
      buildOptions.templates.splice(buildOptions.templates.indexOf(template), 1)
    }
  })
  nuxt.hook('build:templates', async (templates) => {
    const context = {
      nuxt,
      utils: templateUtils,
      app: {
        dir: nuxt.options.srcDir,
        extensions: nuxt.options.extensions,
        plugins: nuxt.options.plugins,
        templates: [
          ...templates.templatesFiles,
          ...virtualTemplates
        ],
        templateVars: templates.templateVars
      }
    }
    for await (const template of virtualTemplates) {
      const contents = await compileTemplate({ ...template, src: '' }, context)
      await fsp.mkdir(dirname(template.dst), { recursive: true })
      await fsp.writeFile(template.dst, contents)
    }
  })
}
kit/src/module/install.ts
import type { Nuxt, NuxtModule } from '@nuxt/schema'
import { useNuxt } from '../context'
import { resolveModule, requireModule, importModule } from '../internal/cjs'
import { resolveAlias } from '../resolve'
import { useModuleContainer } from './container'

/** Installs a module on a Nuxt instance. */
export async function installModule (moduleToInstall: string | NuxtModule, _inlineOptions?: any, _nuxt?: Nuxt) {
  const nuxt = useNuxt()
  const { nuxtModule, inlineOptions } = await normalizeModule(moduleToInstall, _inlineOptions)

  // Call module
  await nuxtModule.call(useModuleContainer(), inlineOptions, nuxt)

  nuxt.options._installedModules = nuxt.options._installedModules || []
  nuxt.options._installedModules.push({
    meta: await nuxtModule.getMeta?.(),
    entryPath: typeof moduleToInstall === 'string' ? resolveAlias(moduleToInstall) : undefined
  })
}

// --- Internal ---

async function normalizeModule (nuxtModule: string | NuxtModule, inlineOptions?: any) {
  const nuxt = useNuxt()

  // Detect if `installModule` used with older signuture (nuxt, nuxtModule)
  // TODO: Remove in RC
  // @ts-ignore
  if (nuxtModule?._version || nuxtModule?.version || nuxtModule?.constructor?.version || '') {
    [nuxtModule, inlineOptions] = [inlineOptions, {}]
    console.warn(new Error('`installModule` is being called with old signature!'))
  }

  // Import if input is string
  if (typeof nuxtModule === 'string') {
    const _src = resolveModule(resolveAlias(nuxtModule), { paths: nuxt.options.modulesDir })
    // TODO: also check with type: 'module' in closest `package.json`
    const isESM = _src.endsWith('.mjs')
    nuxtModule = isESM ? await importModule(_src) : requireModule(_src)
  }

  // Throw error if input is not a function
  if (typeof nuxtModule !== 'function') {
    throw new TypeError('Nuxt module should be a function: ' + nuxtModule)
  }

  return { nuxtModule, inlineOptions } as { nuxtModule: NuxtModule<any>, inlineOptions: undefined | Record<string, any> }
}
  • installModule(module, inlineOptions)

プログラムの䜿甚法

kit/src/loader/config.ts
import { resolve } from 'pathe'
import { applyDefaults } from 'untyped'
import { loadConfig, LoadConfigOptions } from 'c12'
import type { NuxtOptions, NuxtConfig } from '@nuxt/schema'
import { NuxtConfigSchema } from '@nuxt/schema'

export interface LoadNuxtConfigOptions extends LoadConfigOptions<NuxtConfig> {}

export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
  const { config: nuxtConfig, configFile, layers, cwd } = await loadConfig({
    name: 'nuxt',
    configFile: 'nuxt.config',
    rcFile: '.nuxtrc',
    dotenv: true,
    globalRc: true,
    ...opts
  })

  // Fill config
  nuxtConfig.rootDir = nuxtConfig.rootDir || cwd
  nuxtConfig._nuxtConfigFile = configFile
  nuxtConfig._nuxtConfigFiles = [configFile]

  // Resolve `rootDir` & `srcDir` of layers
  for (const layer of layers) {
    layer.config.rootDir = layer.config.rootDir ?? layer.cwd
    layer.config.srcDir = resolve(layer.config.rootDir, layer.config.srcDir)
  }

  // Filter layers
  nuxtConfig._layers = layers.filter(layer => layer.configFile && !layer.configFile.endsWith('.nuxtrc'))

  // Resolve and apply defaults
  return applyDefaults(NuxtConfigSchema, nuxtConfig) as NuxtOptions
}
kit/src/loader/nuxt.ts
import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
import type { Nuxt } from '@nuxt/schema'
import { importModule, tryImportModule, RequireModuleOptions } from '../internal/cjs'
import type { LoadNuxtConfigOptions } from './config'

export interface LoadNuxtOptions extends LoadNuxtConfigOptions {
  /** Load nuxt with development mode */
  dev?: boolean

  /** Use lazy initialization of nuxt if set to false */
  ready?: boolean

  /** @deprecated Use cwd option */
  rootDir?: LoadNuxtConfigOptions['cwd']

  /** @deprecated use overrides option */
  config?: LoadNuxtConfigOptions['overrides']
}

export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
  // Backward compatibility
  opts.cwd = opts.cwd || opts.rootDir
  opts.overrides = opts.overrides || opts.config || {}

  const resolveOpts: RequireModuleOptions = { paths: opts.cwd }

  // Apply dev as config override
  opts.overrides.dev = !!opts.dev

  const nearestNuxtPkg = await Promise.all(['nuxt3', 'nuxt', 'nuxt-edge']
    .map(pkg => resolvePackageJSON(pkg, { url: opts.cwd }).catch(() => null)))
    .then(r => r.filter(Boolean).sort((a, b) => b.length - a.length)[0])
  if (!nearestNuxtPkg) {
    throw new Error(`Cannot find any nuxt version from ${opts.cwd}`)
  }
  const pkg = await readPackageJSON(nearestNuxtPkg)
  const majorVersion = parseInt((pkg.version || '').split('.')[0])

  // Nuxt 3
  if (majorVersion === 3) {
    const { loadNuxt } = await importModule((pkg as any)._name || pkg.name, resolveOpts)
    const nuxt = await loadNuxt(opts)
    return nuxt
  }

  // Nuxt 2
  const { loadNuxt } = await tryImportModule('nuxt-edge', resolveOpts) || await importModule('nuxt', resolveOpts)
  const nuxt = await loadNuxt({
    rootDir: opts.cwd,
    for: opts.dev ? 'dev' : 'build',
    configOverrides: opts.overrides,
    ready: opts.ready,
    envConfig: opts.dotenv // TODO: Backward format convertion
  })

  return nuxt as Nuxt
}

export async function buildNuxt (nuxt: Nuxt): Promise<any> {
  const resolveOpts: RequireModuleOptions = { paths: nuxt.options.rootDir }

  // Nuxt 3
  if (nuxt.options._majorVersion === 3) {
    const { build } = await tryImportModule('nuxt3', resolveOpts) || await importModule('nuxt', resolveOpts)
    return build(nuxt)
  }

  // Nuxt 2
  const { build } = await tryImportModule('nuxt-edge', resolveOpts) || await importModule('nuxt', resolveOpts)
  return build(nuxt)
}
  • loadNuxt(loadOptions)
  • buildNuxt(nuxt)
  • loadNuxtConfig(loadOptions)

互換性

kit/src/compatibility.ts
import satisfies from 'semver/functions/satisfies.js' // npm/node-semver#381
import type { Nuxt, NuxtCompatibility, NuxtCompatibilityIssues } from '@nuxt/schema'
import { useNuxt } from './context'

/**
 * Check version constraints and return incompatibility issues as an array
 */
export async function checkNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<NuxtCompatibilityIssues> {
  const issues: NuxtCompatibilityIssues = []

  // Nuxt version check
  if (constraints.nuxt) {
    const nuxtVersion = getNuxtVersion(nuxt)
    const nuxtSemanticVersion = nuxtVersion.split('-').shift()
    if (!satisfies(nuxtSemanticVersion, constraints.nuxt)) {
      issues.push({
        name: 'nuxt',
        message: `Nuxt version \`${constraints.nuxt}\` is required but currently using \`${nuxtVersion}\``
      })
    }
  }

  // Bridge compatibility check
  if (isNuxt2(nuxt)) {
    const bridgeRequirement = constraints?.bridge
    const hasBridge = !!(nuxt.options as any).bridge
    if (bridgeRequirement === true && !hasBridge) {
      issues.push({
        name: 'bridge',
        message: 'Nuxt bridge is required'
      })
    } else if (bridgeRequirement === false && hasBridge) {
      issues.push({
        name: 'bridge',
        message: 'Nuxt bridge is not supported'
      })
    }
  }

  // Allow extending compatibility checks
  await nuxt.callHook('kit:compatibility', constraints, issues)

  // Issues formatter
  issues.toString = () =>
    issues.map(issue => ` - [${issue.name}] ${issue.message}`).join('\n')

  return issues
}

/**
 * Check version constraints and throw a detailed error if has any, otherwise returns true
 */
export async function assertNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<true> {
  const issues = await checkNuxtCompatibility(constraints, nuxt)
  if (issues.length) {
    throw new Error('Nuxt compatibility issues found:\n' + issues.toString())
  }
  return true
}

/**
 * Check version constraints and return true if passed, otherwise returns false
 */
export async function hasNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<boolean> {
  const issues = await checkNuxtCompatibility(constraints, nuxt)
  return !issues.length
}

/**
 * Check if current nuxt instance is version 2 legacy
 */
export function isNuxt2 (nuxt: Nuxt = useNuxt()) {
  return getNuxtVersion(nuxt).startsWith('2.')
}

/**
 * Check if current nuxt instance is version 3
 */
export function isNuxt3 (nuxt: Nuxt = useNuxt()) {
  return getNuxtVersion(nuxt).startsWith('3.')
}

/**
 * Get nuxt version
 */
export function getNuxtVersion (nuxt: Nuxt | any = useNuxt() /* TODO: LegacyNuxt */) {
  const version = (nuxt?._version || nuxt?.version || nuxt?.constructor?.version || '').replace(/^v/g, '')
  if (!version) {
    throw new Error('Cannot determine nuxt version! Is currect instance passed?')
  }
  return version
}
  • checkNuxtCompatibility(constraints)
  • assertNuxtCompatibility(constraints)
  • hasNuxtCompatibility(constraints)
  • isNuxt2()
  • isNuxt3()
  • getNuxtVersion()

コンポヌネント

kit/src/components.ts
import { pascalCase, kebabCase } from 'scule'
import type { ComponentsDir, Component } from '@nuxt/schema'
import { genDynamicImport } from 'knitwork'
import { useNuxt } from './context'
import { assertNuxtCompatibility } from './compatibility'

/**
 * Register a directory to be scanned for components and imported only when used.
 *
 * Requires Nuxt 2.13+
 */
export async function addComponentsDir (dir: ComponentsDir) {
  const nuxt = useNuxt()
  await assertNuxtCompatibility({ nuxt: '>=2.13' }, nuxt)
  nuxt.options.components = nuxt.options.components || []
  nuxt.hook('components:dirs', (dirs) => { dirs.push(dir) })
}

export type AddComponentOptions = { name: string, filePath: string } & Partial<Exclude<Component,
'shortPath' | 'async' | 'level' | 'import' | 'asyncImport'
>>

/**
 * Register a directory to be scanned for components and imported only when used.
 *
 * Requires Nuxt 2.13+
 */
export async function addComponent (opts: AddComponentOptions) {
  const nuxt = useNuxt()
  await assertNuxtCompatibility({ nuxt: '>=2.13' }, nuxt)
  nuxt.options.components = nuxt.options.components || []

  // Apply defaults
  const component: Component = {
    export: opts.export || 'default',
    chunkName: 'components/' + kebabCase(opts.name),
    global: opts.global ?? false,
    kebabName: kebabCase(opts.name || ''),
    pascalName: pascalCase(opts.name || ''),
    prefetch: false,
    preload: false,
    mode: 'all',

    // Nuxt 2 support
    shortPath: opts.filePath,
    async: false,
    level: 0,
    asyncImport: `${genDynamicImport(opts.filePath)}.then(r => r['${opts.export || 'default'}'])`,
    import: `require(${JSON.stringify(opts.filePath)})['${opts.export || 'default'}']`,

    ...opts
  }

  nuxt.hook('components:extend', (components: Component[]) => {
    const existingComponent = components.find(c => c.pascalName === component.pascalName || c.kebabName === component.kebabName)
    if (existingComponent) {
      const name = existingComponent.pascalName || existingComponent.kebabName
      console.warn(`Overriding ${name} component.`)
      Object.assign(existingComponent, component)
    } else {
      components.push(component)
    }
  })
}
  • addComponentsDir(dir)
  • addComponent(componentObject)

コンテキスト

kit/src/context.ts
import { getContext } from 'unctx'
import type { Nuxt } from '@nuxt/schema'

/** Direct access to the Nuxt context - see https://github.com/unjs/unctx. */
export const nuxtCtx = getContext<Nuxt>('nuxt')

// TODO: Use use/tryUse from unctx. https://github.com/unjs/unctx/issues/6

/**
 * Get access to Nuxt instance.
 *
 * Throws an error if Nuxt instance is unavailable.
 *
 * @example
 * ```js
 * const nuxt = useNuxt()
 * ```
 */
export function useNuxt (): Nuxt {
  const instance = nuxtCtx.use()
  if (!instance) {
    throw new Error('Nuxt instance is unavailable!')
  }
  return instance
}

/**
 * Get access to Nuxt instance.
 *
 * Returns null if Nuxt instance is unavailable.
 *
 * @example
 * ```js
 * const nuxt = tryUseNuxt()
 * if (nuxt) {
 *  // Do something
 * }
 * ```
 */
export function tryUseNuxt (): Nuxt | null {
  return nuxtCtx.use()
}
  • useNuxt()

プラグむン

kit/src/plugin.ts
import { normalize } from 'pathe'
import type { NuxtPlugin, NuxtPluginTemplate } from '@nuxt/schema'
import { useNuxt } from './context'
import { addTemplate } from './template'

/**
 * Normalize a nuxt plugin object
 */
export function normalizePlugin (plugin: NuxtPlugin | string): NuxtPlugin {
  // Normalize src
  if (typeof plugin === 'string') {
    plugin = { src: plugin }
  } else {
    plugin = { ...plugin }
  }

  if (!plugin.src) {
    throw new Error('Invalid plugin. src option is required: ' + JSON.stringify(plugin))
  }

  // Normalize full path to plugin
  plugin.src = normalize(plugin.src)

  // Normalize mode
  if (plugin.ssr) {
    plugin.mode = 'server'
  }
  if (!plugin.mode) {
    const [, mode = 'all'] = plugin.src.match(/\.(server|client)(\.\w+)*$/) || []
    plugin.mode = mode as 'all' | 'client' | 'server'
  }

  return plugin
}

/**
 * Registers a nuxt plugin and to the plugins array.
 *
 * Note: You can use mode or .client and .server modifiers with fileName option
 * to use plugin only in client or server side.
 *
 * Note: By default plugin is prepended to the plugins array. You can use second argument to append (push) instead.
 *
 * @example
 * ```js
 * addPlugin({
 *   src: path.resolve(__dirname, 'templates/foo.js'),
 *   filename: 'foo.server.js' // [optional] only include in server bundle
 * })
 * ```
 */
export interface AddPluginOptions { append?: boolean }
export function addPlugin (_plugin: NuxtPlugin | string, opts: AddPluginOptions = {}) {
  const nuxt = useNuxt()

  // Normalize plugin
  const plugin = normalizePlugin(_plugin)

  // Remove any existing plugin with the same src
  nuxt.options.plugins = nuxt.options.plugins.filter(p => normalizePlugin(p).src !== plugin.src)

  // Prepend to array by default to be before user provided plugins since is usually used by modules
  nuxt.options.plugins[opts.append ? 'push' : 'unshift'](plugin)

  return plugin
}

/**
 * Adds a template and registers as a nuxt plugin.
 */
export function addPluginTemplate (plugin: NuxtPluginTemplate | string, opts: AddPluginOptions = {}): NuxtPlugin {
  const normalizedPlugin: NuxtPlugin = typeof plugin === 'string'
    ? { src: plugin }
    // Update plugin src to template destination
    : { ...plugin, src: addTemplate(plugin).dst }

  return addPlugin(normalizedPlugin, opts)
}
  • addPlugin(pluginOptions, { append? })
  • addPluginTemplate(pluginOptions, { append? })

テンプレヌト

kit/src/template.ts
import { existsSync } from 'node:fs'
import { basename, parse, resolve } from 'pathe'
import hash from 'hash-sum'
import type { NuxtTemplate } from '@nuxt/schema'
import { useNuxt } from './context'

/**
 * Renders given template using lodash template during build into the project buildDir
 */
export function addTemplate (_template: NuxtTemplate | string) {
  const nuxt = useNuxt()

  // Noprmalize template
  const template = normalizeTemplate(_template)

  // Remove any existing template with the same filename
  nuxt.options.build.templates = nuxt.options.build.templates
    .filter(p => normalizeTemplate(p).filename !== template.filename)

  // Add to templates array
  nuxt.options.build.templates.push(template)

  return template
}

/**
 * Normalize a nuxt template object
 */
export function normalizeTemplate (template: NuxtTemplate | string): NuxtTemplate {
  if (!template) {
    throw new Error('Invalid template: ' + JSON.stringify(template))
  }

  // Normalize
  if (typeof template === 'string') {
    template = { src: template }
  } else {
    template = { ...template }
  }

  // Use src if provided
  if (template.src) {
    if (!existsSync(template.src)) {
      throw new Error('Template not found: ' + template.src)
    }
    if (!template.filename) {
      const srcPath = parse(template.src)
      template.filename = template.fileName ||
        `${basename(srcPath.dir)}.${srcPath.name}.${hash(template.src)}${srcPath.ext}`
    }
  }

  if (!template.src && !template.getContents) {
    throw new Error('Invalid template. Either getContents or src options should be provided: ' + JSON.stringify(template))
  }

  if (!template.filename) {
    throw new Error('Invalid template. Either filename should be provided: ' + JSON.stringify(template))
  }

  // Always write declaration files
  if (template.filename.endsWith('.d.ts')) {
    template.write = true
  }

  // Resolve dst
  if (!template.dst) {
    const nuxt = useNuxt()
    template.dst = resolve(nuxt.options.buildDir, template.filename)
  }

  return template
}
  • addTemplate(templateOptions)

サヌバヌ

kit/src/server.ts
import type { Middleware } from 'h3'
import { useNuxt } from './context'

export interface ServerMiddleware {
  route?: string,
  handler: Middleware | string
}

/** Adds a new server middleware to the end of the server middleware array. */
export function addServerMiddleware (middleware: ServerMiddleware) {
  useNuxt().options.serverMiddleware.push(middleware)
}
  • addServerMiddleware(serverMiddleware)

Resolving

kit/src/resolve.ts
import { promises as fsp, existsSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { basename, dirname, resolve, join, normalize, isAbsolute } from 'pathe'
import { globby } from 'globby'
import { tryUseNuxt, useNuxt } from './context'
import { tryResolveModule } from './internal/cjs'
import { isIgnored } from './ignore'

export interface ResolvePathOptions {
  /** Base for resolving paths from. Default is Nuxt rootDir. */
  cwd?: string

  /** An object of aliases. Default is Nuxt configured aliases. */
  alias?: Record<string, string>

  /** The file extensions to try. Default is Nuxt configured extensions. */
  extensions?: string[]
}

/**
 * Resolve full path to a file or directory respecting Nuxt alias and extensions options
 *
 * If path could not be resolved, normalized input path will be returned
 */
export async function resolvePath (path: string, opts: ResolvePathOptions = {}): Promise<string> {
  // Always normalize input
  const _path = path
  path = normalize(path)

  // Fast return if the path exists
  if (isAbsolute(path) && existsSync(path)) {
    return path
  }

  // Use current nuxt options
  const nuxt = useNuxt()
  const cwd = opts.cwd || (nuxt ? nuxt.options.rootDir : process.cwd())
  const extensions = opts.extensions || (nuxt ? nuxt.options.extensions : ['.ts', '.mjs', '.cjs', '.json'])
  const modulesDir = nuxt ? nuxt.options.modulesDir : []

  // Resolve aliases
  path = resolveAlias(path)

  // Resolve relative to cwd
  if (!isAbsolute(path)) {
    path = resolve(cwd, path)
  }

  // Check if resolvedPath is a file
  let isDirectory = false
  if (existsSync(path)) {
    isDirectory = (await fsp.lstat(path)).isDirectory()
    if (!isDirectory) {
      return path
    }
  }

  // Check possible extensions
  for (const ext of extensions) {
    // path.[ext]
    const pathWithExt = path + ext
    if (existsSync(pathWithExt)) {
      return pathWithExt
    }
    // path/index.[ext]
    const pathWithIndex = join(path, 'index' + ext)
    if (isDirectory && existsSync(pathWithIndex)) {
      return pathWithIndex
    }
  }

  // Try to resolve as module id
  const resolveModulePath = tryResolveModule(_path, { paths: [cwd, ...modulesDir] })
  if (resolveModulePath) {
    return resolveModulePath
  }

  // Return normalized input
  return path
}

/**
 * Try to resolve first existing file in paths
 */
export async function findPath (paths: string|string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise<string|null> {
  if (!Array.isArray(paths)) {
    paths = [paths]
  }
  for (const path of paths) {
    const rPath = await resolvePath(path, opts)
    if (await existsSensitive(rPath)) {
      const isDirectory = (await fsp.lstat(rPath)).isDirectory()
      if (!pathType || (pathType === 'file' && !isDirectory) || (pathType === 'dir' && isDirectory)) {
        return rPath
      }
    }
  }
  return null
}

/**
 * Resolve path aliases respecting Nuxt alias options
 */
export function resolveAlias (path: string, alias?: Record<string, string>): string {
  if (!alias) {
    alias = tryUseNuxt()?.options.alias || {}
  }
  for (const key in alias) {
    if (key === '@' && !path.startsWith('@/')) { continue } // Don't resolve @foo/bar
    if (path.startsWith(key)) {
      path = alias[key] + path.slice(key.length)
    }
  }
  return path
}

export interface Resolver {
  resolve(...path): string
  resolvePath(path: string, opts?: ResolvePathOptions): Promise<string>
}

/**
 * Create a relative resolver
 */
export function createResolver (base: string | URL): Resolver {
  if (!base) {
    throw new Error('`base` argument is missing for createResolver(base)!')
  }

  base = base.toString()
  if (base.startsWith('file://')) {
    base = dirname(fileURLToPath(base))
  }

  return {
    resolve: (...path) => resolve(base as string, ...path),
    resolvePath: (path, opts) => resolvePath(path, { cwd: base as string, ...opts })
  }
}

// --- Internal ---

async function existsSensitive (path: string) {
  if (!existsSync(path)) { return false }
  const dirFiles = await fsp.readdir(dirname(path))
  return dirFiles.includes(basename(path))
}

export async function resolveFiles (path: string, pattern: string | string[]) {
  const files = await globby(pattern, { cwd: path, followSymbolicLinks: true })
  return files.filter(p => !isIgnored(p)).map(p => resolve(path, p))
}
  • resolvePath (path, resolveOptions?)
  • resolveAlias (path, aliases?)
  • findPath (paths, resolveOptions?)
  • createResolver (base)

ビルダヌ

kit/src/build.ts
import type { WebpackPluginInstance, Configuration as WebpackConfig } from 'webpack'
import type { Plugin as VitePlugin, UserConfig as ViteConfig } from 'vite'
import { useNuxt } from './context'

export interface ExtendConfigOptions {
  /**
   * Install plugin on dev
   *
   * @default true
   */
   dev?: boolean
   /**
    * Install plugin on build
    *
    * @default true
    */
   build?: boolean
}

export interface ExtendWebpackConfigOptions extends ExtendConfigOptions {
  /**
   * Install plugin on server side
   *
   * @default true
   */
  server?: boolean
  /**
   * Install plugin on client side
   *
   * @default true
   */
  client?: boolean
  /**
   * Install plugin on modern build
   *
   * @default true
   * @deprecated Nuxt 2 only
   */
  modern?: boolean
}

export interface ExtendViteConfigOptions extends ExtendConfigOptions {}

/**
 * Extend Webpack config
 *
 * The fallback function might be called multiple times
 * when applying to both client and server builds.
 */
export function extendWebpackConfig (
  fn: ((config: WebpackConfig)=> void),
  options: ExtendWebpackConfigOptions = {}
) {
  const nuxt = useNuxt()

  if (options.dev === false && nuxt.options.dev) {
    return
  }
  if (options.build === false && nuxt.options.build) {
    return
  }

  nuxt.hook('webpack:config', (configs: WebpackConfig[]) => {
    if (options.server !== false) {
      const config = configs.find(i => i.name === 'server')
      if (config) {
        fn(config)
      }
    }
    if (options.client !== false) {
      const config = configs.find(i => i.name === 'client')
      if (config) {
        fn(config)
      }
    }
    // Nuxt 2 backwards compatibility
    if (options.modern !== false) {
      const config = configs.find(i => i.name === 'modern')
      if (config) {
        fn(config)
      }
    }
  })
}

/**
 * Extend Vite config
 */
export function extendViteConfig (
  fn: ((config: ViteConfig) => void),
  options: ExtendViteConfigOptions = {}
) {
  const nuxt = useNuxt()

  if (options.dev === false && nuxt.options.dev) {
    return
  }
  if (options.build === false && nuxt.options.build) {
    return
  }

  nuxt.hook('vite:extend', ({ config }) => fn(config))
}

/**
 * Append Webpack plugin to the config.
 */
export function addWebpackPlugin (plugin: WebpackPluginInstance, options?: ExtendWebpackConfigOptions) {
  extendWebpackConfig((config) => {
    config.plugins = config.plugins || []
    config.plugins.push(plugin)
  }, options)
}

/**
 * Append Vite plugin to the config.
 */
export function addVitePlugin (plugin: VitePlugin, options?: ExtendViteConfigOptions) {
  extendViteConfig((config) => {
    config.plugins = config.plugins || []
    config.plugins.push(plugin)
  }, options)
}
  • extendWebpackConfig(callback, options?)
  • extendViteConfig(callback, options?)
  • addWebpackPlugin(webpackPlugin, options?)
  • addVitePlugin(vitePlugin, options?)

nuxi add

Nuxtアプリケヌションに゚ンティティを足堎ずしお組み蟌むこずができたす。

npx nuxi add [--cwd] [--force] <TEMPLATE> <NAME>
Option デフォルト 説明
TEMPLATE - 生成されるファむルのテンプレヌトを指定したす。
NAME - 生成されるファむルの名前を指定したす。
--cwd . 察象アプリケヌションのディレクトリです。
--force false ファむルがすでに存圚する堎合、匷制的に䞊曞きしたす。

䟋

npx nuxi add component TheHeader

add コマンドは、新しい芁玠を生成したす。

  • component: npx nuxi add component TheHeader
  • composable: npx nuxi add composable foo
  • レむアりト: npx nuxi add layout custom
  • プラグむン: npx nuxi add plugin analytics
  • ペヌゞ: npx nuxi add page about たたは npx nuxi add page "category/[id]"
  • ミドルりェア: npx nuxi add middleware auth
  • api: npx nuxi add api hello (CLIで/server/api以䞋にファむルが生成されたす)

nuxi analyze

``

nuxi build

``

nuxi dev

``

nuxi info

``

nuxi init

``

nuxi preview

``

nuxi typecheck

``

nuxi upgrade

``

䟋

Hello World

最小限の Nuxt 3 アプリケヌションは、app.vue ず nuxt.config.js のファむルだけで枈みたす。

app.vue
<script setup>
const version = 2 + 1
</script>

<template>
  <div class="hello">
    Hello Nuxt {{ version }}!
  </div>
</template>

<style scoped>
.hello {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 3rem;
  padding: 10rem;
}
</style>

゚ラヌハンドリング

この䟋では、pages、プラグむン、コンポヌネント、ミドルりェアずいう異なるコンテキストでの゚ラヌ凊理方法を瀺しおいたす。

app.vue
<script setup lang="ts">
import { throwError } from '#app'
const route = useRoute()
if ('setup' in route.query) {
  throw new Error('error in setup')
}
if ('mounted' in route.query) {
  onMounted(() => {
    throw new Error('error in mounted')
  })
}
function triggerError () {
  throw new Error('manually triggered error')
}
</script>

<template>
  <NuxtExampleLayout example="app/error-handling">
    <template #nav>
      <nav class="flex align-center gap-4 p-4">
        <NuxtLink to="/" class="n-link-base">
          Home
        </NuxtLink>
        <NuxtLink to="/other" class="n-link-base">
          Other
        </NuxtLink>
        <NuxtLink to="/404" class="n-link-base">
          404
        </NuxtLink>
        <NuxtLink to="/?middleware" class="n-link-base">
          Middleware
        </NuxtLink>
        <button class="n-link-base" @click="throwError">
          Trigger fatal error
        </button>
        <button class="n-link-base" @click="triggerError">
          Trigger non-fatal error
        </button>
      </nav>
    </template>

    <template #footer>
      <div class="text-center p-4 op-50">
        Current route: <code>{{ route.path }}</code>
      </div>
    </template>
  </NuxtExampleLayout>
</template>
error.vue
<template>
  <div class="relative font-sans" n="green6">
    <div class="container max-w-200 mx-auto py-10 px-4">
      <h1>{{ error.message }}</h1>
      There was an error 😱

      <br>
      <button @click="handleError">
        Clear error
      </button>
      <br>
      <NuxtLink to="/404">
        Trigger another error
      </NuxtLink>
      <br>
      <NuxtLink to="/">
        Navigate home
      </NuxtLink>
    </div>
  </div>
</template>

<script setup lang="ts">
defineProps({
  error: Object
})

const handleError = () => clearError({ redirect: '/' })
</script>
components/FaultyComponent.vue
<script setup>
const hasIssue = ref(true)

const fixIssue = (error) => {
  hasIssue.value = false
  error.value = null
}

</script>

<template>
  <NuxtErrorBoundary>
    <throw-error v-if="hasIssue" />
    <div v-else>
      Component is working ^_^
    </div>

    <template #error="{ error }">
      Component failed to Render -_-
      <button @click="fixIssue(error)">
        (fix the issue)
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
components/ThrowError.vue
<script setup>
throw new Error('Deliberate error by <ThrowError>')
</script>

<template>
  <div>Should never see this</div>
</template>
middleware/error.global.ts
export default defineNuxtRouteMiddleware((to) => {
  if ('middleware' in to.query) {
    return throwError('error in middleware')
  }
})
plugins/error.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('vue:error', (..._args) => {
    console.log('vue:error')
    // if (process.client) {
    //   console.log(..._args)
    // }
  })
  nuxtApp.hook('app:error', (..._args) => {
    console.log('app:error')
    // if (process.client) {
    //   console.log(..._args)
    // }
  })
  nuxtApp.vueApp.config.errorHandler = (..._args) => {
    console.log('global error handler')
    // if (process.client) {
    //   console.log(..._args)
    // }
  }
})
server/middleware/error.ts
import { useQuery, defineMiddleware } from 'h3'

export default defineMiddleware((req, res, next) => {
  if ('api' in useQuery(req)) {
    throw new Error('Server middleware error')
  }
  next()
})

プラグむン

この䟋では、plugins/ ディレクトリを䜿甚しお、プラグむンを自動登録する方法を瀺したす。

app.vue
<template>
  <NuxtExampleLayout example="app/plugins">
    <div>{{ $myPlugin() }}</div>
  </NuxtExampleLayout>
</template>
plugins/my-plugin.ts
export default defineNuxtPlugin((/* nuxtApp */) => {
  return {
    provide: {
      myPlugin: () => 'String generated from my auto-imported plugin!'
    }
  }
})

テレポヌト

Vue 3 には、<Teleport> コンポヌネントがあり、Vue アプリケヌションの倖、DOM の別の堎所にコンテンツをレンダリングしたす。

この䟋では、クラむアントサむドおよびサヌバヌサむドのレンダリングで、<Teleport> を䜿甚する方法を瀺したす。

app.vue
<template>
  <NuxtExampleLayout example="app/teleport">
    <div>
      <!-- SSR Teleport -->
      <Teleport to="body">
        SSR Teleport
      </Teleport>

      <!-- Client Teleport -->
      <ClientOnly>
        <Teleport to="body">
          <div>
            Hello from a client-side teleport!
          </div>
        </Teleport>
      </ClientOnly>

      <!-- Modal Example -->
      <MyModal />
    </div>
  </NuxtExampleLayout>
</template>
components/MyModal.vue
<script>
export default {
  data () {
    return {
      open: false
    }
  }
}
</script>

<template>
  <NButton @click="open = true">
    Open Modal
  </NButton>
  <Teleport to="body">
    <NCard v-if="open" class="modal p4">
      <p>Hello from the modal!</p>
      <NButton @click="open = false">
        Close
      </NButton>
    </NCard>
  </Teleport>
</template>

<style scoped>
.modal {
  position: fixed;
  z-index: 999;
  top: 20%;
  left: 50%;
  width: 300px;
  margin-left: -150px;
}
</style>

コンポヌネント

components/ ディレクトリにあるコンポヌネントは自動的にむンポヌトされ、テンプレヌトで自動的に䜿甚するこずができたす。他のディレクトリを蚭定しお、コンポヌネントの自動むンポヌトをサポヌトするこずができたす。

app.vue
<template>
  <NuxtExampleLayout example="auto-imports/components">
    <h1 class="text-xl opacity-50">
      Auto Imported Components
    </h1>
    <div>
      <!-- Auto Imported Components -->
      <HelloWorld class="text-2xl" />
      <Nuxt3 class="text-2xl" />
      <ParentFolderHello class="mt-6" />
      <NuxtWithPrefix class="mt-6" />
    </div>
  </NuxtExampleLayout>
</template>
components/HelloWorld.vue
<template>
  <div>
    This is HelloWorld component!
  </div>
</template>
components/Nuxt3.vue
<template>
  <b style="color: #00C58E">
    From Nuxt 3
  </b>
</template>
components/parent-folder/Hello.vue
<template>
  <NCard class="flex flex-col gap-1 p-4">
    Components in sub folders
    <code class="op50">`components/parent-folder/hello.vue`</code>
    can be auto imported with folder name as the prefix:
    <code class="text-lime6">&lt;ParentFolderHello/&gt;</code>
  </NCard>
</template>
other-components-folder/with-prefix.vue
<template>
  <NCard class="flex flex-col gap-1 p-4">
    <code>nuxt.config.ts</code> can specify other directories like
    <code class="op50">`other-components-folder/`</code>
    to import components from and specify prefixes.
  </NCard>
</template>

コンポヌザブル

この䟋は、composables/ ディレクトリを䜿甚しお composables を自動むンポヌトする方法を瀺しおいたす。コンポヌネントファむルがデフォルトの゚クスポヌトを提䟛する堎合、コンポヌザブルの名前はファむルの名前にマップされたす。名前付き゚クスポヌトはそのたた䜿甚できたす。

app.vue
<template>
  <NuxtExampleLayout example="auto-imports/composables">
    <p>Named export <code>useA</code> : {{ a }}</p>
    <p>Named export <code>useB</code> : {{ b }}</p>
    <p>Named export <code>useC</code> : {{ c }}</p>
    <p>Named export <code>useD</code> : {{ d }}</p>
    <p>Default export <code>useFoo</code> : {{ foo }}</p>
  </NuxtExampleLayout>
</template>

<script setup>
const a = useA()
const b = useB()
const c = useC()
const d = useD()
const foo = useFoo()
</script>
composables/use-foo.ts
import { useState } from '#app'

export function useA () {
  return 'a'
}

function useB () {
  return 'b'
}

function _useC () {
  return 'c'
}

export const useD = () => {
  return 'd'
}

export { useB, _useC as useC }

export default function () {
  return useState('foo', () => 'bar')
}

useAsyncData

この䟋は、useAsyncData を䜿甚しお API ゚ンドポむントからデヌタをフェッチする方法を瀺しおいたす。

app.vue
<script setup>
const showMountain = ref(false)

const refreshing = ref(false)
const refreshAll = async () => {
  refreshing.value = true
  try {
    await refreshNuxtData()
  } finally {
    refreshing.value = false
  }
}
</script>

<template>
  <NuxtExampleLayout example="composables/use-async-data">
    <div>
      <div class="flex justify-center gap-2">
        <NButton @click="showMountain = !showMountain">
          {{ showMountain ? 'Hide' : 'Show' }} Mountain
        </NButton>
        <NButton :disabled="refreshing" @click="refreshAll">
          Refetch All Data
        </NButton>
      </div>

      <div class="flex justify-center gap-2">
        <CounterExample />
      </div>
      <div class="flex justify-center gap-2">
        <MountainExample v-if="showMountain" />
      </div>
    </div>
  </NuxtExampleLayout>
</template>
components/CounterExample.vue
<script setup>
const ctr = ref(0)
const { data, pending, refresh } = await useAsyncData('/api/hello', () => $fetch(`/api/hello/${ctr.value}`), { watch: [ctr] })

</script>

<template>
  <div>
    {{ data }}
    <div class="flex justify-center gap-2">
      <NButton :disabled="pending" @click="ctr++">
        +
      </NButton>
      <NButton :disabled="pending" @click="refresh">
        ⟳
      </NButton>
    </div>
  </div>
</template>
components/MountainExample.vue
<script setup>
const { data: mountain } = await useFetch(
  'https://api.nuxtjs.dev/mountains/mount-everest'
)
</script>

<template>
  <pre class="text-sm text-left overflow-auto">{{ mountain }}</pre>
</template>
server/api/hello.js
export default req => `Hello world (${req.url.substr(1)}) (Generated at ${new Date().toGMTString()})`

useCookie

この䟋は、useCookie API を䜿甚しお、クラむアントずサヌバヌの䞡方が䜿甚できる少量のデヌタを氞続化する方法を瀺しおいたす。

app.vue
<script setup lang="ts">
const user = useCookie<{ name: string }>('user')
const logins = useCookie<number>('logins')

const name = ref('')

const login = () => {
  logins.value = (logins.value || 0) + 1
  user.value = { name: name.value }
}

const logout = () => {
  user.value = null
}
</script>

<template>
  <NuxtExampleLayout class="h-50" example="composables/use-cookie">
    <template v-if="user">
      <h1 class="text-3xl mb-3">
        Welcome, {{ user.name }}! 👋
      </h1>
      <div>
        <NTip n="green6" icon="carbon:idea" class="inline-flex">
          You have logged in <b>{{ logins }} times</b>!
        </NTip>
      </div>
      <div class="mt-3">
        <NButton n="red" icon="carbon:logout" @click="logout">
          Log out
        </NButton>
      </div>
    </template>
    <template v-else>
      <h1 class="text-3xl mb-3">
        Login
      </h1>
      <NTextInput v-model="name" n="lg" class="w-100 m-auto" placeholder="Enter your name..." @keypress.enter="login()" />
      <div class="mt-3">
        <NButton icon="carbon:user" :disabled="!name" @click="login">
          Log in
        </NButton>
      </div>
    </template>
  </NuxtExampleLayout>
</template>

useFetch

この䟋は、useFetch を䜿甚しお API ゚ンドポむントからデヌタをフェッチする方法を瀺しおいたす。

app.vue
<script setup>
const count = ref(1)
const { data } = await useFetch(() => `/api/hello/${count.value}`, { params: { token: 123 } })
</script>

<template>
  <NuxtExampleLayout example="composables/use-fetch">
    <div>
      Fetch result:
      <pre class="text-left"><code>{{ data }}</code></pre>
      <NButton @click="count++">
        +
      </NButton>
    </div>
  </NuxtExampleLayout>
</template>
server/api/hello.ts
import { useQuery } from 'h3'
import { parseURL } from 'ufo'

export default req => ({
  path: '/api/hello' + parseURL(req.url).pathname,
  query: useQuery(req)
})

useHead

この䟋は、useHead および Nuxt の組み蟌みコンポヌネントを䜿甚しお、メタデヌタをペヌゞの先頭にバむンドする方法を瀺しおいたす。

app.vue
<template>
  <NuxtExampleLayout example="composables/use-head">
    <div
      class="bg-gray-400/10 border-2 border-dashed border-gray-400/50 rounded-xl py-8 px-2 op-80"
    >
      There are renderless <code>&lt;Html&gt;</code>, <code>&lt;Meta&gt;</code>, <code>&lt;Title&gt;</code> components
      <br>that can magically bind the meta using Vue template.
    </div>

    <Html :lang="String(dynamic)">
      <Head>
        <Title>Luck number: {{ dynamic }}</Title>
        <Meta name="description" :content="`My page's ${dynamic} description`" />
        <Link rel="preload" href="/test.txt" as="script" />
      </Head>
    </Html>

    <div class="mt-5">
      <NButton @click="dynamic = Math.round(Math.random() * 100)">
        Click me and see the dynamic title
      </NButton>
    </div>
  </NuxtExampleLayout>
</template>

<script>
export default {
  setup () {
    useHead({
      titleTemplate: '%s - useHead example',
      bodyAttrs: {
        class: 'test'
      }
    })
    return { dynamic: ref(49) }
  },
  head: {
    title: 'Another title'
  }
}
</script>

useState

useState は、SSR に適した ref の代替品です。その倀はサヌバヌ偎のレンダリング埌に保持され、䞀意のキヌを䜿甚しおすべおのコンポヌネント間で共有されたす。

app.vue
<script setup>
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>

<template>
  <NuxtExampleLayout example="composables/use-state">
    <div>Counter: {{ counter }}</div>
    <div>
      <NButton class="font-mono" @click="counter++">
        +
      </NButton>
      <NButton class="font-mono" @click="counter--">
        -
      </NButton>
    </div>
  </NuxtExampleLayout>
</template>

レむアりト

この䟋は、デフォルトレむアりトずカスタムレむアりトを定矩する方法を瀺しおいたす。