diff --git a/packages/nuxt/src/components/loader.ts b/packages/nuxt/src/components/loader.ts index 7017440611ce..46fc26448034 100644 --- a/packages/nuxt/src/components/loader.ts +++ b/packages/nuxt/src/components/loader.ts @@ -48,7 +48,7 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => { let identifier = map.get(component) || `__nuxt_component_${num++}` map.set(component, identifier) - const isServerOnly = component.mode === 'server' && + const isServerOnly = !component._raw && component.mode === 'server' && !components.some(c => c.pascalName === component.pascalName && c.mode === 'client') if (isServerOnly) { imports.add(genImport(serverComponentRuntime, [{ name: 'createServerComponent' }])) @@ -59,7 +59,7 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => { return identifier } - const isClientOnly = component.mode === 'client' && component.pascalName !== 'NuxtClientFallback' + const isClientOnly = !component._raw && component.mode === 'client' if (isClientOnly) { imports.add(genImport('#app/components/client-only', [{ name: 'createClientOnly' }])) identifier += '_client' diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts index 4c5a8f984695..9a3cfd92798b 100644 --- a/packages/nuxt/src/components/module.ts +++ b/packages/nuxt/src/components/module.ts @@ -170,6 +170,7 @@ export default defineNuxtModule({ if (component.mode === 'client' && !newComponents.some(c => c.pascalName === component.pascalName && c.mode === 'server')) { newComponents.push({ ...component, + _raw: true, mode: 'server', filePath: resolve(distDir, 'app/components/server-placeholder'), chunkName: 'components/' + component.kebabName diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 150217f04697..2f00eb74001d 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -265,6 +265,7 @@ async function initNuxt (nuxt: Nuxt) { if (nuxt.options.experimental.clientFallback) { addComponent({ name: 'NuxtClientFallback', + _raw: true, priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, 'components/client-fallback.client'), mode: 'client' @@ -272,6 +273,7 @@ async function initNuxt (nuxt: Nuxt) { addComponent({ name: 'NuxtClientFallback', + _raw: true, priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, 'components/client-fallback.server'), mode: 'server' diff --git a/packages/schema/src/types/components.ts b/packages/schema/src/types/components.ts index 010fae5ef08a..6290f4961e6f 100644 --- a/packages/schema/src/types/components.ts +++ b/packages/schema/src/types/components.ts @@ -16,6 +16,13 @@ export interface Component { * components will be used instead of lower priority components. */ priority?: number + /** + * Allow bypassing client/server transforms for internal Nuxt components like + * ServerPlaceholder and NuxtClientFallback. + * + * @internal + */ + _raw?: boolean } export interface ScanDir {