diff --git a/packages/nuxt/src/components/islandsTransform.ts b/packages/nuxt/src/components/islandsTransform.ts
index da41e693d..583ed724c 100644
--- a/packages/nuxt/src/components/islandsTransform.ts
+++ b/packages/nuxt/src/components/islandsTransform.ts
@@ -108,13 +108,20 @@ export const islandsTransform = createUnplugin((options: ServerOnlyComponentTran
s.appendRight(startingIndex + loc[1].end, '')
} else if (options.selectiveClient && ('nuxt-client' in node.attributes || ':nuxt-client' in node.attributes)) {
hasNuxtClient = true
- const attributeValue = node.attributes[':nuxt-client'] || node.attributes['nuxt-client'] || 'true'
+ const { loc, attributes } = node
+ const attributeValue = attributes[':nuxt-client'] || attributes['nuxt-client'] || 'true'
if (isVite) {
- // handle granular interactivity
- const htmlCode = code.slice(startingIndex + node.loc[0].start, startingIndex + node.loc[1].end)
const uid = hash(id + node.loc[0].start + node.loc[0].end)
+ const wrapperAttributes = extractAttributes(attributes, ['v-if', 'v-else-if', 'v-else'])
- s.overwrite(startingIndex + node.loc[0].start, startingIndex + node.loc[1].end, `${htmlCode.replaceAll(NUXTCLIENT_ATTR_RE, '')}`)
+ let startTag = code.slice(startingIndex + loc[0].start, startingIndex + loc[0].end).replace(NUXTCLIENT_ATTR_RE, '')
+ if (wrapperAttributes) {
+ startTag = startTag.replaceAll(EXTRACTED_ATTRS_RE, '')
+ }
+
+ s.appendLeft(startingIndex + loc[0].start, ``)
+ s.overwrite(startingIndex + loc[0].start, startingIndex + loc[0].end, startTag)
+ s.appendRight(startingIndex + loc[1].end, '')
}
}
}
diff --git a/packages/nuxt/test/islandTransform.test.ts b/packages/nuxt/test/islandTransform.test.ts
index 128d63741..78027d84a 100644
--- a/packages/nuxt/test/islandTransform.test.ts
+++ b/packages/nuxt/test/islandTransform.test.ts
@@ -380,6 +380,31 @@ describe('islandTransform - server and island components', () => {
`)
expect(result).toContain('import NuxtTeleportIslandComponent from \'#app/components/nuxt-teleport-island-component\'')
})
+
+ it('should move v-if to the wrapper component', async () => {
+ const result = await viteTransform(`
+
+
+
+
+
+
+ `, 'hello.server.vue', false, true)
+
+ expect(result).toMatchInlineSnapshot(`
+ "
+
+
+
+
+
+
+ "
+ `)
+ })
})
describe('webpack', () => {