diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts
index d0a5223b2ff..e0136cb5c97 100644
--- a/packages/server-renderer/__tests__/render.spec.ts
+++ b/packages/server-renderer/__tests__/render.spec.ts
@@ -1229,5 +1229,23 @@ function testRender(type: string, render: typeof renderToString) {
// during the render phase
expect(getterSpy).toHaveBeenCalledTimes(2)
})
+
+ test('props modifiers in render attrs', async () => {
+ const app = createApp({
+ setup() {
+ return () =>
+ h(
+ 'div',
+ {
+ '^attr': 'attr',
+ '.prop': 'prop',
+ },
+ 'Functional Component',
+ )
+ },
+ })
+ const html = await render(app)
+ expect(html).toBe(`
Functional Component
`)
+ })
})
}
diff --git a/packages/server-renderer/src/helpers/ssrRenderAttrs.ts b/packages/server-renderer/src/helpers/ssrRenderAttrs.ts
index b082da03fe8..b031079e92e 100644
--- a/packages/server-renderer/src/helpers/ssrRenderAttrs.ts
+++ b/packages/server-renderer/src/helpers/ssrRenderAttrs.ts
@@ -29,15 +29,19 @@ export function ssrRenderAttrs(
tag?: string,
): string {
let ret = ''
- for (const key in props) {
+ for (let key in props) {
if (
shouldIgnoreProp(key) ||
isOn(key) ||
- (tag === 'textarea' && key === 'value')
+ (tag === 'textarea' && key === 'value') ||
+ // force as property (not rendered in SSR)
+ key.startsWith('.')
) {
continue
}
const value = props[key]
+ // force as attribute
+ if (key.startsWith('^')) key = key.slice(1)
if (key === 'class') {
ret += ` class="${ssrRenderClass(value)}"`
} else if (key === 'style') {