diff --git a/packages/nuxt/src/app/plugins/check-if-layout-used.ts b/packages/nuxt/src/app/plugins/check-if-layout-used.ts
index 9cf7192ea98c..247429681c05 100644
--- a/packages/nuxt/src/app/plugins/check-if-layout-used.ts
+++ b/packages/nuxt/src/app/plugins/check-if-layout-used.ts
@@ -5,6 +5,8 @@ import { useError } from '../composables/error'
// @ts-expect-error virtual file
import layouts from '#build/layouts'
+// @ts-expect-error virtual file
+import { isNuxtLayoutUsed } from '#build/detected-nuxt-layout-usage'
export default defineNuxtPlugin({
name: 'nuxt:checkIfLayoutUsed',
@@ -12,7 +14,7 @@ export default defineNuxtPlugin({
const error = useError()
function checkIfLayoutUsed () {
- if (!error.value && !nuxtApp._isNuxtLayoutUsed && Object.keys(layouts).length > 0) {
+ if (!error.value && !nuxtApp._isNuxtLayoutUsed && !isNuxtLayoutUsed && Object.keys(layouts).length > 0) {
console.warn('[nuxt] Your project has layouts but the `` component has not been used.')
}
}
diff --git a/packages/nuxt/src/components/loader.ts b/packages/nuxt/src/components/loader.ts
index 1f372adfb35e..17daf155c4c0 100644
--- a/packages/nuxt/src/components/loader.ts
+++ b/packages/nuxt/src/components/loader.ts
@@ -5,7 +5,7 @@ import { pascalCase } from 'scule'
import { resolve } from 'pathe'
import type { Component, ComponentsOptions } from 'nuxt/schema'
-import { logger, tryUseNuxt } from '@nuxt/kit'
+import { logger, tryUseNuxt, updateTemplates } from '@nuxt/kit'
import { distDir } from '../dirs'
import { isVue } from '../core/utils'
@@ -15,6 +15,7 @@ interface LoaderOptions {
sourcemap?: boolean
transform?: ComponentsOptions['transform']
experimentalComponentIslands?: boolean
+ detectedComponentsUsage: Record
}
export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
@@ -54,6 +55,8 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
let identifier = map.get(component) || `__nuxt_component_${num++}`
map.set(component, identifier)
+ detectComponentUsage(component, options.detectedComponentsUsage)
+
const isServerOnly = !component._raw && component.mode === 'server' &&
!components.some(c => c.pascalName === component.pascalName && c.mode === 'client')
if (isServerOnly) {
@@ -123,3 +126,12 @@ function findComponent (components: Component[], name: string, mode: LoaderOptio
// and createServerComponent above
return otherModeComponent
}
+
+function detectComponentUsage (component: Component, detectedComponentsUsage: LoaderOptions['detectedComponentsUsage']) {
+ if (process.env.NODE_ENV !== 'development' || !(component.pascalName in detectedComponentsUsage)) { return }
+
+ detectedComponentsUsage[component.pascalName] = true
+ const virtualFilename = `detected-${component.kebabName}-usage.mjs`
+
+ updateTemplates({ filter: template => template.filename === virtualFilename })
+}
diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts
index 52248d0ad16b..821ed3cf2df2 100644
--- a/packages/nuxt/src/components/module.ts
+++ b/packages/nuxt/src/components/module.ts
@@ -211,6 +211,28 @@ export default defineNuxtModule({
}
})
+ const detectedComponentsUsage = {
+ NuxtLayout: false,
+ NuxtPage: false
+ }
+
+ if (process.env.NODE_ENV === 'development') {
+ addTemplate({
+ filename: 'detected-nuxt-layout-usage.mjs',
+ options: detectedComponentsUsage,
+ getContents: data => `
+ export const isNuxtLayoutUsed = ${data.options.NuxtLayout}
+ `
+ })
+ addTemplate({
+ filename: 'detected-nuxt-page-usage.mjs',
+ options: detectedComponentsUsage,
+ getContents: data => `
+ export const isNuxtPageUsed = ${data.options.NuxtPage}
+ `
+ })
+ }
+
nuxt.hook('vite:extendConfig', (config, { isClient, isServer }) => {
const mode = isClient ? 'client' : 'server'
@@ -230,7 +252,8 @@ export default defineNuxtModule({
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
- experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
+ experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
+ detectedComponentsUsage
}))
if (nuxt.options.experimental.componentIslands) {
@@ -299,7 +322,8 @@ export default defineNuxtModule({
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
- experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
+ experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
+ detectedComponentsUsage
}))
if (nuxt.options.experimental.componentIslands) {
diff --git a/packages/nuxt/src/pages/runtime/plugins/check-if-page-unused.ts b/packages/nuxt/src/pages/runtime/plugins/check-if-page-unused.ts
index 57ae91fe6e63..ff747425082f 100644
--- a/packages/nuxt/src/pages/runtime/plugins/check-if-page-unused.ts
+++ b/packages/nuxt/src/pages/runtime/plugins/check-if-page-unused.ts
@@ -3,13 +3,16 @@ import { defineNuxtPlugin } from '#app/nuxt'
import { onNuxtReady } from '#app/composables/ready'
import { useError } from '#app/composables/error'
+// @ts-expect-error virtual file
+import { isNuxtPageUsed } from '#build/detected-nuxt-page-usage'
+
export default defineNuxtPlugin({
name: 'nuxt:checkIfPageUnused',
setup (nuxtApp) {
const error = useError()
function checkIfPageUnused () {
- if (!error.value && !nuxtApp._isNuxtPageUsed) {
+ if (!error.value && !nuxtApp._isNuxtPageUsed && !isNuxtPageUsed) {
console.warn(
'[nuxt] Your project has pages but the `` component has not been used.' +
' You might be using the `` component instead, which will not work correctly in Nuxt.' +