N
Nuxt2mo ago
Tom

resolveComponent not working as expected

const formatBlockName = (): string => {
const type = props.data.blockType as string;
const typeFormatted = type.slice(0, 1).toUpperCase() + type.slice(1);
return `Block${typeFormatted}`;
};

const blockName = formatBlockName();
const formatBlockName = (): string => {
const type = props.data.blockType as string;
const typeFormatted = type.slice(0, 1).toUpperCase() + type.slice(1);
return `Block${typeFormatted}`;
};

const blockName = formatBlockName();
Returns BlockContentSection
const Block = resolveComponent(blockName);
const Block2 = resolveComponent('BlockContentSection');
const Block = resolveComponent(blockName);
const Block2 = resolveComponent('BlockContentSection');
Block2 renders Block gives error Failed to resolve component: BlockContentSection The template code is
<component :is="Block" :data />
<component :is="Block2" :data />
<component :is="Block" :data />
<component :is="Block2" :data />
I'm unsure why this is happening. Why Block doesn't and Block2 does, other than it will only accept a direct string in to resolveComponents but that defeats the purpose of them being dynamic.
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @Tom. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You're encountering a common issue with resolveComponent in Nuxt. The function resolveComponent in Nuxt works differently than in plain Vue and has a specific limitation: it cannot accept variables as arguments. According to the knowledge sources, resolveComponent only works with string literals, not with variables:
<template>
<component :is="resolveComponent(aVariableThatHoldsComponentName)" />
This is Not OK ❌

<component :is="resolveComponent('MyComponent')" />
This is OK ✅
</template>
<template>
<component :is="resolveComponent(aVariableThatHoldsComponentName)" />
This is Not OK ❌

<component :is="resolveComponent('MyComponent')" />
This is OK ✅
</template>
Stack Overflow: Nuxt3 dynamic component explains this limitation clearly. This happens because Nuxt's auto-import system works at build time, not runtime. When you use resolveComponent('BlockContentSection'), Nuxt can statically analyze your code and include that component. But when you use a variable like blockName, Nuxt can't determine at build time which component you'll need. Solutions There are several ways to handle dynamic components in Nuxt: 1. Use a component map:
const componentMap = {
BlockContentSection: resolveComponent('BlockContentSection'),
BlockOtherType: resolveComponent('BlockOtherType')
}

// Then in your template
<component :is="componentMap[blockName]" :data />

const componentMap = {
BlockContentSection: resolveComponent('BlockContentSection'),
BlockOtherType: resolveComponent('BlockOtherType')
}

// Then in your template
<component :is="componentMap[blockName]" :data />

2. Use global components: If your components are registered globally (either by placing them in components/global/ or using .global.vue suffix), you can directly use:
<component :is="blockName" :data />

<component :is="blockName" :data />

However, this approach has performance implications as noted in the Nuxt documentation. 3. Import components directly:
import { BlockContentSection } from '#components'

// Then conditionally assign the component
const Block = computed(() => {
if (blockName === 'BlockContentSection') return BlockContentSection
// other conditions...
})

import { BlockContentSection } from '#components'

// Then conditionally assign the component
const Block = computed(() => {
if (blockName === 'BlockContentSection') return BlockContentSection
// other conditions...
})

Daniel Roe, a Nuxt team member, has created a short video about resolveComponent that explains why it works differently in Nuxt compared to plain Vue. For more flexible dynamic component handling, you might want to watch this detailed video on dynamic components in Vue/Nuxt which covers three different approaches to implementing dynamic components. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@545621973364113419> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?