From 5d34747784368429fb58bcb9b436cd95d12dfb46 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 21:48:32 +0100 Subject: [PATCH 01/30] chore(deps): update dependency vite to v6.3.4 [security] (3.x) (#31958) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- packages/kit/package.json | 2 +- packages/nuxt/package.json | 2 +- packages/schema/package.json | 2 +- packages/ui-templates/package.json | 2 +- pnpm-lock.yaml | 218 ++++++++++++++++------------- 6 files changed, 129 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index 1b7fca52bf57..f3773e723bb3 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "typescript": "5.8.3", "ufo": "1.6.1", "unimport": "5.0.0", - "vite": "6.3.3", + "vite": "6.3.4", "vue": "3.5.13", "webpack": "5.99.5" }, diff --git a/packages/kit/package.json b/packages/kit/package.json index b7de8fd88b94..e9bd4c20d245 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -59,7 +59,7 @@ "lodash-es": "4.17.21", "nitropack": "2.11.11", "unbuild": "3.5.0", - "vite": "6.3.3", + "vite": "6.3.4", "vitest": "3.1.2", "webpack": "5.99.5" }, diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 944e9ab2fbc7..f8adc347aa91 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -144,7 +144,7 @@ "@vitejs/plugin-vue-jsx": "4.1.2", "@vue/compiler-sfc": "3.5.13", "unbuild": "3.5.0", - "vite": "6.3.3", + "vite": "6.3.4", "vitest": "3.1.2", "vue-sfc-transformer": "0.1.14" }, diff --git a/packages/schema/package.json b/packages/schema/package.json index 6226a4c76559..b24842cd8ab2 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -67,7 +67,7 @@ "unctx": "2.4.1", "unimport": "5.0.0", "untyped": "2.0.0", - "vite": "6.3.3", + "vite": "6.3.4", "vue": "3.5.13", "vue-bundle-renderer": "2.1.1", "vue-loader": "17.4.2", diff --git a/packages/ui-templates/package.json b/packages/ui-templates/package.json index ec785d0c73c3..4f1ce06007e8 100644 --- a/packages/ui-templates/package.json +++ b/packages/ui-templates/package.json @@ -33,6 +33,6 @@ "tinyexec": "1.0.1", "tinyglobby": "0.2.13", "unocss": "66.0.0", - "vite": "6.3.3" + "vite": "6.3.4" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df30eb786dbd..53f68e6416ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,7 +28,7 @@ overrides: typescript: 5.8.3 ufo: 1.6.1 unimport: 5.0.0 - vite: 6.3.3 + vite: 6.3.4 vue: 3.5.13 webpack: 5.99.5 @@ -47,7 +47,7 @@ importers: version: 7.26.5 '@codspeed/vitest-plugin': specifier: 4.0.1 - version: 4.0.1(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + version: 4.0.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) '@nuxt/cli': specifier: 3.25.0 version: 3.25.0(magicast@0.3.5) @@ -331,8 +331,8 @@ importers: specifier: 3.5.0 version: 3.5.0(typescript@5.8.3)(vue-sfc-transformer@0.1.14(@vue/compiler-core@3.5.13)(esbuild@0.25.3)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + specifier: 6.3.4 + version: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vitest: specifier: 3.1.2 version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) @@ -350,7 +350,7 @@ importers: version: 2.0.2 '@nuxt/devtools': specifier: ^2.4.0 - version: 2.4.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 2.4.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@nuxt/kit': specifier: workspace:* version: link:../kit @@ -543,10 +543,10 @@ importers: version: 1.0.7 '@vitejs/plugin-vue': specifier: 5.2.3 - version: 5.2.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue-jsx': specifier: 4.1.2 - version: 4.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 4.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vue/compiler-sfc': specifier: 3.5.13 version: 3.5.13 @@ -554,8 +554,8 @@ importers: specifier: 3.5.0 version: 3.5.0(typescript@5.8.3)(vue-sfc-transformer@0.1.14(@vue/compiler-core@3.5.13)(esbuild@0.25.3)(vue@3.5.13(typescript@5.8.3)))(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3)) vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + specifier: 6.3.4 + version: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vitest: specifier: 3.1.2 version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) @@ -734,10 +734,10 @@ importers: version: 2.0.8(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue': specifier: 5.2.3 - version: 5.2.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue-jsx': specifier: 4.1.2 - version: 4.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 4.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vue/compiler-core': specifier: 3.5.13 version: 3.5.13 @@ -814,8 +814,8 @@ importers: specifier: 2.0.0 version: 2.0.0 vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + specifier: 6.3.4 + version: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vue: specifier: 3.5.13 version: 3.5.13(typescript@5.8.3) @@ -884,10 +884,10 @@ importers: version: 0.2.13 unocss: specifier: 66.0.0 - version: 66.0.0(postcss@8.5.3)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 66.0.0(postcss@8.5.3)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + specifier: 6.3.4 + version: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) packages/vite: dependencies: @@ -899,10 +899,10 @@ importers: version: 6.0.2(rollup@4.40.1) '@vitejs/plugin-vue': specifier: ^5.2.3 - version: 5.2.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue-jsx': specifier: ^4.1.2 - version: 4.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + version: 4.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.3) @@ -979,14 +979,14 @@ importers: specifier: ^2.3.2 version: 2.3.2 vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + specifier: 6.3.4 + version: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vite-node: specifier: ^3.1.2 version: 3.1.2(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vite-plugin-checker: specifier: ^0.9.1 - version: 0.9.1(eslint@9.25.1(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.10(typescript@5.8.3)) + version: 0.9.1(eslint@9.25.1(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.10(typescript@5.8.3)) vue-bundle-renderer: specifier: ^2.1.1 version: 2.1.1 @@ -1338,10 +1338,18 @@ packages: resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -1355,6 +1363,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.1': + resolution: {integrity: sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-syntax-jsx@7.25.9': resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} @@ -1393,6 +1406,10 @@ packages: resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -1416,7 +1433,7 @@ packages: '@codspeed/vitest-plugin@4.0.1': resolution: {integrity: sha512-aqmrPJzX9cD50UWDsOyih5L5WcEYlNQg3u84sJJ9ZuuLApA51w+LGxk6Xbyb8LJF9n/CwM94HKHV/qArfnvDoQ==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vitest: '>=1.2.2' '@colors/colors@1.5.0': @@ -2003,7 +2020,7 @@ packages: '@nuxt/devtools-kit@2.4.0': resolution: {integrity: sha512-GdxdxEDN1f6uxJOPooYQTLC6X1QUe5kRs83A0PVH/uD0sqoXCjpKHOw+H0vdhkHOwOIsVIsbL+TdaF4k++p9TA==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 '@nuxt/devtools-wizard@2.4.0': resolution: {integrity: sha512-3/5S2zpl79rE1b/lh8M/2lDNsYiYIXXHZmCwsYPuFJA6DilLQo/VY44oq6cY0Q1up32HYB3h1Te/q3ELbsb+ag==} @@ -2013,7 +2030,7 @@ packages: resolution: {integrity: sha512-iXjLoLeWfMa2qWWKRG3z6DKlKVLmbIa3zl7Y8X83BF83m7RW1xVXu6S4tVlLaTi+5tzeKIFlXHo+RO/tJVA72A==} hasBin: true peerDependencies: - vite: 6.3.3 + vite: 6.3.4 '@nuxt/eslint-config@1.3.0': resolution: {integrity: sha512-m0ebtmjyAiPVctBn+YijVst3WA2tQ6s/YJT4Dr33bTiSVvl+sFapxvAV+YOTyS4WECCBtjTAct61gamjbiahPg==} @@ -2868,7 +2885,7 @@ packages: '@unocss/astro@66.0.0': resolution: {integrity: sha512-GBhXT6JPqXjDXoJZTXhySk83NgOt0UigChqrUUdG4x7Z+DVYkDBION8vZUJjw0OdIaxNQ4euGWu4GDsMF6gQQg==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 peerDependenciesMeta: vite: optional: true @@ -2946,7 +2963,7 @@ packages: '@unocss/vite@66.0.0': resolution: {integrity: sha512-IVcPX8xL+2edyXKt4tp9yu5A6gcbPVCsspfcL0XgziCr01kS+4qSoZ90F3IUs3hXc/AyO5eCpRtGFMPLpOjXQg==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 '@unrs/resolver-binding-darwin-arm64@1.7.2': resolution: {integrity: sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg==} @@ -3047,14 +3064,14 @@ packages: resolution: {integrity: sha512-4Rk0GdE0QCdsIkuMmWeg11gmM4x8UmTnZR/LWPm7QJ7+BsK4tq08udrN0isrrWqz5heFy9HLV/7bOLgFS8hUjA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vue: 3.5.13 '@vitejs/plugin-vue@5.2.3': resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vue: 3.5.13 '@vitest/coverage-v8@3.1.2': @@ -3073,7 +3090,7 @@ packages: resolution: {integrity: sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==} peerDependencies: msw: ^2.4.9 - vite: 6.3.3 + vite: 6.3.4 peerDependenciesMeta: msw: optional: true @@ -6231,14 +6248,14 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - oniguruma-parser@0.12.0: - resolution: {integrity: sha512-fD9o5ebCmEAA9dLysajdQvuKzLL7cj+w7DQjuO3Cb6IwafENfx6iL+RGkmyW82pVRsvgzixsWinHvgxTMJvdIA==} + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} oniguruma-to-es@2.3.0: resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} - oniguruma-to-es@4.3.1: - resolution: {integrity: sha512-VtX1kepWO+7HG7IWV5v72JhiqofK7XsiHmtgnvurnNOTdIvE5mrdWYtsOrQyrXCv1L2Ckm08hywp+MFO7rC4Ug==} + oniguruma-to-es@4.3.2: + resolution: {integrity: sha512-Hxxc18dGbVYzcTp2W64YwxQLYabiYM+dOX5Dtycy3qLvuYE4HIQjwfgEeAtPS6chFJs8UdINTQ83/Rlh+1Qwsg==} open@10.1.1: resolution: {integrity: sha512-zy1wx4+P3PfhXSEPJNtZmJXfhkkIaxU1VauWIrDZw1O7uJRDRJtKr9n3Ic4NgbA16KyOxOXO2ng9gYwCdXuSXA==} @@ -7763,7 +7780,7 @@ packages: engines: {node: '>=14'} peerDependencies: '@unocss/webpack': 66.0.0 - vite: 6.3.3 + vite: 6.3.4 peerDependenciesMeta: '@unocss/webpack': optional: true @@ -7933,12 +7950,12 @@ packages: vite-dev-rpc@1.0.7: resolution: {integrity: sha512-FxSTEofDbUi2XXujCA+hdzCDkXFG1PXktMjSk1efq9Qb5lOYaaM9zNSvKvPPF7645Bak79kSp1PTooMW2wktcA==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vite-hot-client@2.0.4: resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vite-node@3.1.2: resolution: {integrity: sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==} @@ -7955,7 +7972,7 @@ packages: optionator: ^0.9.4 stylelint: '>=16' typescript: 5.8.3 - vite: 6.3.3 + vite: 6.3.4 vls: '*' vti: '*' vue-tsc: ~2.2.2 @@ -7984,7 +8001,7 @@ packages: engines: {node: '>=14'} peerDependencies: '@nuxt/kit': '*' - vite: 6.3.3 + vite: 6.3.4 peerDependenciesMeta: '@nuxt/kit': optional: true @@ -7992,11 +8009,11 @@ packages: vite-plugin-vue-tracer@0.1.3: resolution: {integrity: sha512-+fN6oo0//dwZP9Ax9gRKeUroCqpQ43P57qlWgL0ljCIxAs+Rpqn/L4anIPZPgjDPga5dZH+ZJsshbF0PNJbm3Q==} peerDependencies: - vite: 6.3.3 + vite: 6.3.4 vue: 3.5.13 - vite@6.3.3: - resolution: {integrity: sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==} + vite@6.3.4: + resolution: {integrity: sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -8531,8 +8548,12 @@ snapshots: '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helpers@7.27.0': @@ -8544,6 +8565,10 @@ snapshots: dependencies: '@babel/types': 7.27.0 + '@babel/parser@7.27.1': + dependencies: + '@babel/types': 7.27.1 + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -8597,6 +8622,11 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@1.0.2': {} '@braidai/lang@1.1.1': {} @@ -8625,10 +8655,10 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@4.0.1(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': + '@codspeed/vitest-plugin@4.0.1(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': dependencies: '@codspeed/core': 4.0.1 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) transitivePeerDependencies: - debug @@ -9198,12 +9228,12 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.4.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': + '@nuxt/devtools-kit@2.4.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': dependencies: '@nuxt/kit': link:packages/kit '@nuxt/schema': link:packages/schema execa: 8.0.1 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) '@nuxt/devtools-wizard@2.4.0': dependencies: @@ -9216,12 +9246,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.1 - '@nuxt/devtools@2.4.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@nuxt/devtools@2.4.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: - '@nuxt/devtools-kit': 2.4.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + '@nuxt/devtools-kit': 2.4.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) '@nuxt/devtools-wizard': 2.4.0 '@nuxt/kit': link:packages/kit - '@vue/devtools-core': 7.7.5(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + '@vue/devtools-core': 7.7.5(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@vue/devtools-kit': 7.7.5 birpc: 2.3.0 consola: 3.4.2 @@ -9246,9 +9276,9 @@ snapshots: sirv: 3.0.1 structured-clone-es: 1.0.0 tinyglobby: 0.2.13 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) - vite-plugin-inspect: 11.0.1(@nuxt/kit@packages+kit)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) - vite-plugin-vue-tracer: 0.1.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite-plugin-inspect: 11.0.1(@nuxt/kit@packages+kit)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + vite-plugin-vue-tracer: 0.1.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) which: 5.0.0 ws: 8.18.1 transitivePeerDependencies: @@ -9384,7 +9414,7 @@ snapshots: tinyexec: 0.3.2 ufo: 1.6.1 unplugin: 2.3.2 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vitest-environment-nuxt: 1.0.1(@playwright/test@1.52.0)(@testing-library/vue@8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)))(@types/node@22.15.3)(@vue/test-utils@2.4.6)(happy-dom@17.4.4)(jiti@2.4.2)(magicast@0.3.5)(playwright-core@1.52.0)(terser@5.39.0)(typescript@5.8.3)(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1) vue: 3.5.13(typescript@5.8.3) optionalDependencies: @@ -9859,7 +9889,7 @@ snapshots: dependencies: '@shikijs/types': 3.3.0 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.1 + oniguruma-to-es: 4.3.2 '@shikijs/engine-oniguruma@1.29.2': dependencies: @@ -10232,13 +10262,13 @@ snapshots: unhead: 2.0.8 vue: 3.5.13(typescript@5.8.3) - '@unocss/astro@66.0.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@unocss/astro@66.0.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: '@unocss/core': 66.0.0 '@unocss/reset': 66.0.0 - '@unocss/vite': 66.0.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 66.0.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) transitivePeerDependencies: - vue @@ -10363,7 +10393,7 @@ snapshots: dependencies: '@unocss/core': 66.0.0 - '@unocss/vite@66.0.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@unocss/vite@66.0.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: '@ampproject/remapping': 2.3.0 '@unocss/config': 66.0.0 @@ -10373,7 +10403,7 @@ snapshots: magic-string: 0.30.17 tinyglobby: 0.2.13 unplugin-utils: 0.2.4 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) transitivePeerDependencies: - vue @@ -10468,19 +10498,19 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue-jsx@4.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10) '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.26.10) - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vue: 3.5.13(typescript@5.8.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vue: 3.5.13(typescript@5.8.3) '@vitest/coverage-v8@3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': @@ -10508,13 +10538,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': + '@vitest/mocker@3.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))': dependencies: '@vitest/spy': 3.1.2 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) '@vitest/pretty-format@3.1.2': dependencies: @@ -10644,14 +10674,14 @@ snapshots: dependencies: '@vue/devtools-kit': 7.7.6 - '@vue/devtools-core@7.7.5(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': + '@vue/devtools-core@7.7.5(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3))': dependencies: '@vue/devtools-kit': 7.7.5 '@vue/devtools-shared': 7.7.5 mitt: 3.0.1 nanoid: 5.1.5 pathe: 2.0.3 - vite-hot-client: 2.0.4(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + vite-hot-client: 2.0.4(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) vue: 3.5.13(typescript@5.8.3) transitivePeerDependencies: - vite @@ -11048,7 +11078,7 @@ snapshots: babel-walk@3.0.0-canary-5: dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.27.1 bail@2.0.2: {} @@ -11391,8 +11421,8 @@ snapshots: constantinople@4.0.1: dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/parser': 7.27.1 + '@babel/types': 7.27.1 convert-gitmoji@0.1.5: {} @@ -14286,7 +14316,7 @@ snapshots: dependencies: mimic-fn: 4.0.0 - oniguruma-parser@0.12.0: {} + oniguruma-parser@0.12.1: {} oniguruma-to-es@2.3.0: dependencies: @@ -14294,9 +14324,9 @@ snapshots: regex: 5.1.1 regex-recursion: 5.1.1 - oniguruma-to-es@4.3.1: + oniguruma-to-es@4.3.2: dependencies: - oniguruma-parser: 0.12.0 + oniguruma-parser: 0.12.1 regex: 6.0.1 regex-recursion: 6.0.2 @@ -15983,9 +16013,9 @@ snapshots: dependencies: normalize-path: 2.1.1 - unocss@66.0.0(postcss@8.5.3)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): + unocss@66.0.0(postcss@8.5.3)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): dependencies: - '@unocss/astro': 66.0.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + '@unocss/astro': 66.0.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) '@unocss/cli': 66.0.0 '@unocss/core': 66.0.0 '@unocss/postcss': 66.0.0(postcss@8.5.3) @@ -16002,9 +16032,9 @@ snapshots: '@unocss/transformer-compile-class': 66.0.0 '@unocss/transformer-directives': 66.0.0 '@unocss/transformer-variant-group': 66.0.0 - '@unocss/vite': 66.0.0(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 66.0.0(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) transitivePeerDependencies: - postcss - supports-color @@ -16167,15 +16197,15 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.0.7(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): + vite-dev-rpc@1.0.7(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): dependencies: birpc: 2.3.0 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) - vite-hot-client: 2.0.4(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite-hot-client: 2.0.4(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) - vite-hot-client@2.0.4(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): + vite-hot-client@2.0.4(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): dependencies: - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vite-node@3.1.2(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1): dependencies: @@ -16183,7 +16213,7 @@ snapshots: debug: 4.4.0 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) transitivePeerDependencies: - '@types/node' - jiti @@ -16198,7 +16228,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.9.1(eslint@9.25.1(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.10(typescript@5.8.3)): + vite-plugin-checker@0.9.1(eslint@9.25.1(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.10(typescript@5.8.3)): dependencies: '@babel/code-frame': 7.26.2 chokidar: 4.0.3 @@ -16208,7 +16238,7 @@ snapshots: strip-ansi: 7.1.0 tiny-invariant: 1.3.3 tinyglobby: 0.2.13 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.25.1(jiti@2.4.2) @@ -16216,7 +16246,7 @@ snapshots: typescript: 5.8.3 vue-tsc: 2.2.10(typescript@5.8.3) - vite-plugin-inspect@11.0.1(@nuxt/kit@packages+kit)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): + vite-plugin-inspect@11.0.1(@nuxt/kit@packages+kit)(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)): dependencies: ansis: 3.17.0 debug: 4.4.0 @@ -16226,24 +16256,24 @@ snapshots: perfect-debounce: 1.0.0 sirv: 3.0.1 unplugin-utils: 0.2.4 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) - vite-dev-rpc: 1.0.7(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite-dev-rpc: 1.0.7(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) optionalDependencies: '@nuxt/kit': link:packages/kit transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@0.1.3(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): + vite-plugin-vue-tracer@0.1.3(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue@3.5.13(typescript@5.8.3)): dependencies: estree-walker: 3.0.3 exsolve: 1.0.5 magic-string: 0.30.17 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vue: 3.5.13(typescript@5.8.3) - vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1): + vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1): dependencies: esbuild: 0.25.3 fdir: 6.4.4(picomatch@4.0.2) @@ -16289,7 +16319,7 @@ snapshots: vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.3)(happy-dom@17.4.4)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1): dependencies: '@vitest/expect': 3.1.2 - '@vitest/mocker': 3.1.2(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) + '@vitest/mocker': 3.1.2(vite@6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1)) '@vitest/pretty-format': 3.1.2 '@vitest/runner': 3.1.2 '@vitest/snapshot': 3.1.2 @@ -16306,7 +16336,7 @@ snapshots: tinyglobby: 0.2.13 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.3.3(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) + vite: 6.3.4(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) vite-node: 3.1.2(@types/node@22.15.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1) why-is-node-running: 2.3.0 optionalDependencies: @@ -16571,8 +16601,8 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/parser': 7.27.1 + '@babel/types': 7.27.1 assert-never: 1.4.0 babel-walk: 3.0.0-canary-5 From 3c59b5e623e3295cc002bae25bc7087d5722a6b6 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 29 Apr 2025 11:22:22 +0100 Subject: [PATCH 02/30] fix(nuxt): ensure asyncData is initialised before effects run (#31946) --- .../nuxt/src/app/composables/asyncData.ts | 14 ++++++++----- packages/nuxt/src/app/composables/fetch.ts | 2 +- test/nuxt/composables.test.ts | 21 +++++++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 3f065fcf6483..10f08e064457 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -362,11 +362,15 @@ export function useAsyncData< // setup watchers/instance const hasScope = getCurrentScope() - const unsub = watch([key, ...options.watch || []], ([newKey], [oldKey]) => { - if (oldKey === newKey) { + if (options.watch) { + const unsubExecute = watch(options.watch, () => { asyncData._execute({ cause: 'watch', dedupe: options.dedupe }) - return + }, { flush: 'post' }) + if (hasScope) { + onScopeDispose(() => unsubExecute()) } + } + const unsubKey = watch(key, (newKey, oldKey) => { if (oldKey) { unregister(oldKey) } @@ -377,11 +381,11 @@ export function useAsyncData< if (options.immediate) { nuxtApp._asyncData[newKey]!.execute({ cause: 'initial', dedupe: options.dedupe }) } - }) + }, { flush: 'sync' }) if (hasScope) { onScopeDispose(() => { - unsub() + unsubKey() unregister(key.value) }) } diff --git a/packages/nuxt/src/app/composables/fetch.ts b/packages/nuxt/src/app/composables/fetch.ts index 8c93640d1d18..615119040561 100644 --- a/packages/nuxt/src/app/composables/fetch.ts +++ b/packages/nuxt/src/app/composables/fetch.ts @@ -148,7 +148,7 @@ export function useFetch< if (watchSources !== false && !immediate) { watch([...(watchSources || []), _fetchOptions], () => { _asyncDataOptions.immediate = true - }, { flush: 'pre', once: true }) + }, { flush: 'sync', once: true }) } let controller: AbortController diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts index 8da356656b15..5ea774034624 100644 --- a/test/nuxt/composables.test.ts +++ b/test/nuxt/composables.test.ts @@ -691,6 +691,27 @@ describe('useFetch', () => { expect(data.value).toEqual({ url: '/api/immediate-false' }) }) + it('should be accessible immediately', async () => { + registerEndpoint('/api/watchable-fetch', defineEventHandler(() => ({ url: '/api/watchable-fetch' }))) + + const searchTerm = ref('') + + const { data } = await useFetch('/api/watchable-fetch', { + params: { q: searchTerm }, + }) + + for (const value of [undefined, 'pre', 'post', 'sync'] as const) { + watchEffect(() => { + expect(() => data.value).not.toThrow() + }, { flush: value }) + } + + searchTerm.value = 'new' + + await nextTick() + await flushPromises() + }) + it('should timeout', async () => { const { status, error } = await useFetch( // @ts-expect-error should resolve to a string From 331833736438ff0d8cf3d558145748d07c2f61fc Mon Sep 17 00:00:00 2001 From: James Date: Wed, 30 Apr 2025 15:14:29 +0200 Subject: [PATCH 03/30] docs: add missing article (#31952) --- docs/2.guide/1.concepts/1.auto-imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.guide/1.concepts/1.auto-imports.md b/docs/2.guide/1.concepts/1.auto-imports.md index 91a03145c5e7..9e66b3e9487e 100644 --- a/docs/2.guide/1.concepts/1.auto-imports.md +++ b/docs/2.guide/1.concepts/1.auto-imports.md @@ -54,7 +54,7 @@ const double = computed(() => count.value * 2) When you are using the built-in Composition API composables provided by Vue and Nuxt, be aware that many of them rely on being called in the right _context_. -During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of `nuxtApp`) via a global variable, and then unsets it in same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components. +During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of `nuxtApp`) via a global variable, and then unsets it in the same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components. That means that (with very few exceptions) you cannot use them outside a Nuxt plugin, Nuxt route middleware or Vue setup function. On top of that, you must use them synchronously - that is, you cannot use `await` before calling a composable, except within ` + + diff --git a/test/fixtures/basic/pages/route-scroll-behavior/scroll-to-top/[id].vue b/test/fixtures/basic/pages/route-scroll-behavior/scroll-to-top/[id].vue new file mode 100644 index 000000000000..fce505249660 --- /dev/null +++ b/test/fixtures/basic/pages/route-scroll-behavior/scroll-to-top/[id].vue @@ -0,0 +1,15 @@ + + + diff --git a/test/nuxt/loading-indicator.test.ts b/test/nuxt/loading-indicator.test.ts index b8db1d014eaa..8bdaebaa026f 100644 --- a/test/nuxt/loading-indicator.test.ts +++ b/test/nuxt/loading-indicator.test.ts @@ -101,9 +101,6 @@ describe('page loading indicator', () => { expect(getLoadingIndicator().attributes().style).toContain('opacity: 1;') onLoad?.() - // ensure loading hasn't already finished - await nextTick(() => new Promise(r => setTimeout(r, 0))) - if (isLoading.value) { resolve!() await new Promise(resolve => nuxtApp.hooks.hookOnce('page:loading:end', () => { resolve() })) From a38f465846ee92a47f00e56875a17288b0f0ce75 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 1 May 2025 17:01:12 +0100 Subject: [PATCH 12/30] fix(nuxt): load live data from `vfs` even if a file exists in `buildDir` (#31969) --- packages/nuxt/src/core/plugins/virtual.ts | 36 +++++++++++++---------- packages/vite/src/vite.ts | 2 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/nuxt/src/core/plugins/virtual.ts b/packages/nuxt/src/core/plugins/virtual.ts index 2a3f00a3bd27..13ff58bac36d 100644 --- a/packages/nuxt/src/core/plugins/virtual.ts +++ b/packages/nuxt/src/core/plugins/virtual.ts @@ -28,26 +28,30 @@ export const VirtualFSPlugin = (nuxt: Nuxt, options: VirtualFSPluginOptions) => return { name: 'nuxt:virtual', - resolveId (id, importer) { - id = resolveAlias(id, alias) - if (process.platform === 'win32' && isAbsolute(id)) { - // Add back C: prefix on Windows - id = resolve(id) - } + resolveId: { + order: 'pre', + handler (id, importer) { + id = resolveAlias(id, alias) - const resolvedId = resolveWithExt(id) - if (resolvedId) { - return PREFIX + encodeURIComponent(resolvedId) - } + if (process.platform === 'win32' && isAbsolute(id)) { + // Add back C: prefix on Windows + id = resolve(id) + } - if (importer && RELATIVE_ID_RE.test(id)) { - const path = resolve(dirname(withoutPrefix(decodeURIComponent(importer))), id) - const resolved = resolveWithExt(path) - if (resolved) { - return PREFIX + encodeURIComponent(resolved) + const resolvedId = resolveWithExt(id) + if (resolvedId) { + return PREFIX + encodeURIComponent(resolvedId) } - } + + if (importer && RELATIVE_ID_RE.test(id)) { + const path = resolve(dirname(withoutPrefix(decodeURIComponent(importer))), id) + const resolved = resolveWithExt(path) + if (resolved) { + return PREFIX + encodeURIComponent(resolved) + } + } + }, }, loadInclude (id) { diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index 4beaa8061912..2b1f937c4830 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -192,7 +192,7 @@ export const bundle: NuxtBuilder['bundle'] = async (nuxt) => { const clientCSSMap = {} nuxt.hook('vite:extendConfig', (config, { isServer }) => { - config.plugins!.push(ssrStylesPlugin({ + config.plugins!.unshift(ssrStylesPlugin({ srcDir: ctx.nuxt.options.srcDir, clientCSSMap, chunksWithInlinedCSS, From e03d44b47c40772120c519d09daa9d7202d34481 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 1 May 2025 17:36:20 +0100 Subject: [PATCH 13/30] test: update bundle size snapshot --- test/bundle.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 76285246d348..f0c1b9282306 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -37,7 +37,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM const serverDir = join(rootDir, '.output/server') const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"193k"`) + expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"194k"`) const modules = await analyzeSizes(['node_modules/**/*'], serverDir) expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1385k"`) From 4bcfe0278bd76c1cd54a843d7d8cb1762505f864 Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Fri, 2 May 2025 15:38:25 +0800 Subject: [PATCH 14/30] perf(nuxt): tree-shake router's `handleHotUpdate` in production (#31971) --- packages/nuxt/src/pages/runtime/plugins/router.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index af9b841aff25..b3e32aa09104 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -87,7 +87,9 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ routes, }) - handleHotUpdate(router, routerOptions.routes ? routerOptions.routes : routes => routes) + if (import.meta.hot) { + handleHotUpdate(router, routerOptions.routes ? routerOptions.routes : routes => routes) + } if (import.meta.client && 'scrollRestoration' in window.history) { window.history.scrollRestoration = 'auto' From dfd2663ea88013a295b3ef87a77312c900f449e4 Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Fri, 2 May 2025 16:06:59 +0800 Subject: [PATCH 15/30] docs: improve `@nuxt/kit` documentation (#31793) --- docs/3.api/5.kit/1.modules.md | 192 +++++----- docs/3.api/5.kit/10.runtime-config.md | 2 + docs/3.api/5.kit/10.templates.md | 342 +++++++++--------- docs/3.api/5.kit/11.nitro.md | 364 ++++++++++--------- docs/3.api/5.kit/12.resolving.md | 212 +++++------ docs/3.api/5.kit/13.logging.md | 48 +-- docs/3.api/5.kit/14.builder.md | 490 ++++++-------------------- docs/3.api/5.kit/2.programmatic.md | 75 +--- docs/3.api/5.kit/3.compatibility.md | 215 +++++------ docs/3.api/5.kit/4.autoimports.md | 6 +- docs/3.api/5.kit/5.components.md | 25 +- docs/3.api/5.kit/6.context.md | 108 +++--- docs/3.api/5.kit/7.pages.md | 290 +++++---------- docs/3.api/5.kit/8.layout.md | 117 +++--- docs/3.api/5.kit/9.plugins.md | 279 +++++++-------- 15 files changed, 1170 insertions(+), 1595 deletions(-) diff --git a/docs/3.api/5.kit/1.modules.md b/docs/3.api/5.kit/1.modules.md index 8845c92fa8a2..7b9cb9c1a659 100644 --- a/docs/3.api/5.kit/1.modules.md +++ b/docs/3.api/5.kit/1.modules.md @@ -14,87 +14,52 @@ Modules are the building blocks of Nuxt. Kit provides a set of utilities to help 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. -### Type +### Usage -```ts -function defineNuxtModule (definition: ModuleDefinition | NuxtModule): NuxtModule - -type ModuleOptions = Record - -interface ModuleDefinition { - meta?: ModuleMeta - defaults?: T | ((nuxt: Nuxt) => T) - schema?: T - hooks?: Partial - setup?: (this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable -} - -interface NuxtModule { - (this: void, inlineOptions: T, nuxt: Nuxt): Awaitable - getOptions?: (inlineOptions?: T, nuxt?: Nuxt) => Promise - getMeta?: () => Promise -} - -interface ModuleSetupReturn { - timings?: { - setup?: number - [key: string]: number | undefined +```ts twoslash +import { defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'my-module', + configKey: 'myModule' + }, + defaults: { + enabled: true + }, + setup (options) { + if (options.enabled) { + console.log('My Nuxt module is enabled!') + } } -} - -interface ModuleMeta { - name?: string - version?: string - configKey?: string - compatibility?: NuxtCompatibility - [key: string]: unknown -} +}) ``` -### Parameters - -#### `definition` - -**Type**: `ModuleDefinition | NuxtModule` - -**Required**: `true` - -A module definition object or a module function. - -- `meta` (optional) - - **Type**: `ModuleMeta` - - Metadata of the module. It defines the module name, version, config key and compatibility. - -- `defaults` (optional) - - **Type**: `T | ((nuxt: Nuxt) => T)` - - Default options for the module. If a function is provided, it will be called with the Nuxt instance as the first argument. - -- `schema` (optional) - - **Type**: `T` - - Schema for the module options. If provided, options will be applied to the schema. +### Type -- `hooks` (optional) +```ts twoslash +function defineNuxtModule (definition: ModuleDefinition | NuxtModule): NuxtModule +``` - **Type**: `Partial` +### Parameters - Hooks to be installed for the module. If provided, the module will install the hooks. +**definition**: A module definition object or a module function. The module definition object should contain the following properties: -- `setup` (optional) +| Property | Type | Required | Description | +| ------------------ | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `meta` | `ModuleMeta` | `false` | Metadata of the module. It defines the module name, version, config key and compatibility. | +| `defaults` | `T \| ((nuxt: Nuxt) => T)`{lang="ts"} | `false` | Default options for the module. If a function is provided, it will be called with the Nuxt instance as the first argument. | +| `schema` | `T` | `false` | Schema for the module options. If provided, options will be applied to the schema. | +| `hooks` | `Partial`{lang="ts"} | `false` | Hooks to be installed for the module. If provided, the module will install the hooks. | +| `setup` | `(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable`{lang="ts"} | `false` | Setup function for the module. If provided, the module will call the setup function. | - **Type**: `(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable` +### Examples - Setup function for the module. If provided, the module will call the setup function. +#### Using `configKey` to Make Your Module Configurable -### Examples +When defining a Nuxt module, you can set a `configKey` to specify how users should configure the module in their `nuxt.config`. ```ts -// https://github.com/nuxt/starter/tree/module import { defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ @@ -103,51 +68,94 @@ export default defineNuxtModule({ configKey: 'myModule' }, defaults: { - test: 123 + // Module options + enabled: true }, - setup (options, nuxt) { - nuxt.hook('modules:done', () => { - console.log('My module is ready with current test option: ', options.test) - }) + setup (options) { + if (options.enabled) { + console.log('My Nuxt module is enabled!') + } } }) ``` -## `installModule` - -Install specified Nuxt module programmatically. This is helpful when your module depends on other modules. You can pass the module options as an object to `inlineOptions` and they will be passed to the module's `setup` function. - -### Type +Users can provide options for this module under the corresponding key in `nuxt.config`. ```ts -async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt) +export default defineNuxtConfig({ + myModule: { + enabled: false + } +}) ``` -### Parameters +#### Defining Module Compatibility Requirements + +If you're developing a Nuxt module and using APIs that are only supported in specific Nuxt versions, it's highly recommended to include `compatibility.nuxt`. -#### `moduleToInstall` +```ts +export default defineNuxtModule({ + meta: { + name: '@nuxt/icon', + configKey: 'icon', + compatibility: { + // Required nuxt version in semver format. + nuxt: '>=3.0.0', // or use '^3.0.0' + }, + }, + async setup() { + const resolver = createResolver(import.meta.url) + // Implement + }, +}) +``` -**Type**: `string` | `NuxtModule` +If the user tries to use your module with an incompatible Nuxt version, they will receive a warning in the console. -**Required**: `true` +```terminal + WARN Module @nuxt/icon is disabled due to incompatibility issues: + - [nuxt] Nuxt version ^3.1.0 is required but currently using 3.0.0 +``` -The module to install. Can be either a string with the module name or a module object itself. +## `installModule` -#### `inlineOptions` +Install specified Nuxt module programmatically. This is helpful when your module depends on other modules. You can pass the module options as an object to `inlineOptions` and they will be passed to the module's `setup` function. -**Type**: `any` +### Usage -**Default**: `{}` +```ts twoslash +import { defineNuxtModule, installModule } from '@nuxt/kit' -An object with the module options to be passed to the module's `setup` function. +export default defineNuxtModule({ + async setup () { + // will install @nuxtjs/fontaine with Roboto font and Impact fallback + await installModule('@nuxtjs/fontaine', { + // module configuration + fonts: [ + { + family: 'Roboto', + fallbacks: ['Impact'], + fallbackName: 'fallback-a', + } + ] + }) + } +}) +``` -#### `nuxt` +### Type -**Type**: `Nuxt` +```ts +async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt) +``` -**Default**: `useNuxt()` +### Parameters -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +| Property | Type | Required | Description | +| ------------------ | -------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `moduleToInstall` | `string \| NuxtModule`{lang="ts"} | `true` | The module to install. Can be either a string with the module name or a module object itself. | +| `inlineOptions` | `any` | `false` | An object with the module options to be passed to the module's `setup` function. | +| `nuxt` | `Nuxt` | `false` | Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. | ### Examples diff --git a/docs/3.api/5.kit/10.runtime-config.md b/docs/3.api/5.kit/10.runtime-config.md index 49f53487036e..f548f4ed7ff5 100644 --- a/docs/3.api/5.kit/10.runtime-config.md +++ b/docs/3.api/5.kit/10.runtime-config.md @@ -22,6 +22,8 @@ function useRuntimeConfig (): Record It is also possible to update runtime configuration. This will be merged with the existing runtime configuration, and if Nitro has already been initialized it will trigger an HMR event to reload the Nitro runtime config. +### Type + ```ts function updateRuntimeConfig (config: Record): void | Promise ``` diff --git a/docs/3.api/5.kit/10.templates.md b/docs/3.api/5.kit/10.templates.md index 223df41744ae..9f15a6eaf1c4 100644 --- a/docs/3.api/5.kit/10.templates.md +++ b/docs/3.api/5.kit/10.templates.md @@ -12,105 +12,76 @@ Templates allows to generate extra files during development and build time. Thes ## `addTemplate` -Renders given template during build into the project buildDir. +Renders given template during build into the virtual file system, and optionally to disk in the project `buildDir` -### Type - -```ts -function addTemplate (template: NuxtTemplate | string): ResolvedNuxtTemplate - -interface NuxtTemplate { - src?: string - filename?: string - dst?: string - options?: Record - getContents?: (data: Record) => string | Promise - write?: boolean -} - -interface ResolvedNuxtTemplate { - src: string - filename: string - dst: string - options: Record - getContents: (data: Record) => string | Promise - write: boolean - filename: string - dst: string -} -``` - -### Parameters - -#### `template` - -**Type**: `NuxtTemplate | string` - -**Required**: `true` - -A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: - -- `src` (optional) - - **Type**: `string` +### Usage - Path to the template. If `src` is not provided, `getContents` must be provided instead. - -- `filename` (optional) - - **Type**: `string` - - Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. - -- `dst` (optional) - - **Type**: `string` +```ts twoslash +import { addTemplate, defineNuxtModule } from '@nuxt/kit' +import { defu } from 'defu' - Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. +export default defineNuxtModule({ + setup(options, nuxt) { + const globalMeta = defu(nuxt.options.app.head, { + charset: options.charset, + viewport: options.viewport + }) -- `options` (optional) + addTemplate({ + filename: 'meta.config.mjs', + getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' }) + }) + } +}) +``` - **Type**: `Options` +### Type - Options to pass to the template. +```ts twoslash +function addTemplate (template: NuxtTemplate | string): ResolvedNuxtTemplate +``` -- `getContents` (optional) +### Parameters - **Type**: `(data: Options) => string | Promise` +**template**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: - A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. +| Property | Type | Required | Description | +| ---------- | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `src` | `string` | `false` | Path to the template. If `src` is not provided, `getContents` must be provided instead. | +| `filename` | `string` | `false` | Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. | +| `dst` | `string` | `false` | Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. | +| `options` | `Options` | `false` | Options to pass to the template. | +| `getContents` | `(data: Options) => string \| Promise`{lang="ts"} | `false` | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. | +| `write` | `boolean` | `false` | If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. | -- `write` (optional) - - **Type**: `boolean` +### Examples - If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. +#### Creating a Virtual File for Runtime Plugin -### Examples +In this example, we merge an object inside a module and consume the result in a runtime plugin. -::code-group - -```ts [module.ts] -// https://github.com/nuxt/bridge +```ts twoslash [module.ts] import { addTemplate, defineNuxtModule } from '@nuxt/kit' import { defu } from 'defu' export default defineNuxtModule({ - setup(options, nuxt) { + setup (options, nuxt) { const globalMeta = defu(nuxt.options.app.head, { charset: options.charset, - viewport: options.viewport + viewport: options.viewport, }) addTemplate({ filename: 'meta.config.mjs', - getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' }) + getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' }), }) - } + }, }) ``` -```ts [plugin.ts] +In the module above, we generate a virtual file named `meta.config.mjs`. In the runtime plugin, we can import it using the `#build` alias: + +```ts [runtime/plugin.ts] import { createHead as createServerHead } from '@unhead/vue/server' import { createHead as createClientHead } from '@unhead/vue/client' import { defineNuxtPlugin } from '#imports' @@ -126,147 +97,176 @@ export default defineNuxtPlugin((nuxtApp) => { }) ``` -:: - ## `addTypeTemplate` Renders given template during build into the project buildDir, then registers it as types. +### Usage + +```ts twoslash +import { addTypeTemplate, defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + setup () { + addTypeTemplate({ + filename: 'types/markdown.d.ts', + getContents: () => `declare module '*.md' { + import type { ComponentOptions } from 'vue' + const Component: ComponentOptions + export default Component +}`, + }) + }, +}) +``` + ### Type ```ts -function addTypeTemplate (template: NuxtTypeTemplate | string): ResolvedNuxtTemplate - -interface NuxtTemplate { - src?: string - filename?: string - dst?: string - options?: Record - getContents?: (data: Record) => string | Promise -} - -interface ResolvedNuxtTemplate { - src: string - filename: string - dst: string - options: Record - getContents: (data: Record) => string | Promise - write: boolean - filename: string - dst: string -} +function addTypeTemplate (template: NuxtTypeTemplate | string, context?: { nitro?: boolean, nuxt?: boolean }): ResolvedNuxtTemplate ``` ### Parameters -#### `template` - -**Type**: `NuxtTypeTemplate | string` +**template**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: -**Required**: `true` +| Property | Type | Required | Description | +| ---------- | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `src` | `string` | `false` | Path to the template. If `src` is not provided, `getContents` must be provided instead. | +| `filename` | `string` | `false` | Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. | +| `dst` | `string` | `false` | Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. | +| `options` | `Options` | `false` | Options to pass to the template. | +| `getContents` | `(data: Options) => string \| Promise`{lang="ts"} | `false` | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. | -A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: +**context**: An optional context object can be passed to control where the type is added. If omitted, the type will only be added to the Nuxt context. This object supports the following properties: -- `src` (optional) +| Property | Type | Required | Description | +| ---------- | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `nuxt` | `boolean` | `false` | If set to `true`, the type will be added to the Nuxt context. | +| `nitro` | `boolean` | `false` | If set to `true`, the type will be added to the Nitro context. | - **Type**: `string` - - Path to the template. If `src` is not provided, `getContents` must be provided instead. +### Examples -- `filename` (optional) +#### Adding Type Templates to the Nitro Context - **Type**: `string` +By default, -- only adds the type declarations to the Nuxt context. To also add them to the Nitro context, set nitro to true. - Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. +```ts twoslash +import { addTypeTemplate, defineNuxtModule } from '@nuxt/kit' -- `dst` (optional) +export default defineNuxtModule({ + setup () { + addTypeTemplate({ + filename: 'types/auth.d.ts', + getContents: () => `declare module '#auth-utils' { + interface User { + id: string; + name: string; + } - **Type**: `string` +}`, + }, { + nitro: true, + }) + }, +}) +``` - Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. +This allows the `#auth-utils` module to be used within the Nitro context. -- `options` (optional) +```ts [server/api/auth.ts] +import type { User } from '#auth-utils' - **Type**: `Options` +export default eventHandler(() => { + const user: User = { + id: '123', + name: 'John Doe', + } - Options to pass to the template. + // do something with the user -- `getContents` (optional) + return user +}) +``` - **Type**: `(data: Options) => string | Promise` +## `addServerTemplate` - A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. +Adds a virtual file that can be used within the Nuxt Nitro server build. -### Examples +### Usage -```ts -// https://github.com/Hebilicious/nuxtpress -import { addTypeTemplate, defineNuxtModule } from "@nuxt/kit" +```ts twoslash +import { addServerTemplate, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ - setup() { - addTypeTemplate({ - filename: "types/markdown.d.ts", - getContents: () => /* ts */` - declare module '*.md' { - import type { ComponentOptions } from 'vue' - const Component: ComponentOptions - export default Component - }` + setup () { + addServerTemplate({ + filename: '#my-module/test.mjs', + getContents () { + return 'export const test = 123' + }, }) - } -} + }, +}) ``` -## `updateTemplates` - -Regenerate templates that match the filter. If no filter is provided, all templates will be regenerated. - ### Type -```ts -async function updateTemplates (options: UpdateTemplatesOptions): void - -interface UpdateTemplatesOptions { - filter?: (template: ResolvedNuxtTemplate) => boolean -} - -interface ResolvedNuxtTemplate { - src: string - filename: string - dst: string - options: Record - getContents: (data: Record) => string | Promise - write: boolean - filename: string - dst: string -} +```ts twoslash +function addServerTemplate (template: NuxtServerTemplate): NuxtServerTemplate ``` ### Parameters -#### `options` +**template**: A template object. It must have the following properties: + +| Property | Type | Required | Description | +| ------------- | ---------------------------------------------| -------- | --------------------------------------------------------------------------------------------------------------- | +| `filename` | `string` | `true` | Filename of the template. | +| `getContents` | `() => string \| Promise`{lang="ts"} | `true` | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. | -**Type**: `UpdateTemplatesOptions` +### Examples -**Default**: `{}` +### Creating a Virtual File for Nitro -Options to pass to the template. This object can have the following property: +In this example, we create a virtual file that can be used within the Nuxt Nitro server build. -- `filter` (optional) +```ts twoslash +import { addServerTemplate, defineNuxtModule } from '@nuxt/kit' - **Type**: `(template: ResolvedNuxtTemplate) => boolean` +export default defineNuxtModule({ + setup () { + addServerTemplate({ + filename: '#my-module/test.mjs', + getContents () { + return 'export const test = 123' + }, + }) + }, +}) +``` - A function that will be called with the `template` object. It should return a boolean indicating whether the template should be regenerated. If `filter` is not provided, all templates will be regenerated. +And then in a runtime file -### Example +```ts [server/api/test.ts] +import { test } from '#my-module/test.js' -```ts -// https://github.com/nuxt/nuxt +export default eventHandler(() => { + return test +}) +``` + +## `updateTemplates` + +Regenerate templates that match the filter. If no filter is provided, all templates will be regenerated. + +### Usage + +```ts twoslash import { defineNuxtModule, updateTemplates } from '@nuxt/kit' export default defineNuxtModule({ - setup(options, nuxt) { + setup (options, nuxt) { // watch and rebuild routes template list when one of the pages changes nuxt.hook('builder:watch', async (event, relativePath) => { if (event === 'change') { return } @@ -274,10 +274,24 @@ export default defineNuxtModule({ const path = resolve(nuxt.options.srcDir, relativePath) if (updateTemplatePaths.some(dir => path.startsWith(dir))) { await updateTemplates({ - filter: template => template.filename === 'routes.mjs' + filter: template => template.filename === 'routes.mjs', }) } }) - } + }, }) ``` + +### Type + +```ts +async function updateTemplates (options: UpdateTemplatesOptions): void +``` + +### Parameters + +**options**: Options to pass to the template. This object can have the following property: + +| Property | Type | Required | Description | +| ---------- | -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `filter` | `(template: ResolvedNuxtTemplate) => boolean`{lang="ts"} | `false` | A function that will be called with the `template` object. It should return a boolean indicating whether the template should be regenerated. If `filter` is not provided, all templates will be regenerated. | diff --git a/docs/3.api/5.kit/11.nitro.md b/docs/3.api/5.kit/11.nitro.md index 2064e82ac24b..96065b4efb5a 100644 --- a/docs/3.api/5.kit/11.nitro.md +++ b/docs/3.api/5.kit/11.nitro.md @@ -12,83 +12,67 @@ Nitro is an open source TypeScript framework to build ultra-fast web servers. Nu ## `addServerHandler` -Adds a nitro server handler. Use it if you want to create server middleware or custom route. +Adds a Nitro server handler. Use this if you want to create server middleware or a custom route. + +### Usage + +```ts twoslash +import { createResolver, defineNuxtModule, addServerHandler } from '@nuxt/kit' + +export default defineNuxtModule({ + setup(options) { + const { resolve } = createResolver(import.meta.url) + + addServerHandler({ + route: '/robots.txt', + handler: resolve('./runtime/robots.get') + }) + } +}) +``` ### Type ```ts function addServerHandler (handler: NitroEventHandler): void - -export interface NitroEventHandler { - handler: string; - route?: string; - middleware?: boolean; - lazy?: boolean; - method?: string; -} ``` ### Parameters -#### `handler` - -**Type**: `NitroEventHandler` - -**Required**: `true` - -A handler object with the following properties: - -- `handler` (required) - - **Type**: `string` - - Path to event handler. - -- `route` (optional) - - **Type**: `string` +**handler**: A handler object with the following properties: - Path prefix or route. If an empty string used, will be used as a middleware. +| Property | Type | Required | Description | +| ----------- | -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `handler` | `string` | `true` | Path to event handler. | +| `route` | `string` | `false` | Path prefix or route. If an empty string used, will be used as a middleware. | +| `middleware`| `boolean` | `false` | Specifies this is a middleware handler. Middleware are called on every route and should normally return nothing to pass to the next handlers. | +| `lazy` | `boolean` | `false` | Use lazy loading to import the handler. This is useful when you only want to load the handler on demand. | +| `method` | `string` | `false` | Router method matcher. If handler name contains method name, it will be used as a default value. | -- `middleware` (optional) - - **Type**: `boolean` - - Specifies this is a middleware handler. Middleware are called on every route and should normally return nothing to pass to the next handlers. - -- `lazy` (optional) - - **Type**: `boolean` - - Use lazy loading to import handler. - -- `method` (optional) - - **Type**: `string` +### Examples - Router method matcher. If handler name contains method name, it will be used as a default value. +#### Basic Usage -### Examples +You can use `addServerHandler` to add a server handler from your module. ::code-group -```ts [module.ts] -// https://github.com/nuxt-modules/robots +```ts twoslash [module.ts] import { createResolver, defineNuxtModule, addServerHandler } from '@nuxt/kit' export default defineNuxtModule({ setup(options) { - const resolver = createResolver(import.meta.url) + const { resolve } = createResolver(import.meta.url) addServerHandler({ route: '/robots.txt', - handler: resolver.resolve('./runtime/robots.get') + handler: resolve('./runtime/robots.get') }) } }) ``` -```ts [runtime/robots.get.ts] +```ts twoslash [runtime/robots.get.ts] export default defineEventHandler(() => { return { body: `User-agent: *\nDisallow: /` @@ -98,70 +82,59 @@ export default defineEventHandler(() => { :: -## `addDevServerHandler` +When you access `/robots.txt`, it will return the following response: -Adds a nitro server handler to be used only in development mode. This handler will be excluded from production build. - -### Type - -```ts -function addDevServerHandler (handler: NitroDevEventHandler): void - -export interface NitroDevEventHandler { - handler: EventHandler; - route?: string; -} +```txt +User-agent: * +Disallow: / ``` -### Parameters - -#### `handler` - -**Type**: `NitroEventHandler` - -**Required**: `true` - -A handler object with the following properties: - -- `handler` (required) - - **Type**: `string` - - The event handler. - -- `route` (optional) - - **Type**: `string` - - Path prefix or route. If an empty string used, will be used as a middleware. +## `addDevServerHandler` -### Examples +Adds a Nitro server handler to be used only in development mode. This handler will be excluded from production build. -::code-group +### Usage -```ts [module.ts] +```ts twoslash +import { defineEventHandler } from 'h3' import { createResolver, defineNuxtModule, addDevServerHandler } from '@nuxt/kit' export default defineNuxtModule({ setup() { - const resolver = createResolver(import.meta.url) - addDevServerHandler({ - handler: () => { + handler: defineEventHandler(() => { return { body: `Response generated at ${new Date().toISOString()}` } - }, + }), route: '/_handler' }) } }) ``` -:: +### Type -```ts -// https://github.com/nuxt-modules/tailwindcss +```ts twoslash +function addDevServerHandler (handler: NitroDevEventHandler): void +``` + +### Parameters + +**handler**: A handler object with the following properties: + +| Property | Type | Required | Description | +| ----------- | -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `handler` | `EventHandler` | `true` | Event handler. | +| `route` | `string` | `false` | Path prefix or route. If an empty string used, will be used as a middleware. | + +### Examples + +#### Basic Usage + +In some cases, you may want to create a server handler specifically for development purposes, such as a Tailwind config viewer. + +```ts twoslash import { joinURL } from 'ufo' import { defineNuxtModule, addDevServerHandler } from '@nuxt/kit' @@ -190,29 +163,10 @@ You can call `useNitro()` only after `ready` hook. Changes to the Nitro instance configuration are not applied. :: -### Type - -```ts -function useNitro (): Nitro - -export interface Nitro { - options: NitroOptions; - scannedHandlers: NitroEventHandler[]; - vfs: Record; - hooks: Hookable; - unimport?: Unimport; - logger: ConsolaInstance; - storage: Storage; - close: () => Promise; - updateConfig: (config: NitroDynamicConfig) => void | Promise; -} -``` - -### Examples +### Usage ```ts -// https://github.com/nuxt/nuxt/blob/4e05650cde31ca73be4d14b1f0d23c7854008749/packages/nuxt/src/core/nuxt.ts#L404 -import { defineNuxtModule, useNitro, addPlugin, createResolver } from '@nuxt/kit' +import { defineNuxtModule, useNitro } from '@nuxt/kit' export default defineNuxtModule({ setup(options, nuxt) { @@ -220,21 +174,18 @@ export default defineNuxtModule({ nuxt.hook('ready', () => { const nitro = useNitro() - if (nitro.options.static && nuxt.options.experimental.payloadExtraction === undefined) { - console.warn('Using experimental payload extraction for full-static output. You can opt-out by setting `experimental.payloadExtraction` to `false`.') - nuxt.options.experimental.payloadExtraction = true - } - nitro.options.replace['process.env.NUXT_PAYLOAD_EXTRACTION'] = String(!!nuxt.options.experimental.payloadExtraction) - nitro.options._config.replace!['process.env.NUXT_PAYLOAD_EXTRACTION'] = String(!!nuxt.options.experimental.payloadExtraction) - - if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) { - addPlugin(resolver.resolve(nuxt.options.appDir, 'plugins/payload.client')) - } + // Do something with Nitro instance }) } }) ``` +### Type + +```ts +function useNitro (): Nitro +``` + ## `addServerPlugin` Add plugin to extend Nitro's runtime behavior. @@ -243,6 +194,19 @@ Add plugin to extend Nitro's runtime behavior. You can read more about Nitro plugins in the [Nitro documentation](https://nitro.unjs.io/guide/plugins). :: +### Usage + +```ts twoslash +import { createResolver, defineNuxtModule, addServerPlugin } from '@nuxt/kit' + +export default defineNuxtModule({ + setup() { + const { resolve } = createResolver(import.meta.url) + addServerPlugin(resolve('./runtime/plugin.ts')) + } +}) +``` + ### Type ```ts @@ -251,13 +215,9 @@ function addServerPlugin (plugin: string): void ### Parameters -#### `plugin` - -**Type**: `string` - -**Required**: `true` - -Path to the plugin. The plugin must export a function that accepts Nitro instance as an argument. +| Property | Type | Required | Description | +| ----------- | -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| `plugin` | `string` | `true` | Path to the plugin. The plugin must export a default function that accepts the Nitro instance as an argument. | ### Examples @@ -268,8 +228,8 @@ import { createResolver, defineNuxtModule, addServerPlugin } from '@nuxt/kit' export default defineNuxtModule({ setup() { - const resolver = createResolver(import.meta.url) - addServerPlugin(resolver.resolve('./runtime/plugin.ts')) + const { resolve } = createResolver(import.meta.url) + addServerPlugin(resolve('./runtime/plugin.ts')) } }) ``` @@ -296,23 +256,7 @@ export default defineNitroPlugin((nitroApp) => { Add routes to be prerendered to Nitro. -### Type - -```ts -function function addPrerenderRoutes (routes: string | string[]): void -``` - -### Parameters - -#### `routes` - -**Type**: `string | string[]` - -**Required**: `true` - -A route or an array of routes to prerender. - -### Examples +### Usage ```ts import { defineNuxtModule, addPrerenderRoutes } from '@nuxt/kit' @@ -334,10 +278,39 @@ export default defineNuxtModule({ }) ``` +### Type + +```ts +function addPrerenderRoutes (routes: string | string[]): void +``` + +### Parameters + +| Property | Type | Required | Description | +| ----------- | ------------------------------- | -------- | ---------------------------------------------- | +| `routes` | `string \| string[]`{lang="ts"} | `true` | A route or an array of routes to prerender. | + ## `addServerImportsDir` Add a directory to be scanned for auto-imports by Nitro. +### Usage + +```ts twoslash +import { defineNuxtModule, createResolver, addServerImportsDir } from '@nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'my-module', + configKey: 'myModule', + }, + setup(options) { + const { resolve } = createResolver(import.meta.url) + addServerImportsDir(resolve('./runtime/server/composables')) + } +}) +``` + ### Type ```ts @@ -346,17 +319,18 @@ function addServerImportsDir (dirs: string | string[], opts: { prepend?: boolean ### Parameters -#### `dirs` - -**Type**: `string | string[]` +| Property | Type | Required | Description | +| ----------- | ------------------------------- | -------- | ---------------------------------------------- | +| `dirs` | `string \| string[]`{lang="ts"} | `true` | A directory or an array of directories to register to be scanned by Nitro. | +| `opts` | `{ prepend?: boolean }` | `false` | Options for the import directory. If `prepend` is `true`, the directory is added to the beginning of the scan list. | -**Required**: `true` +### Examples -A directory or an array of directories to register to be scanned by Nitro +You can use `addServerImportsDir` to add a directory to be scanned by Nitro. This is useful when you want Nitro to auto-import functions from a custom server directory. -### Examples +::code-group -```ts +```ts twoslash [module.ts] import { defineNuxtModule, createResolver, addServerImportsDir } from '@nuxt/kit' export default defineNuxtModule({ @@ -365,17 +339,56 @@ export default defineNuxtModule({ configKey: 'myModule', }, setup(options) { - const resolver = createResolver(import.meta.url) - addServerImportsDir(resolver.resolve('./runtime/server/utils')) + const { resolve } = createResolver(import.meta.url) + addServerImportsDir(resolve('./runtime/server/composables')) } }) ``` +```ts twoslash [runtime/server/composables/index.ts] +export function useApiSecret() { + const { apiSecret } = useRuntimeConfig() + return apiSecret +} +``` + +:: + +You can then use the `useApiSecret` function in your server code: + +```ts twoslash [runtime/server/api/hello.ts] +export default defineEventHandler(() => { + const apiSecret = useApiSecret() + // Do something with the apiSecret +}) +``` + ## `addServerScanDir` Add directories to be scanned by Nitro. It will check for subdirectories, which will be registered just like the `~/server` folder is. +::note +Only `~/server/api`, `~/server/routes`, `~/server/middleware`, and `~/server/utils` are scanned. +:: + +### Usage + +```ts twoslash +import { defineNuxtModule, createResolver, addServerScanDir } from '@nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'my-module', + configKey: 'myModule', + }, + setup(options) { + const { resolve } = createResolver(import.meta.url) + addServerScanDir(resolve('./runtime/server')) + } +}) +``` + ### Type ```ts @@ -384,26 +397,43 @@ function addServerScanDir (dirs: string | string[], opts: { prepend?: boolean }) ### Parameters -#### `dirs` +| Property | Type | Required | Description | +| ----------- | ------------------------------- | -------- | ---------------------------------------------- | +| `dirs` | `string \| string[]`{lang="ts"} | `true` | A directory or an array of directories to register to be scanned for by Nitro as server dirs. | +| `opts` | `{ prepend?: boolean }` | `false` | Options for the import directory. If `prepend` is `true`, the directory is added to the beginning of the scan list. | -**Type**: `string | string[]` - -**Required**: `true` +### Examples -A directory or an array of directories to register to be scanned for by Nitro as server dirs. +You can use `addServerScanDir` to add a directory to be scanned by Nitro. This is useful when you want to add a custom server directory. -### Examples +::code-group -```ts +```ts twoslash [module.ts] import { defineNuxtModule, createResolver, addServerScanDir } from '@nuxt/kit' + export default defineNuxtModule({ meta: { name: 'my-module', configKey: 'myModule', }, setup(options) { - const resolver = createResolver(import.meta.url) - addServerScanDir(resolver.resolve('./runtime/server')) + const { resolve } = createResolver(import.meta.url) + addServerScanDir(resolve('./runtime/server')) } }) ``` + +```ts twoslash [runtime/server/utils/index.ts] +export function hello() { + return 'Hello from server utils!' +} +``` +:: + +You can then use the `hello` function in your server code. + +```ts twoslash [runtime/server/api/hello.ts] +export default defineEventHandler(() => { + return hello() // Hello from server utils! +}) +``` diff --git a/docs/3.api/5.kit/12.resolving.md b/docs/3.api/5.kit/12.resolving.md index 9bb3ae55d3c4..3a7b3db34f78 100644 --- a/docs/3.api/5.kit/12.resolving.md +++ b/docs/3.api/5.kit/12.resolving.md @@ -14,58 +14,42 @@ Sometimes you need to resolve a paths: relative to the current module, with unkn Resolves 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. -### Type +### Usage ```ts -async function resolvePath (path: string, options?: ResolvePathOptions): Promise -``` - -### Parameters - -#### `path` - -**Type**: `string` - -**Required**: `true` - -Path to resolve. - -#### `options` - -**Type**: `ResolvePathOptions` - -**Default**: `{}` - -Options to pass to the resolver. This object can have the following properties: - -- `cwd` (optional) - - **Type**: `string` - - **Default**: `process.cwd()` - - Current working directory. - -- `alias` (optional) +import { defineNuxtModule, resolvePath } from '@nuxt/kit' - **Type**: `Record` +export default defineNuxtModule({ + async setup () { + const entrypoint = await resolvePath('@unhead/vue') + console.log(`Unhead entrypoint is ${entrypoint}`) + }, +}) +``` - **Default**: `{}` +### Type - Alias map. +```ts +function resolvePath (path: string, options?: ResolvePathOptions): Promise +``` -- `extensions` (optional) +### Parameters - **Type**: `string[]` +**`path`**: A path to resolve. - **Default**: `['.js', '.mjs', '.ts', '.jsx', '.tsx', '.json']` +**`options`**: Options to pass to the resolver. This object can have the following properties: - Extensions to try. +| Property | Type | Required | Description | +| -------------------- | ----------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | +| `cwd` | `string` | `false` | Base for resolving paths from. Default is Nuxt rootDir. | +| `alias` | `Record`{lang="ts"} | `false` | An object of aliases. Default is Nuxt configured aliases. | +| `extensions` | `string[]` | `false` | The file extensions to try. Default is Nuxt configured extensions. | +| `virtual` | `boolean` | `false` | Whether to resolve files that exist in the Nuxt VFS (for example, as a Nuxt template). | +| `fallbackToOriginal` | `boolean` | `false` | Whether to fallback to the original path if the resolved path does not exist instead of returning the normalized input path. | ### Examples ```ts -// https://github.com/P4sca1/nuxt-headlessui import { defineNuxtModule, resolvePath } from '@nuxt/kit' import { join } from 'pathe' @@ -79,8 +63,8 @@ const headlessComponents: ComponentGroup[] = [ 'ComboboxButton', 'ComboboxInput', 'ComboboxOptions', - 'ComboboxOption' - ] + 'ComboboxOption', + ], }, ] @@ -90,7 +74,7 @@ export default defineNuxtModule({ configKey: 'headlessui', }, defaults: { - prefix: 'Headless' + prefix: 'Headless', }, async setup (options) { const entrypoint = await resolvePath('@headlessui/vue') @@ -104,12 +88,12 @@ export default defineNuxtModule({ export: e, filePath: join(root, group.relativePath), chunkName: group.chunkName, - mode: 'all' - } + mode: 'all', + }, ) } } - } + }, }) ``` @@ -125,87 +109,50 @@ function resolveAlias (path: string, alias?: Record): string ### Parameters -#### `path` - -**Type**: `string` +**`path`**: A path to resolve. -**Required**: `true` - -Path to resolve. - -#### `alias` - -**Type**: `Record` - -**Default**: `{}` - -Alias map. If not provided, it will be read from `nuxt.options.alias`. +**`alias`**: An object of aliases. If not provided, it will be read from `nuxt.options.alias`. ## `findPath` Try to resolve first existing file in given paths. -### Type +### Usage ```ts -async function findPath (paths: string | string[], options?: ResolvePathOptions, pathType: 'file' | 'dir'): Promise +import { defineNuxtModule, findPath } from '@nuxt/kit' +import { join } from 'pathe' -interface ResolvePathOptions { - cwd?: string - alias?: Record - extensions?: string[] -} +export default defineNuxtModule({ + async setup (_, nuxt) { + // Resolve main (app.vue) + const mainComponent = await findPath([ + join(nuxt.options.srcDir, 'App'), + join(nuxt.options.srcDir, 'app'), + ]) + }, +}) ``` -### Parameters - -#### `paths` - -**Type**: `string | string[]` - -**Required**: `true` - -A path or an array of paths to resolve. - -#### `options` - -**Type**: `ResolvePathOptions` - -**Default**: `{}` - -Options to pass to the resolver. This object can have the following properties: - -- `cwd` (optional) - - **Type**: `string` - - **Default**: `process.cwd()` - - Current working directory. - -- `alias` (optional) - - **Type**: `Record` - - **Default**: `{}` - - Alias map. - -- `extensions` (optional) - - **Type**: `string[]` - - **Default**: `['.js', '.mjs', '.ts', '.jsx', '.tsx', '.json']` +### Type - Extensions to try. +```ts +function findPath (paths: string | string[], options?: ResolvePathOptions, pathType: 'file' | 'dir'): Promise +``` -#### `pathType` +### Parameters -**Type**: `'file' | 'dir'` +**`paths`**: A path or an array of paths to resolve. -**Default**: `'file'` +**`options`**: Options to pass to the resolver. This object can have the following properties: -Type of path to resolve. If set to `'file'`, the function will try to resolve a file. If set to `'dir'`, the function will try to resolve a directory. +| Property | Type | Required | Description | +| -------------------- | ----------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | +| `cwd` | `string` | `false` | Base for resolving paths from. Default is Nuxt rootDir. | +| `alias` | `Record`{lang="ts"} | `false` | An object of aliases. Default is Nuxt configured aliases. | +| `extensions` | `string[]` | `false` | The file extensions to try. Default is Nuxt configured extensions. | +| `virtual` | `boolean` | `false` | Whether to resolve files that exist in the Nuxt VFS (for example, as a Nuxt template). | +| `fallbackToOriginal` | `boolean` | `false` | Whether to fallback to the original path if the resolved path does not exist instead of returning the normalized input path. | ## `createResolver` @@ -215,45 +162,44 @@ Creates resolver relative to base path. Watch Vue School video about createResolver. :: -### Type +### Usage ```ts -function createResolver (basePath: string | URL): Resolver +import { defineNuxtModule, createResolver } from '@nuxt/kit' -interface Resolver { - resolve (...path: string[]): string - resolvePath (path: string, options?: ResolvePathOptions): Promise -} +export default defineNuxtModule({ + async setup (_, nuxt) { + const { resolve, resolvePath } = createResolver(import.meta.url) + }, +}) +``` -interface ResolvePathOptions { - cwd?: string - alias?: Record - extensions?: string[] -} +### Type + +```ts +function createResolver (basePath: string | URL): Resolver ``` ### Parameters -#### `basePath` +**`basePath`**: A base path to resolve from. It can be a string or a URL. -**Type**: `string` +### Return Value -**Required**: `true` +The `createResolver` function returns an object with the following properties: -Base path to resolve from. +| Property | Type | Description | +| ------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `resolve` | `(path: string) => string`{lang="ts"} | A function that resolves a path relative to the base path. | +| `resolvePath` | `(path: string, options?: ResolvePathOptions) => Promise`{lang="ts"} | A function that resolves a path relative to the base path and respects Nuxt alias and extensions options. | ### Examples ```ts -// https://github.com/vuejs/pinia/blob/v2/packages/nuxt -import { - defineNuxtModule, - isNuxt2, - createResolver, -} from '@nuxt/kit' +import { createResolver, defineNuxtModule, isNuxt2 } from '@nuxt/kit' export default defineNuxtModule({ - setup(options, nuxt) { + setup (options, nuxt) { const resolver = createResolver(import.meta.url) nuxt.hook('modules:done', () => { @@ -263,6 +209,6 @@ export default defineNuxtModule({ addPlugin(resolver.resolve('./runtime/plugin.vue3')) } }) - } + }, }) ``` diff --git a/docs/3.api/5.kit/13.logging.md b/docs/3.api/5.kit/13.logging.md index cb0781c1f4bd..0d09a2186ac8 100644 --- a/docs/3.api/5.kit/13.logging.md +++ b/docs/3.api/5.kit/13.logging.md @@ -14,6 +14,20 @@ Nuxt provides a logger instance that you can use to log messages with extra feat Returns a logger instance. It uses [consola](https://github.com/unjs/consola) under the hood. +### Usage + +```ts twoslash +import { defineNuxtModule, useLogger } from '@nuxt/kit' + +export default defineNuxtModule({ + setup (options, nuxt) { + const logger = useLogger('my-module') + + logger.info('Hello from my module!') + }, +}) +``` + ### Type ```ts @@ -22,44 +36,20 @@ function useLogger (tag?: string, options?: Partial): ConsolaIns ### Parameters -#### `tag` - -**Type**: `string` - -**Optional**: `true` - -A tag to prefix all log messages with. - -#### `options` +**`tag`**: A tag to suffix all log messages with. -**Type**: `Partial` - -**Optional**: `true` - -Consola configuration options +**`options`**: Consola configuration options. ### Examples -```ts -import { defineNuxtModule, useLogger } from '@nuxt/kit' - -export default defineNuxtModule({ - setup(options, nuxt) { - const logger = useLogger('my-module') - - logger.info('Hello from my module!') - } -}) -``` - -```ts +```ts twoslash import { defineNuxtModule, useLogger } from '@nuxt/kit' export default defineNuxtModule({ - setup(options, nuxt) { + setup (options, nuxt) { const logger = useLogger('my-module', { level: options.quiet ? 0 : 3 }) logger.info('Hello from my module!') - } + }, }) ``` diff --git a/docs/3.api/5.kit/14.builder.md b/docs/3.api/5.kit/14.builder.md index d749fb1ef829..2b4ea1e2ef09 100644 --- a/docs/3.api/5.kit/14.builder.md +++ b/docs/3.api/5.kit/14.builder.md @@ -1,6 +1,6 @@ --- title: Builder -description: Nuxt Kit provides a set of utilities to help you work with the builder. These functions allow you to extend the webpack and vite configurations. +description: Nuxt Kit provides a set of utilities to help you work with the builder. These functions allow you to extend the Vite and webpack configurations. links: - label: Source icon: i-simple-icons-github @@ -8,284 +8,156 @@ links: size: xs --- -Nuxt have builders based on [webpack](https://github.com/nuxt/nuxt/tree/main/packages/webpack) and [vite](https://github.com/nuxt/nuxt/tree/main/packages/vite). You can extend the config passed to each one using `extendWebpackConfig` and `extendViteConfig` functions. You can also add additional plugins via `addVitePlugin`, `addWebpackPlugin` and `addBuildPlugin`. +Nuxt have builders based on [Vite](https://github.com/nuxt/nuxt/tree/main/packages/vite) and [webpack](https://github.com/nuxt/nuxt/tree/main/packages/webpack). You can extend the config passed to each one using `extendViteConfig` and `extendWebpackConfig` functions. You can also add additional plugins via `addVitePlugin`, `addWebpackPlugin` and `addBuildPlugin`. -## `extendWebpackConfig` +## `extendViteConfig` -Extends the webpack configuration. Callback function can be called multiple times, when applying to both client and server builds. +Extends the Vite configuration. Callback function can be called multiple times, when applying to both client and server builds. -### Type +### Usage -```ts -function extendWebpackConfig (callback: ((config: WebpackConfig) => void), options?: ExtendWebpackConfigOptions): void +```ts twoslash +import { defineNuxtModule, extendViteConfig } from '@nuxt/kit' -export interface ExtendWebpackConfigOptions { - dev?: boolean - build?: boolean - server?: boolean - client?: boolean - prepend?: boolean -} +export default defineNuxtModule({ + setup () { + extendViteConfig((config) => { + config.optimizeDeps ||= {} + config.optimizeDeps.include ||= [] + config.optimizeDeps.include.push('cross-fetch') + }) + }, +}) ``` -::read-more{to="https://webpack.js.org/configuration" target="_blank" icon="i-simple-icons-webpack"} -Checkout webpack website for more information about its configuration. -:: - -### Parameters - -#### `callback` - -**Type**: `(config: WebpackConfig) => void` - -**Required**: `true` - -A callback function that will be called with the webpack configuration object. - -#### `options` - -**Type**: `ExtendWebpackConfigOptions` - -**Default**: `{}` - -Options to pass to the callback function. This object can have the following properties: - -- `dev` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in development mode. - -- `build` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in production mode. - -- `server` (optional) - - **Type**: `boolean` - - **Default**: `true` +### Type - If set to `true`, the callback function will be called when building the server bundle. +```ts twoslash +function extendViteConfig (callback: ((config: ViteConfig) => void), options?: ExtendViteConfigOptions): void +``` -- `client` (optional) +::read-more{to="https://vite.dev/config" target="_blank" icon="i-simple-icons-vite"} +Checkout Vite website for more information about its configuration. +:: - **Type**: `boolean` +### Parameters - **Default**: `true` +**`callback`**: A callback function that will be called with the Vite configuration object. - If set to `true`, the callback function will be called when building the client bundle. +**`options`**: Options to pass to the callback function. This object can have the following properties: -- `prepend` (optional) +| Property | Type | Required | Description | +| --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | +| `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. | +| `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. | +| `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. | +| `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. | +| `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. | - **Type**: `boolean` +## `extendWebpackConfig` - If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. +Extends the webpack configuration. Callback function can be called multiple times, when applying to both client and server builds. -### Examples +### Usage -```ts +```ts twoslash import { defineNuxtModule, extendWebpackConfig } from '@nuxt/kit' export default defineNuxtModule({ - setup() { + setup () { extendWebpackConfig((config) => { config.module?.rules.push({ test: /\.txt$/, - use: 'raw-loader' + use: 'raw-loader', }) }) - } + }, }) ``` -## `extendViteConfig` - -Extends the Vite configuration. Callback function can be called multiple times, when applying to both client and server builds. - ### Type -```ts -function extendViteConfig (callback: ((config: ViteConfig) => void), options?: ExtendViteConfigOptions): void - -export interface ExtendViteConfigOptions { - dev?: boolean - build?: boolean - server?: boolean - client?: boolean - prepend?: boolean -} +```ts twoslash +function extendWebpackConfig (callback: ((config: WebpackConfig) => void), options?: ExtendWebpackConfigOptions): void ``` -::read-more{to="https://vite.dev/config" target="_blank" icon="i-simple-icons-vite"} -Checkout Vite website for more information about its configuration. +::read-more{to="https://webpack.js.org/configuration" target="_blank" icon="i-simple-icons-webpack"} +Checkout webpack website for more information about its configuration. :: ### Parameters -#### `callback` - -**Type**: `(config: ViteConfig) => void` - -**Required**: `true` - -A callback function that will be called with the Vite configuration object. - -#### `options` - -**Type**: `ExtendViteConfigOptions` - -**Default**: `{}` - -Options to pass to the callback function. This object can have the following properties: - -- `dev` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in development mode. - -- `build` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in production mode. - -- `server` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the server bundle. - -- `client` (optional) - - **Type**: `boolean` +**`callback`**: A callback function that will be called with the webpack configuration object. - **Default**: `true` +**`options`**: Options to pass to the callback function. This object can have the following properties: - If set to `true`, the callback function will be called when building the client bundle. +| Property | Type | Required | Description | +| --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | +| `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. | +| `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. | +| `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. | +| `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. | +| `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. | -- `prepend` (optional) - - **Type**: `boolean` +## `addVitePlugin` - If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. +Append Vite plugin to the config. -### Examples +### Usage -```ts -// https://github.com/Hrdtr/nuxt-appwrite -import { defineNuxtModule, extendViteConfig } from '@nuxt/kit' +```ts twoslash +import { addVitePlugin, defineNuxtModule } from '@nuxt/kit' +import { svg4VuePlugin } from 'vite-plugin-svg4vue' export default defineNuxtModule({ - setup() { - extendViteConfig((config) => { - config.optimizeDeps = config.optimizeDeps || {} - config.optimizeDeps.include = config.optimizeDeps.include || [] - config.optimizeDeps.include.push('cross-fetch') - }) - } + meta: { + name: 'nuxt-svg-icons', + configKey: 'nuxtSvgIcons', + }, + defaults: { + svg4vue: { + assetsDirName: 'assets/icons', + }, + }, + setup (options) { + addVitePlugin(svg4VuePlugin(options.svg4vue)) + }, }) ``` -## `addWebpackPlugin` - -Append webpack plugin to the config. - ### Type -```ts -function addWebpackPlugin (pluginOrGetter: PluginOrGetter, options?: ExtendWebpackConfigOptions): void - -type PluginOrGetter = WebpackPluginInstance | WebpackPluginInstance[] | (() => WebpackPluginInstance | WebpackPluginInstance[]) - -interface ExtendWebpackConfigOptions { - dev?: boolean - build?: boolean - server?: boolean - client?: boolean - prepend?: boolean -} +```ts twoslash +function addVitePlugin (pluginOrGetter: PluginOrGetter, options?: ExtendViteConfigOptions): void ``` ::tip -See [webpack website](https://webpack.js.org/concepts/plugins) for more information about webpack plugins. You can also use [this collection](https://webpack.js.org/awesome-webpack/#webpack-plugins) to find a plugin that suits your needs. +See [Vite website](https://vite.dev/guide/api-plugin.html) for more information about Vite plugins. You can also use [this repository](https://github.com/vitejs/awesome-vite#plugins) to find a plugin that suits your needs. :: ### Parameters -#### `pluginOrGetter` - -**Type**: `PluginOrGetter` - -**Required**: `true` - -A webpack plugin instance or an array of webpack plugin instances. If a function is provided, it must return a webpack plugin instance or an array of webpack plugin instances. - -#### `options` - -**Type**: `ExtendWebpackConfigOptions` - -**Default**: `{}` - -Options to pass to the callback function. This object can have the following properties: - -- `dev` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in development mode. +**`pluginOrGetter`**: A Vite plugin instance or an array of Vite plugin instances. If a function is provided, it must return a Vite plugin instance or an array of Vite plugin instances. -- `build` (optional) +**`options`**: Options to pass to the callback function. This object can have the following properties: - **Type**: `boolean` +| Property | Type | Required | Description | +| --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | +| `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. | +| `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. | +| `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. | +| `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. | +| `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. | - **Default**: `true` - - If set to `true`, the callback function will be called when building in production mode. - -- `server` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the server bundle. - -- `client` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the client bundle. - -- `prepend` (optional) - - **Type**: `boolean` +## `addWebpackPlugin` - If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. +Append webpack plugin to the config. -### Examples +### Usage -```ts -// https://github.com/nuxt-modules/eslint +```ts twoslash import EslintWebpackPlugin from 'eslint-webpack-plugin' -import { defineNuxtModule, addWebpackPlugin } from '@nuxt/kit' +import { addWebpackPlugin, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ meta: { @@ -296,196 +168,62 @@ export default defineNuxtModule({ include: [`${nuxt.options.srcDir}/**/*.{js,jsx,ts,tsx,vue}`], lintOnStart: true, }), - setup(options, nuxt) { + setup (options, nuxt) { const webpackOptions = { ...options, context: nuxt.options.srcDir, files: options.include, - lintDirtyModulesOnly: !options.lintOnStart + lintDirtyModulesOnly: !options.lintOnStart, } addWebpackPlugin(new EslintWebpackPlugin(webpackOptions), { server: false }) - } + }, }) ``` -## `addVitePlugin` - -Append Vite plugin to the config. - ### Type -```ts -function addVitePlugin (pluginOrGetter: PluginOrGetter, options?: ExtendViteConfigOptions): void - -type PluginOrGetter = VitePlugin | VitePlugin[] | (() => VitePlugin | VitePlugin[]) - -interface ExtendViteConfigOptions { - dev?: boolean - build?: boolean - server?: boolean - client?: boolean - prepend?: boolean -} +```ts twoslash +function addWebpackPlugin (pluginOrGetter: PluginOrGetter, options?: ExtendWebpackConfigOptions): void ``` ::tip -See [Vite website](https://vite.dev/guide/api-plugin.html) for more information about Vite plugins. You can also use [this repository](https://github.com/vitejs/awesome-vite#plugins) to find a plugin that suits your needs. +See [webpack website](https://webpack.js.org/concepts/plugins) for more information about webpack plugins. You can also use [this collection](https://webpack.js.org/awesome-webpack/#webpack-plugins) to find a plugin that suits your needs. :: ### Parameters -#### `pluginOrGetter` - -**Type**: `PluginOrGetter` - -**Required**: `true` - -A Vite plugin instance or an array of Vite plugin instances. If a function is provided, it must return a Vite plugin instance or an array of Vite plugin instances. - -#### `options` - -**Type**: `ExtendViteConfigOptions` - -**Default**: `{}` - -Options to pass to the callback function. This object can have the following properties: - -- `dev` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in development mode. - -- `build` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in production mode. +**`pluginOrGetter`**: A webpack plugin instance or an array of webpack plugin instances. If a function is provided, it must return a webpack plugin instance or an array of webpack plugin instances. -- `server` (optional) +**`options`**: Options to pass to the callback function. This object can have the following properties: - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the server bundle. - -- `client` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the client bundle. - -- `prepend` (optional) - - **Type**: `boolean` - - If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. - -### Examples - -```ts -// https://github.com/yisibell/nuxt-svg-icons -import { defineNuxtModule, addVitePlugin } from '@nuxt/kit' -import { svg4VuePlugin } from 'vite-plugin-svg4vue' - -export default defineNuxtModule({ - meta: { - name: 'nuxt-svg-icons', - configKey: 'nuxtSvgIcons', - }, - defaults: { - svg4vue: { - assetsDirName: 'assets/icons', - }, - }, - setup(options) { - addVitePlugin(svg4VuePlugin(options.svg4vue)) - }, -}) -``` +| Property | Type | Required | Description | +| --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | +| `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. | +| `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. | +| `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. | +| `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. | +| `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. | ## `addBuildPlugin` -Builder-agnostic version of `addWebpackPlugin` and `addVitePlugin`. It will add the plugin to both webpack and vite configurations if they are present. +Builder-agnostic version of `addVitePlugin` and `addWebpackPlugin`. It will add the plugin to both Vite and webpack configurations if they are present. ### Type -```ts +```ts twoslash function addBuildPlugin (pluginFactory: AddBuildPluginFactory, options?: ExtendConfigOptions): void - -interface AddBuildPluginFactory { - vite?: () => VitePlugin | VitePlugin[] - webpack?: () => WebpackPluginInstance | WebpackPluginInstance[] -} - -interface ExtendConfigOptions { - dev?: boolean - build?: boolean - server?: boolean - client?: boolean - prepend?: boolean -} ``` ### Parameters -#### `pluginFactory` - -**Type**: `AddBuildPluginFactory` - -**Required**: `true` - -A factory function that returns an object with `vite` and/or `webpack` properties. These properties must be functions that return a Vite plugin instance or an array of Vite plugin instances and/or a webpack plugin instance or an array of webpack plugin instances. - -#### `options` - -**Type**: `ExtendConfigOptions` - -**Default**: `{}` - -Options to pass to the callback function. This object can have the following properties: - -- `dev` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in development mode. - -- `build` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building in production mode. - -- `server` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the server bundle. - -- `client` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, the callback function will be called when building the client bundle. - -- `prepend` (optional) +**`pluginFactory`**: A factory function that returns an object with `vite` and/or `webpack` properties. These properties must be functions that return a Vite plugin instance or an array of Vite plugin instances and/or a webpack plugin instance or an array of webpack plugin instances. - **Type**: `boolean` +**`options`**: Options to pass to the callback function. This object can have the following properties: - If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. +| Property | Type | Required | Description | +| --------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------ | +| `dev` | `boolean` | `false` | If set to `true`, the callback function will be called when building in development mode. | +| `build` | `boolean` | `false` | If set to `true`, the callback function will be called when building in production mode. | +| `server` | `boolean` | `false` | If set to `true`, the callback function will be called when building the server bundle. | +| `client` | `boolean` | `false` | If set to `true`, the callback function will be called when building the client bundle. | +| `prepend` | `boolean` | `false` | If set to `true`, the callback function will be prepended to the array with `unshift()` instead of `push()`. | diff --git a/docs/3.api/5.kit/2.programmatic.md b/docs/3.api/5.kit/2.programmatic.md index d5877bf01f51..138602f8f0cb 100644 --- a/docs/3.api/5.kit/2.programmatic.md +++ b/docs/3.api/5.kit/2.programmatic.md @@ -17,39 +17,17 @@ Load Nuxt programmatically. It will load the Nuxt configuration, instantiate and ### Type ```ts -async function loadNuxt (loadOptions?: LoadNuxtOptions): Promise - -interface LoadNuxtOptions extends LoadNuxtConfigOptions { - dev?: boolean - ready?: boolean -} +function loadNuxt (loadOptions?: LoadNuxtOptions): Promise ``` ### Parameters -#### `loadOptions` - -**Type**: `LoadNuxtOptions` - -**Default**: `{}` - -Loading conditions for Nuxt. `loadNuxt` uses [`c12`](https://github.com/unjs/c12) under the hood, so it accepts the same options as `c12.loadConfig` with some additional options: - -- `dev` (optional) +**`loadOptions`**: Loading conditions for Nuxt. `loadNuxt` uses [`c12`](https://github.com/unjs/c12) under the hood, so it accepts the same options as `c12.loadConfig` with some additional options: - **Type**: `boolean` - - **Default**: `false` - - If set to `true`, Nuxt will be loaded in development mode. - -- `ready` (optional) - - **Type**: `boolean` - - **Default**: `true` - - If set to `true`, Nuxt will be ready to use after the `loadNuxt` call. If set to `false`, you will need to call `nuxt.ready()` to make sure Nuxt is ready to use. +| Property | Type | Required | Description | +| -------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dev` | `boolean` | `false` | If set to `true`, Nuxt will be loaded in development mode. | +| `ready` | `boolean` | `true` | If set to `true`, Nuxt will be ready to use after the `loadNuxt` call. If set to `false`, you will need to call `nuxt.ready()` to make sure Nuxt is ready to use. | ## `buildNuxt` @@ -58,18 +36,12 @@ Build Nuxt programmatically. It will invoke the builder (currently [@nuxt/vite-b ### Type ```ts -async function buildNuxt (nuxt: Nuxt): Promise +function buildNuxt (nuxt: Nuxt): Promise ``` ### Parameters -#### `nuxt` - -**Type**: `Nuxt` - -**Required**: `true` - -Nuxt instance to build. It can be retrieved from the context via `useNuxt()` call. +**`nuxt`**: Nuxt instance to build. It can be retrieved from the context via `useNuxt()` call. ## `loadNuxtConfig` @@ -78,18 +50,12 @@ Load Nuxt configuration. It will return the promise with the configuration objec ### Type ```ts -async function loadNuxtConfig (options: LoadNuxtConfigOptions): Promise +function loadNuxtConfig (options: LoadNuxtConfigOptions): Promise ``` ### Parameters -#### `options` - -**Type**: `LoadNuxtConfigOptions` - -**Required**: `true` - -Options to pass in [`c12`](https://github.com/unjs/c12#options) `loadConfig` call. +**`options`**: Options to pass in [`c12`](https://github.com/unjs/c12#options) `loadConfig` call. ## `writeTypes` @@ -99,27 +65,8 @@ Generates `tsconfig.json` and writes it to the project buildDir. ```ts function writeTypes (nuxt?: Nuxt): void - -interface Nuxt { - options: NuxtOptions - hooks: Hookable - hook: Nuxt['hooks']['hook'] - callHook: Nuxt['hooks']['callHook'] - addHooks: Nuxt['hooks']['addHooks'] - ready: () => Promise - close: () => Promise - server?: any - vfs: Record - apps: Record -} ``` ### Parameters -#### `nuxt` - -**Type**: `Nuxt` - -**Required**: `true` - -Nuxt instance to build. It can be retrieved from the context via `useNuxt()` call. +**`nuxt`**: Nuxt instance to build. It can be retrieved from the context via `useNuxt()` call. diff --git a/docs/3.api/5.kit/3.compatibility.md b/docs/3.api/5.kit/3.compatibility.md index a253f7e84543..c5608c14e282 100644 --- a/docs/3.api/5.kit/3.compatibility.md +++ b/docs/3.api/5.kit/3.compatibility.md @@ -14,64 +14,39 @@ Nuxt Kit utilities can be used in Nuxt 3, Nuxt 2 with Bridge and even Nuxt 2 wit Checks if constraints are met for the current Nuxt version. If not, returns an array of messages. Nuxt 2 version also checks for `bridge` support. +### Usage + +```ts twoslash +import { defineNuxtModule, checkNuxtCompatibility } from '@nuxt/kit' + +export default defineNuxtModule({ + async setup () { + const issues = await checkNuxtCompatibility({ nuxt: '^2.16.0' }, nuxt) + if (issues.length) { + console.warn('Nuxt compatibility issues found:\n' + issues.toString()) + } else { + // do something + } + } +}) +``` + ### Type ```ts -async function checkNuxtCompatibility( - constraints: NuxtCompatibility, - nuxt?: Nuxt -): Promise; - -interface NuxtCompatibility { - nuxt?: string; - bridge?: boolean; - builder?: { - // Set `false` if your module is not compatible with a builder - // or a semver-compatible string version constraint - vite?: false | string; - webpack?: false | string; - }; -} - -interface NuxtCompatibilityIssue { - name: string; - message: string; -} - -interface NuxtCompatibilityIssues extends Array { - toString(): string; -} +function checkNuxtCompatibility(constraints: NuxtCompatibility, nuxt?: Nuxt): Promise; ``` ### Parameters -#### `constraints` - -**Type**: `NuxtCompatibility` - -**Default**: `{}` - -Constraints to check for. It accepts the following properties: - -- `nuxt` (optional) - - **Type**: `string` +**`constraints`**: Version and builder constraints to check against. It accepts the following properties: - Nuxt version in semver format. Versions may be defined in Node.js way, for example: `>=2.15.0 <3.0.0`. +| Property | Type | Required | Description | +| -------- | --------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| `nuxt` | `string` | `false` | Nuxt version in semver format. Versions may be defined in Node.js way, for example: `>=2.15.0 <3.0.0`. | +| `bridge` | `Record`{lang="ts"} | `false` | Specifies version constraints or disables compatibility for specific Nuxt builders like `vite`, `webpack`, or `rspack`. Use `false` to disable. | -- `bridge` (optional) - - **Type**: `boolean` - - If set to `true`, it will check if the current Nuxt version supports `bridge`. - -#### `nuxt` - -**Type**: `Nuxt` - -**Default**: `useNuxt()` - -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. ## `assertNuxtCompatibility` @@ -80,134 +55,114 @@ Asserts that constraints are met for the current Nuxt version. If not, throws an ### Type ```ts -async function assertNuxtCompatibility( - constraints: NuxtCompatibility, - nuxt?: Nuxt -): Promise; - -interface NuxtCompatibility { - nuxt?: string; - bridge?: boolean; -} +function assertNuxtCompatibility(constraints: NuxtCompatibility, nuxt?: Nuxt): Promise; ``` ### Parameters -#### `constraints` - -**Type**: `NuxtCompatibility` +**`constraints`**: Version and builder constraints to check against. Refer to the [constraints table in `checkNuxtCompatibility`](#parameters) for details. -**Default**: `{}` +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. -Constraints to check for. It accepts the following properties: - -- `nuxt` (optional) - - **Type**: `string` - - Nuxt version in semver format. Versions may be defined in Node.js way, for example: `>=2.15.0 <3.0.0`. - -- `bridge` (optional) - - **Type**: `boolean` - - If set to `true`, it will check if the current Nuxt version supports `bridge`. - -#### `nuxt` - -**Type**: `Nuxt` +## `hasNuxtCompatibility` -**Default**: `useNuxt()` +Checks if constraints are met for the current Nuxt version. Return `true` if all constraints are met, otherwise returns `false`. Nuxt 2 version also checks for `bridge` support. -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +### Usage -## `hasNuxtCompatibility` +```ts twoslash +import { defineNuxtModule, hasNuxtCompatibility } from '@nuxt/kit' -Checks if constraints are met for the current Nuxt version. Return `true` if all constraints are met, otherwise returns `false`. Nuxt 2 version also checks for `bridge` support. +export defineNuxtModule({ + async setup () { + const usingNewPostcss = await hasNuxtCompatibility({ nuxt: '^2.16.0' }, nuxt) + if (usingNewPostcss) { + // do something + } else { + // do something else + } + } +}) ### Type +``` ```ts -async function hasNuxtCompatibility( - constraints: NuxtCompatibility, - nuxt?: Nuxt -): Promise; - -interface NuxtCompatibility { - nuxt?: string; - bridge?: boolean; -} +function hasNuxtCompatibility(constraints: NuxtCompatibility, nuxt?: Nuxt): Promise; ``` ### Parameters -#### `constraints` +**`constraints`**: Version and builder constraints to check against. Refer to the [constraints table in `checkNuxtCompatibility`](#parameters) for details. -**Type**: `NuxtCompatibility` +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. -**Default**: `{}` +## `isNuxtMajorVersion` -Constraints to check for. It accepts the following properties: +Check if current Nuxt instance is of specified major version -- `nuxt` (optional) +### Usage - **Type**: `string` +```ts twoslash +import { defineNuxtModule, isNuxtMajorVersion } from '@nuxt/kit' - Nuxt version in semver format. Versions may be defined in Node.js way, for example: `>=2.15.0 <3.0.0`. - -- `bridge` (optional) +export default defineNuxtModule({ + async setup () { + if (isNuxtMajorVersion(3)) { + // do something for Nuxt 3 + } else { + // do something else for other versions + } +}) +``` - **Type**: `boolean` +### Type - If set to `true`, it will check if the current Nuxt version supports `bridge`. +```ts +function isNuxtMajorVersion(major: number, nuxt?: Nuxt): boolean; +``` -#### `nuxt` +### Parameters -**Type**: `Nuxt` +**`major`**: Major version to check against. -**Default**: `useNuxt()` +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +## `isNuxt3` -## `isNuxt2` +Checks if the current Nuxt version is 3.x. -Checks if the current Nuxt version is 2.x. +::note +Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version. +:: ### Type ```ts -function isNuxt2(nuxt?: Nuxt): boolean; +function isNuxt3(nuxt?: Nuxt): boolean; ``` ### Parameters -#### `nuxt` - -**Type**: `Nuxt` +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. -**Default**: `useNuxt()` +## `isNuxt2` -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +Checks if the current Nuxt version is 2.x. -## `isNuxt3` - -Checks if the current Nuxt version is 3.x. +::note +Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version. +:: ### Type ```ts -function isNuxt3(nuxt?: Nuxt): boolean; +function isNuxt2(nuxt?: Nuxt): boolean; ``` ### Parameters -#### `nuxt` - -**Type**: `Nuxt` - -**Default**: `useNuxt()` - -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. ## `getNuxtVersion` @@ -221,10 +176,4 @@ function getNuxtVersion(nuxt?: Nuxt): string; ### Parameters -#### `nuxt` - -**Type**: `Nuxt` - -**Default**: `useNuxt()` - -Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. +**`nuxt`**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call. diff --git a/docs/3.api/5.kit/4.autoimports.md b/docs/3.api/5.kit/4.autoimports.md index 57801966ca56..9ccf0ad77f00 100644 --- a/docs/3.api/5.kit/4.autoimports.md +++ b/docs/3.api/5.kit/4.autoimports.md @@ -58,7 +58,7 @@ function addImports (imports: Import | Import[]): void `imports`: An object or an array of objects with the following properties: -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `name` | `string` | `true` | Import name to be detected. | | `from` | `string` | `true` | Module specifier to import from. | @@ -98,7 +98,7 @@ function addImportsDir (dirs: string | string[], options?: { prepend?: boolean } ### Parameters -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `dirs` | `string \| string[]`{lang="ts"} | `true` | A string or an array of strings with the path to the directory to import from. | | `options` | `{ prepend?: boolean }`{lang="ts"} | `false` | Options to pass to the import. If `prepend` is set to `true`, the imports will be prepended to the list of imports. | @@ -138,7 +138,7 @@ function addImportsSources (importSources: ImportSource | ImportSource[]): void **importSources**: An object or an array of objects with the following properties: -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `from` | `string` | `true` | Module specifier to import from. | | `imports` | `PresetImport \| ImportSource[]`{lang="ts"} | `true` | An object or an array of objects, which can be import names, import objects or import sources. | diff --git a/docs/3.api/5.kit/5.components.md b/docs/3.api/5.kit/5.components.md index 9f0540226c9c..b75b0fbce20e 100644 --- a/docs/3.api/5.kit/5.components.md +++ b/docs/3.api/5.kit/5.components.md @@ -46,7 +46,7 @@ function addComponentsDir (dir: ComponentsDir, opts: { prepend?: boolean } = {}) `dir` An object with the following properties: -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `path` | `string` | `true` | Path (absolute or relative) to the directory containing your components. You can use Nuxt aliases (~ or @) to refer to directories inside project or directly use an npm package path similar to require. | | `pattern` | `string \| string[]`{lang="ts"} | `false` | Accept Pattern that will be run against specified path. | @@ -66,7 +66,7 @@ function addComponentsDir (dir: ComponentsDir, opts: { prepend?: boolean } = {}) `opts` -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `prepend` | `boolean` | `false` | If set to `true`, the directory will be prepended to the array with `unshift()` instead of `push()`. | @@ -110,7 +110,7 @@ function addComponent (options: AddComponentOptions): void `options`: An object with the following properties: -| Prop | Type | Required | Description | +| Property | Type | Required | Description | | ------------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `name` | `string` | `true` | Component name. | | `filePath` | `string` | `true` | Path to the component. | @@ -125,3 +125,22 @@ function addComponent (options: AddComponentOptions): void | `island` | `boolean` | `false` | If enabled, registers component as island. You can read more about islands in [``](/docs/api/components/nuxt-island#nuxtisland) component description. | | `mode` | `'client' \| 'server' \| 'all'`{lang="ts"} | `false` | This options indicates if component should render on client, server or both. By default, it will render on both client and server. | | `priority` | `number` | `false` | Priority of the component, if multiple components have the same name, the one with the highest priority will be used. | + +### Examples + +If you want to auto-import a component from an npm package, and the component is a named export (rather than the default), you can use the `export` option to specify it. + +```ts +import { addComponent, defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + setup () { + // import { MyComponent as MyAutoImportedComponent } from 'my-npm-package' + addComponent({ + name: 'MyAutoImportedComponent', + export: 'MyComponent', + filePath: 'my-npm-package', + }) + }, +}) +``` diff --git a/docs/3.api/5.kit/6.context.md b/docs/3.api/5.kit/6.context.md index df4199fb3559..7b6385b71a0f 100644 --- a/docs/3.api/5.kit/6.context.md +++ b/docs/3.api/5.kit/6.context.md @@ -8,64 +8,71 @@ links: size: xs --- -Nuxt modules allow you to enhance Nuxt's capabilities. They offer a structured way to keep your code organized and modular. If you're looking to break down your module into smaller components, Nuxt offers the `useNuxt` and `tryUseNuxt` functions. These functions enable you to conveniently access the Nuxt instance from the context without having to pass it as argument. +Nuxt modules allow you to enhance Nuxt's capabilities. They offer a structured way to keep your code organized and modular. If you're looking to break down your module into smaller components, Nuxt offers the `useNuxt` and `tryUseNuxt` functions. These functions enable you to conveniently access the Nuxt instance from the context without having to pass it as an argument. ::note -When you're working with the `setup` function in Nuxt modules, Nuxt is already provided as the second argument. This means you can directly utilize it without needing to call `useNuxt()`. You can look at [Nuxt Site Config](https://github.com/harlan-zw/nuxt-site-config) as an example of usage. +When you're working with the `setup` function in Nuxt modules, Nuxt is already provided as the second argument. This means you can access it directly without needing to call `useNuxt()`. :: ## `useNuxt` Get the Nuxt instance from the context. It will throw an error if Nuxt is not available. -### Type +### Usage ```ts -function useNuxt(): Nuxt +import { useNuxt } from '@nuxt/kit' + +const setupSomeFeature = () => { + const nuxt = useNuxt() -interface Nuxt { - options: NuxtOptions - hooks: Hookable - hook: Nuxt['hooks']['hook'] - callHook: Nuxt['hooks']['callHook'] - addHooks: Nuxt['hooks']['addHooks'] - ready: () => Promise - close: () => Promise - server?: any - vfs: Record - apps: Record + // You can now use the nuxt instance + console.log(nuxt.options) } ``` +### Type + +```ts twoslash +function useNuxt(): Nuxt +``` + +### Return Value + +The `useNuxt` function returns the Nuxt instance, which contains all the options and methods available in Nuxt. + +| Property | Type | Description | +| ---------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `options` | `NuxtOptions` | The resolved Nuxt configuration. | +| `hooks` | `Hookable` | The Nuxt hook system. Allows registering and listening to lifecycle events. | +| `hook` | `(name: string, (...args: any[]) => Promise \| void) => () => void` | Shortcut for `nuxt.hooks.hook`. Registers a single callback for a specific lifecycle hook. | +| `callHook` | `(name: string, ...args: any[]) => Promise` | Shortcut for `nuxt.hooks.callHook`. Triggers a lifecycle hook manually and runs all registered callbacks. | +| `addHooks` | `(configHooks: NestedHooks) => () => void` | Shortcut for `nuxt.hooks.addHooks`. Registers multiple hooks at once. | + ### Examples ::code-group -```ts [setupTranspilation.ts] -// https://github.com/Lexpeartha/nuxt-xstate/blob/main/src/parts/transpile.ts +```ts twoslash [setupTranspilation.ts] import { useNuxt } from '@nuxt/kit' export const setupTranspilation = () => { const nuxt = useNuxt() - nuxt.options.build.transpile = nuxt.options.build.transpile || [] - if (nuxt.options.builder === '@nuxt/webpack-builder') { - nuxt.options.build.transpile.push( - 'xstate', - ) + nuxt.options.build.transpile ||= [] + nuxt.options.build.transpile.push('xstate') } } ``` -```ts [module.ts] -import { useNuxt } from '@nuxt/kit' +```ts twoslash [module.ts] import { setupTranspilation } from './setupTranspilation' export default defineNuxtModule({ - setup() { + setup () { setupTranspilation() - } + }, }) ``` @@ -75,35 +82,44 @@ export default defineNuxtModule({ Get the Nuxt instance from the context. It will return `null` if Nuxt is not available. -### Type +### Usage -```ts -function tryUseNuxt(): Nuxt | null +```ts twoslash +import { tryUseNuxt } from '@nuxt/kit' -interface Nuxt { - options: NuxtOptions - hooks: Hookable - hook: Nuxt['hooks']['hook'] - callHook: Nuxt['hooks']['callHook'] - addHooks: Nuxt['hooks']['addHooks'] - ready: () => Promise - close: () => Promise - server?: any - vfs: Record - apps: Record +function setupSomething () { + const nuxt = tryUseNuxt() + + if (nuxt) { + // You can now use the nuxt instance + console.log(nuxt.options) + } else { + console.log('Nuxt is not available') + } } ``` +### Type + +```ts twoslash +function tryUseNuxt(): Nuxt | null +``` + +### Return Value + +The `tryUseNuxt` function returns the Nuxt instance if available, or `null` if Nuxt is not available. + +The Nuxt instance as described in the `useNuxt` section. + ### Examples ::code-group -```ts [requireSiteConfig.ts] -// https://github.com/harlan-zw/nuxt-site-config/blob/main/test/assertions.test.ts +```ts twoslash [requireSiteConfig.ts] import { tryUseNuxt } from '@nuxt/kit' interface SiteConfig { - title: string + title: string | null } export const requireSiteConfig = (): SiteConfig => { @@ -115,15 +131,15 @@ export const requireSiteConfig = (): SiteConfig => { } ``` -```ts [module.ts] +```ts twoslash [module.ts] import { useNuxt } from '@nuxt/kit' import { requireSiteConfig } from './requireSiteConfig' export default defineNuxtModule({ - setup(_, nuxt) { + setup (_, nuxt) { const config = requireSiteConfig() nuxt.options.app.head.title = config.title - } + }, }) ``` diff --git a/docs/3.api/5.kit/7.pages.md b/docs/3.api/5.kit/7.pages.md index e0912c63ade8..a0dd6c365292 100644 --- a/docs/3.api/5.kit/7.pages.md +++ b/docs/3.api/5.kit/7.pages.md @@ -16,258 +16,147 @@ In Nuxt, routes are automatically generated based on the structure of the files Watch Vue School video about extendPages. :: -### Type - -```ts -function extendPages (callback: (pages: NuxtPage[]) => void): void - -type NuxtPage = { - name?: string - path: string - file?: string - meta?: Record - alias?: string[] | string - redirect?: RouteLocationRaw - children?: NuxtPage[] -} -``` - -### Parameters - -#### `callback` +### Usage -**Type**: `(pages: NuxtPage[]) => void` - -**Required**: `true` - -A function that will be called with the pages configuration. You can alter this array by adding, deleting, or modifying its elements. Note: You should modify the provided pages array directly, as changes made to a copied array will not be reflected in the configuration. - -### Examples - -```ts -// https://github.com/nuxt-modules/prismic/blob/master/src/module.ts +```ts twoslash import { createResolver, defineNuxtModule, extendPages } from '@nuxt/kit' export default defineNuxtModule({ - setup(options) { - const resolver = createResolver(import.meta.url) + setup (options) { + const { resolve } = createResolver(import.meta.url) extendPages((pages) => { pages.unshift({ name: 'prismic-preview', path: '/preview', - file: resolver.resolve('runtime/preview.vue') - }) + file: resolve('runtime/preview.vue'), + }) }) - } + }, }) ``` -## `extendRouteRules` - -Nuxt is powered by the [Nitro](https://nitro.unjs.io) server engine. With Nitro, you can incorporate high-level logic directly into your configuration, which is useful for actions like redirects, proxying, caching, and appending headers to routes. This configuration works by associating route patterns with specific route settings. - -::tip -You can read more about Nitro route rules in the [Nitro documentation](https://nitro.unjs.io/guide/routing#route-rules). -:: - -::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/adding-route-rules-and-route-middlewares?friend=nuxt" target="_blank"} -Watch Vue School video about adding route rules and route middelwares. -:: - ### Type ```ts -function extendRouteRules (route: string, rule: NitroRouteConfig, options: ExtendRouteRulesOptions): void - -interface NitroRouteConfig { - cache?: CacheOptions | false; - headers?: Record; - redirect?: string | { to: string; statusCode?: HTTPStatusCode }; - prerender?: boolean; - proxy?: string | ({ to: string } & ProxyOptions); - isr?: number | boolean; - cors?: boolean; - swr?: boolean | number; - static?: boolean | number; -} - -interface ExtendRouteRulesOptions { - override?: boolean -} - -interface CacheOptions { - swr?: boolean - name?: string - group?: string - integrity?: any - maxAge?: number - staleMaxAge?: number - base?: string - headersOnly?: boolean -} - -// See https://www.jsdocs.io/package/h3#ProxyOptions -interface ProxyOptions { - headers?: RequestHeaders | HeadersInit; - fetchOptions?: RequestInit & { duplex?: Duplex } & { - ignoreResponseError?: boolean; - }; - fetch?: typeof fetch; - sendStream?: boolean; - streamRequest?: boolean; - cookieDomainRewrite?: string | Record; - cookiePathRewrite?: string | Record; - onResponse?: (event: H3Event, response: Response) => void; -} +function extendPages(callback: (pages: NuxtPage[]) => void): void ``` ### Parameters -#### `route` - -**Type**: `string` +**callback**: A function that will be called with the pages configuration. You can alter this array by adding, deleting, or modifying its elements. Note: You should modify the provided pages array directly, as changes made to a copied array will not be reflected in the configuration. -**Required**: `true` +| Property | Type | Required | Description | +| ---------- | ---------------------------------- | -------- | -------------------------------------------------------------------------------------------- | +| `name` | `string` | `false` | The name of the route. Useful for programmatic navigation and identifying routes. | +| `path` | `string` | `false` | The route URL path. If not set, Nuxt will infer it from the file location. | +| `file` | `string` | `false` | Path to the Vue file that should be used as the component for the route. | +| `meta` | `Record`{lang="ts"} | `false` | Custom metadata for the route. Can be used in layouts, middlewares, or navigation guards. | +| `alias` | `string[] \| string`{lang="ts"} | `false` | One or more alias paths for the route. Useful for supporting multiple URLs. | +| `redirect` | `RouteLocationRaw`{lang="ts"} | `false` | Redirect rule for the route. Supports named routes, objects, or string paths. | +| `children` | `NuxtPage[]`{lang="ts"} | `false` | Nested child routes under this route for layout or view nesting. | -A route pattern to match against. - -#### `rule` - -**Type**: `NitroRouteConfig` - -**Required**: `true` - -A route configuration to apply to the matched route. +## `extendRouteRules` -#### `options` +Nuxt is powered by the [Nitro](https://nitro.unjs.io) server engine. With Nitro, you can incorporate high-level logic directly into your configuration, which is useful for actions like redirects, proxying, caching, and appending headers to routes. This configuration works by associating route patterns with specific route settings. -**Type**: `ExtendRouteRulesOptions` +::tip +You can read more about Nitro route rules in the [Nitro documentation](https://nitro.unjs.io/guide/routing#route-rules). +:: -**Default**: `{}` +::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/adding-route-rules-and-route-middlewares?friend=nuxt" target="_blank"} +Watch Vue School video about adding route rules and route middelwares. +:: -Options to pass to the route configuration. If `override` is set to `true`, it will override the existing route configuration. +### Usage -### Examples - -```ts -// https://github.com/directus/website/blob/main/modules/redirects.ts -import { createResolver, defineNuxtModule, extendRouteRules, extendPages } from '@nuxt/kit' +```ts twoslash +import { createResolver, defineNuxtModule, extendPages, extendRouteRules } from '@nuxt/kit' export default defineNuxtModule({ - setup(options) { - const resolver = createResolver(import.meta.url) + setup (options) { + const { resolve } = createResolver(import.meta.url) extendPages((pages) => { pages.unshift({ name: 'preview-new', path: '/preview-new', - file: resolver.resolve('runtime/preview.vue') - }) + file: resolve('runtime/preview.vue'), + }) }) extendRouteRules('/preview', { redirect: { to: '/preview-new', - statusCode: 302 - } + statusCode: 302, + }, }) extendRouteRules('/preview-new', { cache: { - maxAge: 60 * 60 * 24 * 7 - } + maxAge: 60 * 60 * 24 * 7, + }, }) - } + }, }) ``` -## `addRouteMiddleware` - -Registers route middlewares to be available for all routes or for specific routes. - -Route middlewares can be also defined in plugins via [`addRouteMiddleware`](/docs/api/utils/add-route-middleware) composable. - -::tip -Read more about route middlewares in the [Route middleware documentation](/docs/getting-started/routing#route-middleware). -:: - -::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/adding-route-rules-and-route-middlewares?friend=nuxt" target="_blank"} -Watch Vue School video about adding route rules and route middelwares. -:: - ### Type ```ts -function addRouteMiddleware (input: NuxtMiddleware | NuxtMiddleware[], options: AddRouteMiddlewareOptions): void - -type NuxtMiddleware = { - name: string - path: string - global?: boolean -} - -interface AddRouteMiddlewareOptions { - override?: boolean - prepend?: boolean -} +function extendRouteRules(route: string, rule: NitroRouteConfig, options?: ExtendRouteRulesOptions): void ``` ### Parameters -#### `input` - -**Type**: `NuxtMiddleware | NuxtMiddleware[]` - -**Required**: `true` - -A middleware object or an array of middleware objects with the following properties: - -- `name` (required) - - **Type**: `string` - - Middleware name. - -- `path` (required) - - **Type**: `string` - - Path to the middleware. +**route**: A route pattern to match against.\ +**rule**: A route rule configuration to apply to the matched route. -- `global` (optional) - - **Type**: `boolean` - - If enabled, registers middleware to be available for all routes. - -#### `options` +::tip +About route rules configurations, you can get more detail in [Hybrid Rendering > Route Rules](/docs/guide/concepts/rendering#route-rules). +:: -**Type**: `AddRouteMiddlewareOptions` +**options**: A object to pass to the route configuration. If `override` is set to `true`, it will override the existing route configuration. -**Default**: `{}` +| Name | Type | Default | Description | +| ---------- | --------- | ------- | -------------------------------------------- | +| `override` | `boolean` | `false` | Override route rule config, default is false | -- `override` (optional) +## `addRouteMiddleware` - **Type**: `boolean` +Registers route middlewares to be available for all routes or for specific routes. - **Default**: `false` +Route middlewares can be also defined in plugins via [`addRouteMiddleware`](/docs/api/utils/add-route-middleware) composable. - If enabled, overrides the existing middleware with the same name. +::tip +Read more about route middlewares in the [Route middleware documentation](/docs/getting-started/routing#route-middleware). +:: -- `prepend` (optional) +::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/adding-route-rules-and-route-middlewares?friend=nuxt" target="_blank"} +Watch Vue School video about adding route rules and route middelwares. +:: - **Type**: `boolean` +### Usage - **Default**: `false` +::code-group - If enabled, prepends the middleware to the list of existing middleware. +```ts twoslash [module.ts] +import { addRouteMiddleware, createResolver, defineNuxtModule } from '@nuxt/kit' -### Examples +export default defineNuxtModule({ + setup () { + const { resolve } = createResolver(import.meta.url) -::code-group + addRouteMiddleware({ + name: 'auth', + path: resolve('runtime/auth.ts'), + global: true, + }, { prepend: true }) + }, +}) +``` -```ts [runtime/auth.ts] +```ts twoslash [runtime/auth.ts] export default defineNuxtRouteMiddleware((to, from) => { // isAuthenticated() is an example method verifying if a user is authenticated if (to.path !== '/login' && isAuthenticated() === false) { @@ -276,20 +165,27 @@ export default defineNuxtRouteMiddleware((to, from) => { }) ``` -```ts [module.ts] -import { createResolver, defineNuxtModule, addRouteMiddleware } from '@nuxt/kit' +:: -export default defineNuxtModule({ - setup() { - const resolver = createResolver(import.meta.url) +### Type - addRouteMiddleware({ - name: 'auth', - path: resolver.resolve('runtime/auth.ts'), - global: true - }, { prepend: true }) - } -}) +```ts +function addRouteMiddleware(input: NuxtMiddleware | NuxtMiddleware[], options?: AddRouteMiddlewareOptions): void ``` -:: +### Parameters + +**input**: A middleware object or an array of middleware objects with the following properties: + +| Property | Type | Required | Description | +| -------- | --------- | -------- | --------------------------------------------------- | +| `name` | `string` | `true` | The name of the middleware. | +| `path` | `string` | `true` | The file path to the middleware. | +| `global` | `boolean` | `false` | If set to `true`, applies middleware to all routes. | + +**options**: An object with the following properties: + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ----------------------------------------------------------- | +| `override` | `boolean` | `false` | If `true`, replaces middleware with the same name. | +| `prepend` | `boolean` | `false` | If `true`, prepends middleware before existing middlewares. | diff --git a/docs/3.api/5.kit/8.layout.md b/docs/3.api/5.kit/8.layout.md index 9bf3ef78d2b0..1eaa8d9c7fe4 100644 --- a/docs/3.api/5.kit/8.layout.md +++ b/docs/3.api/5.kit/8.layout.md @@ -18,63 +18,82 @@ Register template as layout and add it to the layouts. In Nuxt 2 `error` layout can also be registered using this utility. In Nuxt 3+ `error` layout [replaced](/docs/getting-started/error-handling#rendering-an-error-page) with `error.vue` page in project root. :: -### Type - -```ts -function addLayout (layout: NuxtTemplate | string, name: string): void - -interface NuxtTemplate { - src?: string - filename?: string - dst?: string - options?: Record - getContents?: (data: Record) => string | Promise - write?: boolean -} -``` - -### Parameters - -#### `layout` - -**Type**: `NuxtTemplate | string` - -**Required**: `true` - -A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: - -- `src` (optional) - - **Type**: `string` - - Path to the template. If `src` is not provided, `getContents` must be provided instead. +### Usage -- `filename` (optional) +```ts twoslash +import { addLayout, createResolver, defineNuxtModule } from '@nuxt/kit' - **Type**: `string` +export default defineNuxtModule({ + setup () { + const { resolve } = createResolver(import.meta.url) - Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. - -- `dst` (optional) - - **Type**: `string` - - Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. - -- `options` (optional) + addLayout({ + src: resolve('templates/custom-layout.ts'), + filename: 'custom-layout.ts', + }, 'custom') + }, +}) +``` - **Type**: `Options` +### Type - Options to pass to the template. +```ts +function addLayout(layout: NuxtTemplate | string, name: string): void +``` -- `getContents` (optional) +### Parameters - **Type**: `(data: Options) => string | Promise` +**`layout`**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties: + +| Property | Type | Required | Description | +| ------------- | ------------------------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `src` | `string` | `false` | Path to the template. If `src` is not provided, `getContents` must be provided instead. | +| `filename` | `string` | `false` | Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. | +| `dst` | `string` | `false` | Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. | +| `options` | `Record`{lang="ts"} | `false` | Options to pass to the template. | +| `getContents` | `(data) => string \| Promise`{lang="ts"} | `false` | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. | +| `write` | `boolean` | `false` | If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. | + +**`name`**: The name to register the layout under (e.g., `default`, `custom`, etc.). + +### Example + +This will register a layout named `custom` that wraps pages with a header and footer. + +```ts twoslash +import { addLayout, defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + setup () { + addLayout({ + write: true, + filename: 'my-layout.vue', + getContents: () => ``, + }, 'custom') + }, +}) +``` - A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. +You can then use this layout in your pages: -- `write` (optional) +```vue [pages/about.vue] + - **Type**: `boolean` + +``` - If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. +::warning +Due to the lack of support for virtual `.vue` files by `@vitejs/plugin-vue`, you can work around this limitation by passing `write: true` to the first argument of `addLayout`. +:: diff --git a/docs/3.api/5.kit/9.plugins.md b/docs/3.api/5.kit/9.plugins.md index 9e1df7928bba..820b99c6302a 100644 --- a/docs/3.api/5.kit/9.plugins.md +++ b/docs/3.api/5.kit/9.plugins.md @@ -8,95 +8,81 @@ links: size: xs --- -Plugins are self-contained code that usually add app-level functionality to Vue. In Nuxt, plugins are automatically imported from the `plugins` directory. However, if you need to ship a plugin with your module, Nuxt Kit provides the `addPlugin` and `addPluginTemplate` methods. These utils allow you to customize the plugin configuration to better suit your needs. +Plugins are self-contained code that usually add app-level functionality to Vue. In Nuxt, plugins are automatically imported from the `plugins/` directory. However, if you need to ship a plugin with your module, Nuxt Kit provides the `addPlugin` and `addPluginTemplate` methods. These utils allow you to customize the plugin configuration to better suit your needs. ## `addPlugin` -Registers a Nuxt plugin and to the plugins array. +Registers a Nuxt plugin and adds it to the plugins array. ::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/injecting-plugins?friend=nuxt" target="_blank"} -Watch Vue School video about addPlugin. +Watch Vue School video about `addPlugin`. :: -### Type +### Usage -```ts -function addPlugin (plugin: NuxtPlugin | string, options: AddPluginOptions): NuxtPlugin +```ts twoslash +import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit' -interface NuxtPlugin { - src: string - mode?: 'all' | 'server' | 'client' - order?: number -} +export default defineNuxtModule({ + setup () { + const { resolve } = createResolver(import.meta.url) -interface AddPluginOptions { append?: boolean } + addPlugin({ + src: resolve('runtime/plugin.js'), + mode: 'client', + }) + }, +}) ``` -### Parameters - -#### `plugin` - -**Type**: `NuxtPlugin | string` - -**Required**: `true` - -A plugin object or a string with the path to the plugin. If a string is provided, it will be converted to a plugin object with `src` set to the string value. If a plugin object is provided, it must have the following properties: - -- `src` (required) - - **Type**: `string` - - Path to the plugin. - -- `mode` (optional) - - **Type**: `'all' | 'server' | 'client'` - - **Default**: `'all'` +### Type - If set to `'all'`, the plugin will be included in both client and server bundles. If set to `'server'`, the plugin will only be included in the server bundle. If set to `'client'`, the plugin will only be included in the client bundle. You can also use `.client` and `.server` modifiers when specifying `src` option to use plugin only in client or server side. +```ts +function addPlugin(plugin: NuxtPlugin | string, options?: AddPluginOptions): NuxtPlugin +``` -- `order` (optional) +### Parameters - **Type**: `number` +**`plugin`**: A plugin object or a string with the path to the plugin. If a string is provided, it will be converted to a plugin object with `src` set to the string value. - **Default**: `0` +If a plugin object is provided, it must have the following properties: - Order of the plugin. This allows more granular control over plugin order and should only be used by advanced users. Lower numbers run first, and user plugins default to `0`. It's recommended to set `order` to a number between `-20` for `pre`-plugins (plugins that run before Nuxt plugins) and `20` for `post`-plugins (plugins that run after Nuxt plugins). +| Property | Type | Required | Description | +| -------- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `src` | `string` | `true` | Path to the plugin file. | +| `mode` | `'all' \| 'server' \| 'client'`{lang="ts"} | `false` | If set to `'all'`, the plugin will be included in both client and server bundles. If set to `'server'`, the plugin will only be included in the server bundle. If set to `'client'`, the plugin will only be included in the client bundle. You can also use `.client` and `.server` modifiers when specifying `src` option to use plugin only in client or server side. | +| `order` | `number` | `false` | Order of the plugin. This allows more granular control over plugin order and should only be used by advanced users. Lower numbers run first, and user plugins default to `0`. It's recommended to set `order` to a number between `-20` for `pre`-plugins (plugins that run before Nuxt plugins) and `20` for `post`-plugins (plugins that run after Nuxt plugins). | ::warning -Don't use `order` unless you know what you're doing. For most plugins, the default `order` of `0` is sufficient. To append a plugin to the end of the plugins array, use the `append` option instead. +Avoid using `order` unless necessary. Use `append` if you simply need to register plugins after Nuxt defaults. :: -#### `options` - -**Type**: `AddPluginOptions` +**`options`**: Optional object with the following properties: -**Default**: `{}` - -Options to pass to the plugin. If `append` is set to `true`, the plugin will be appended to the plugins array instead of prepended. +| Property | Type | Required | Description | +| -------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------- | +| `append` | `boolean` | `false` | If `true`, the plugin will be appended to the plugins array. If `false`, it will be prepended. Defaults to `false`. | ### Examples ::code-group ```ts [module.ts] -import { createResolver, defineNuxtModule, addPlugin } from '@nuxt/kit' +import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ - setup() { - const resolver = createResolver(import.meta.url) + setup () { + const { resolve } = createResolver(import.meta.url) addPlugin({ - src: resolver.resolve('runtime/plugin.js'), - mode: 'client' + src: resolve('runtime/plugin.js'), + mode: 'client', }) - } + }, }) ``` -```ts [runtime/plugin.js] -// https://github.com/nuxt/nuxters +```ts [runtime/plugin.ts] export default defineNuxtPlugin((nuxtApp) => { const colorMode = useColorMode() @@ -115,139 +101,150 @@ export default defineNuxtPlugin((nuxtApp) => { Adds a template and registers as a nuxt plugin. This is useful for plugins that need to generate code at build time. ::tip{icon="i-lucide-video" to="https://vueschool.io/lessons/injecting-plugin-templates?friend=nuxt" target="_blank"} -Watch Vue School video about addPluginTemplate. +Watch Vue School video about `addPluginTemplate`. :: +### Usage + +```ts twoslash +import { addPluginTemplate, defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + setup (options) { + addPluginTemplate({ + filename: 'module-plugin.mjs', + getContents: () => `import { defineNuxtPlugin } from '#app/nuxt' +export default defineNuxtPlugin({ + name: 'module-plugin', + setup (nuxtApp) { + ${options.log ? 'console.log("Plugin install")' : ''} + } +})`, + }) + }, +}) +``` + ### Type ```ts -function addPluginTemplate (pluginOptions: NuxtPluginTemplate, options: AddPluginOptions): NuxtPlugin - -interface NuxtPluginTemplate> { - src?: string, - filename?: string, - dst?: string, - mode?: 'all' | 'server' | 'client', - options?: Options, - getContents?: (data: Options) => string | Promise, - write?: boolean, - order?: number -} - -interface AddPluginOptions { append?: boolean } - -interface NuxtPlugin { - src: string - mode?: 'all' | 'server' | 'client' - order?: number -} +function addPluginTemplate(pluginOptions: NuxtPluginTemplate, options?: AddPluginOptions): NuxtPlugin ``` ### Parameters -#### `pluginOptions` - -**Type**: `NuxtPluginTemplate` - -**Required**: `true` - -A plugin template object with the following properties: - -- `src` (optional) +**`pluginOptions`**: A plugin template object with the following properties: - **Type**: `string` +| Property | Type | Required | Description | +| ------------- | --------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `src` | `string` | `false` | Path to the template. If `src` is not provided, `getContents` must be provided instead. | +| `filename` | `string` | `false` | Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. | +| `dst` | `string` | `false` | Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. | +| `mode` | `'all' \| 'server' \| 'client'`{lang="ts"} | `false` | If set to `'all'`, the plugin will be included in both client and server bundles. If set to `'server'`, the plugin will only be included in the server bundle. If set to `'client'`, the plugin will only be included in the client bundle. You can also use `.client` and `.server` modifiers when specifying `src` option to use plugin only in client or server side. | +| `options` | `Record`{lang="ts"} | `false` | Options to pass to the template. | +| `getContents` | `(data: Record) => string \| Promise`{lang="ts"} | `false` | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. | +| `write` | `boolean` | `false` | If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. | +| `order` | `number` | `false` | Order of the plugin. This allows more granular control over plugin order and should only be used by advanced users. Lower numbers run first, and user plugins default to `0`. It's recommended to set `order` to a number between `-20` for `pre`-plugins (plugins that run before Nuxt plugins) and `20` for `post`-plugins (plugins that run after Nuxt plugins). | - Path to the template. If `src` is not provided, `getContents` must be provided instead. - -- `filename` (optional) - - **Type**: `string` - - Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required. - -- `dst` (optional) - - **Type**: `string` - - Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option. - -- `mode` (optional) - - **Type**: `'all' | 'server' | 'client'` - - **Default**: `'all'` - - If set to `'all'`, the plugin will be included in both client and server bundles. If set to `'server'`, the plugin will only be included in the server bundle. If set to `'client'`, the plugin will only be included in the client bundle. You can also use `.client` and `.server` modifiers when specifying `src` option to use plugin only in client or server side. - -- `options` (optional) - - **Type**: `Options` +::warning +Prefer using `getContents` for dynamic plugin generation. Avoid setting `order` unless necessary. +:: - Options to pass to the template. +**`options`**: Optional object with the following properties: -- `getContents` (optional) +| Property | Type | Required | Description | +| -------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------- | +| `append` | `boolean` | `false` | If `true`, the plugin will be appended to the plugins array. If `false`, it will be prepended. Defaults to `false`. | - **Type**: `(data: Options) => string | Promise` +### Examples - A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. +#### Generate a plugin template with different options -- `write` (optional) +Use `addPluginTemplate` when you need to generate plugin code dynamically at build time. This allows you to generate different plugin contents based on the options passed to it. For example, Nuxt internally uses this function to generate Vue app configurations. - **Type**: `boolean` +```ts twoslash [module.ts] +import { addPluginTemplate, defineNuxtModule } from '@nuxt/kit' - If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem. +export default defineNuxtModule({ + setup (_, nuxt) { + if (nuxt.options.vue.config && Object.values(nuxt.options.vue.config).some(v => v !== null && v !== undefined)) { + addPluginTemplate({ + filename: 'vue-app-config.mjs', + write: true, + getContents: () => `import { defineNuxtPlugin } from '#app/nuxt' +export default defineNuxtPlugin({ + name: 'nuxt:vue-app-config', + enforce: 'pre', + setup (nuxtApp) { + ${Object.keys(nuxt.options.vue.config!) + .map(k => `nuxtApp.vueApp.config[${JSON.stringify(k)}] = ${JSON.stringify(nuxt.options.vue.config![k as 'idPrefix'])}`) + .join('\n') + } + } +})`, + }) + } + }, +}) +``` -- `order` (optional) +This generates different plugin code depending on the provided configuration. - **Type**: `number` +::code-group - **Default**: `0` +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + vue: { + config: { + idPrefix: 'nuxt', + }, + }, +}) +``` - Order of the plugin. This allows more granular control over plugin order and should only be used by advanced users. Lower numbers run first, and user plugins default to `0`. It's recommended to set `order` to a number between `-20` for `pre`-plugins (plugins that run before Nuxt plugins) and `20` for `post`-plugins (plugins that run after Nuxt plugins). +```ts [#build/vue-app-config.mjs] +import { defineNuxtPlugin } from '#app/nuxt' +export default defineNuxtPlugin({ + name: 'nuxt:vue-app-config', + enforce: 'pre', + setup (nuxtApp) { + nuxtApp.vueApp.config["idPrefix"] = "nuxt" + } +}) +``` -::warning -Don't use `order` unless you know what you're doing. For most plugins, the default `order` of `0` is sufficient. To append a plugin to the end of the plugins array, use the `append` option instead. :: -#### `options` +#### Using an EJS template to generate a plugin -**Type**: `AddPluginOptions` - -**Default**: `{}` - -Options to pass to the plugin. If `append` is set to `true`, the plugin will be appended to the plugins array instead of prepended. - -### Examples +You can also use an EJS template to generate your plugin. Options can be passed through the `options` property and then used within the EJS template to generate the plugin content. ::code-group ```ts [module.ts] -// https://github.com/vuejs/vuefire -import { createResolver, defineNuxtModule, addPluginTemplate } from '@nuxt/kit' +import { addPluginTemplate, createResolver, defineNuxtModule } from '@nuxt/kit' export default defineNuxtModule({ - setup() { - const resolver = createResolver(import.meta.url) + setup (options, nuxt) { + const { resolve } = createResolver(import.meta.url) addPluginTemplate({ - src: resolve(templatesDir, 'plugin.ejs'), + src: resolve('templates/plugin.ejs'), filename: 'plugin.mjs', options: { - ...options, ssr: nuxt.options.ssr, }, }) - } + }, }) ``` -```ts [runtime/plugin.ejs] +```ts [templates/plugin.ejs] import { VueFire, useSSRInitialState } from 'vuefire' import { defineNuxtPlugin } from '#imports' export default defineNuxtPlugin((nuxtApp) => { const firebaseApp = nuxtApp.$firebaseApp - nuxtApp.vueApp.use(VueFire, { firebaseApp }) <% if(options.ssr) { %> @@ -261,3 +258,7 @@ export default defineNuxtPlugin((nuxtApp) => { ``` :: + +::warning +If you set `compatibilityVersion` to `4`, Nuxt no longer uses `lodash.template` to compile templates by default. You can still enable it via the `experimental.compileTemplate` option, but support for EJS templates will be removed entirely in the next major version. +:: From b0eb9c79e304c559ee22471c0d367cb726e92d7f Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 2 May 2025 09:07:17 +0100 Subject: [PATCH 16/30] fix(nuxt): short circuit middleware when validate returns false (#31967) --- docs/1.getting-started/07.routing.md | 2 +- .../nuxt/src/pages/runtime/plugins/router.ts | 3 +- packages/nuxt/src/pages/runtime/validate.ts | 36 +++++++------------ .../basic/pages/catchall/[...slug].vue | 9 ++++- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/docs/1.getting-started/07.routing.md b/docs/1.getting-started/07.routing.md index 01a14b299cdf..6d3271cce52f 100644 --- a/docs/1.getting-started/07.routing.md +++ b/docs/1.getting-started/07.routing.md @@ -131,7 +131,7 @@ definePageMeta({ Nuxt offers route validation via the `validate` property in [`definePageMeta()`](/docs/api/utils/define-page-meta) in each page you wish to validate. -The `validate` property accepts the `route` as an argument. You can return a boolean value to determine whether or not this is a valid route to be rendered with this page. If you return `false`, and another match can't be found, this will cause a 404 error. You can also directly return an object with `statusCode`/`statusMessage` to respond immediately with an error (other matches will not be checked). +The `validate` property accepts the `route` as an argument. You can return a boolean value to determine whether or not this is a valid route to be rendered with this page. If you return `false`, this will cause a 404 error. You can also directly return an object with `statusCode`/`statusMessage` to customize the error returned. If you have a more complex use case, then you can use anonymous route middleware instead. diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index b3e32aa09104..03234281d76c 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -2,7 +2,6 @@ import { isReadonly, reactive, shallowReactive, shallowRef } from 'vue' import type { Ref } from 'vue' import type { RouteLocation, RouteLocationNormalizedLoaded, Router, RouterScrollBehavior } from 'vue-router' import { START_LOCATION, createMemoryHistory, createRouter, createWebHashHistory, createWebHistory } from 'vue-router' -import { createError } from 'h3' import { isSamePath, withoutBase } from 'ufo' import type { Plugin, RouteMiddleware } from 'nuxt/app' @@ -12,7 +11,7 @@ import { toArray } from '../utils' import { getRouteRules } from '#app/composables/manifest' import { defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt' -import { clearError, isNuxtError, showError, useError } from '#app/composables/error' +import { clearError, createError, isNuxtError, showError, useError } from '#app/composables/error' import { navigateTo } from '#app/composables/router' // @ts-expect-error virtual file diff --git a/packages/nuxt/src/pages/runtime/validate.ts b/packages/nuxt/src/pages/runtime/validate.ts index 263eab3cdc62..0dbfbcaad3fe 100644 --- a/packages/nuxt/src/pages/runtime/validate.ts +++ b/packages/nuxt/src/pages/runtime/validate.ts @@ -1,39 +1,29 @@ -import { createError, showError } from '#app/composables/error' -import { useNuxtApp } from '#app/nuxt' -import { defineNuxtRouteMiddleware, useRouter } from '#app/composables/router' +import { createError } from '#app/composables/error' +import { defineNuxtRouteMiddleware } from '#app/composables/router' -export default defineNuxtRouteMiddleware(async (to) => { +export default defineNuxtRouteMiddleware(async (to, from) => { if (!to.meta?.validate) { return } - const nuxtApp = useNuxtApp() - const router = useRouter() - const result = await Promise.resolve(to.meta.validate(to)) if (result === true) { return } const error = createError({ + fatal: import.meta.client, statusCode: (result && result.statusCode) || 404, statusMessage: (result && result.statusMessage) || `Page Not Found: ${to.fullPath}`, data: { path: to.fullPath, }, }) - const unsub = router.beforeResolve((final) => { - unsub() - if (final === to) { - const unsub = router.afterEach(async () => { - unsub() - await nuxtApp.runWithContext(() => showError(error)) - // We pretend to have navigated to the invalid route so - // that the user can return to the previous page with - // the back button. - window?.history.pushState({}, '', to.fullPath) - }) - // We stop the navigation immediately before it resolves - // if there is no other route matching it. - return false - } - }) + + // We pretend to have navigated to the invalid route so + // that the user can return to the previous page with + // the back button. + if (typeof window !== 'undefined') { + window.history.pushState({}, '', from.fullPath) + } + + return error }) diff --git a/test/fixtures/basic/pages/catchall/[...slug].vue b/test/fixtures/basic/pages/catchall/[...slug].vue index 1af000b72bb3..cb4a895ecf0f 100644 --- a/test/fixtures/basic/pages/catchall/[...slug].vue +++ b/test/fixtures/basic/pages/catchall/[...slug].vue @@ -8,7 +8,14 @@