diff --git a/packages/nuxt/src/components/runtime/server-component.ts b/packages/nuxt/src/components/runtime/server-component.ts index 777204209e..4a308c1b56 100644 --- a/packages/nuxt/src/components/runtime/server-component.ts +++ b/packages/nuxt/src/components/runtime/server-component.ts @@ -7,11 +7,14 @@ export const createServerComponent = (name: string) => { inheritAttrs: false, props: { lazy: Boolean }, setup (props, { attrs, slots }) { - return () => h(NuxtIsland, { - name, - lazy: props.lazy, - props: attrs - }, slots) + return () => { + return h(NuxtIsland, { + name, + lazy: props.lazy, + // #23051 - remove data-v attributes + props: Object.fromEntries(Object.entries(attrs).filter(([key]) => !key.startsWith('data-v-'))) + }, slots) + } } }) } diff --git a/test/nuxt/nuxt-island.test.ts b/test/nuxt/nuxt-island.test.ts new file mode 100644 index 0000000000..90e3a2922b --- /dev/null +++ b/test/nuxt/nuxt-island.test.ts @@ -0,0 +1,41 @@ +import { describe, expect, it, vi } from 'vitest' +import { h } from 'vue' +import { createServerComponent } from '../../packages/nuxt/src/components/runtime/server-component' + +vi.mock('vue', async (original) => { + const vue = await original() + return { + ...vue, + h: vi.fn(vue.h) + } +}) + +describe('runtime server component', () => { + it('expect no data-v- attrbutes #23051', () => { + // @ts-expect-error mock + vi.mocked(h).mockImplementation(() => null) + + // @ts-expect-error test setup + createServerComponent('DummyName').setup!({ + lazy: false + }, { + attrs: { + 'data-v-123': '', + test: 1 + }, + slots: {}, + emit: vi.fn(), + expose: vi.fn() + })() + + expect(h).toHaveBeenCalledOnce() + if (!vi.mocked(h).mock.lastCall) { throw new Error('no last call') } + expect(vi.mocked(h).mock.lastCall![1]?.props).toBeTypeOf('object') + expect(Object.keys(vi.mocked(h).mock.lastCall![1]?.props)).not.toContain('data-v-123') + expect(vi.mocked(h).mock.lastCall![1]?.props).toMatchInlineSnapshot(` + { + "test": 1, + } + `) + }) +})