diff --git a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts
index 2fde4560e..04ebb890a 100644
--- a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts
+++ b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts
@@ -51,6 +51,31 @@ describe('ssr: components', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.foo), _mergeProps({ prop: "b" }, _attrs), null), _parent)
}"
`)
+
+ expect(
+ compile(
+ ``,
+ ).code,
+ ).toMatchInlineSnapshot(`
+ "const { resolveDynamicComponent: _resolveDynamicComponent, mergeProps: _mergeProps, createVNode: _createVNode } = require("vue")
+ const { ssrRenderVNode: _ssrRenderVNode } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("div"), _mergeProps({ innerHTML: '
ssr dynamic component v-html
' }, _attrs), null), _parent)
+ }"
+ `)
+
+ expect(
+ compile(``)
+ .code,
+ ).toMatchInlineSnapshot(`
+ "const { resolveDynamicComponent: _resolveDynamicComponent, mergeProps: _mergeProps, createVNode: _createVNode } = require("vue")
+ const { ssrRenderVNode: _ssrRenderVNode } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("div"), _mergeProps({ textContent: 'ssr dynamic component v-text' }, _attrs), null), _parent)
+ }"
+ `)
})
describe('slots', () => {
diff --git a/packages/compiler-ssr/src/index.ts b/packages/compiler-ssr/src/index.ts
index f8a686555..d7fb043b9 100644
--- a/packages/compiler-ssr/src/index.ts
+++ b/packages/compiler-ssr/src/index.ts
@@ -27,6 +27,8 @@ import { ssrTransformModel } from './transforms/ssrVModel'
import { ssrTransformShow } from './transforms/ssrVShow'
import { ssrInjectFallthroughAttrs } from './transforms/ssrInjectFallthroughAttrs'
import { ssrInjectCssVars } from './transforms/ssrInjectCssVars'
+import { ssrTransformHtml } from './transforms/ssrVHtml'
+import { ssrTransformText } from './transforms/ssrVText'
export function compile(
source: string | RootNode,
@@ -72,9 +74,11 @@ export function compile(
// reusing core v-bind
bind: transformBind,
on: transformOn,
- // model and show have dedicated SSR handling
+ // model, show, text and html have dedicated SSR handling
model: ssrTransformModel,
show: ssrTransformShow,
+ text: ssrTransformText,
+ html: ssrTransformHtml,
// the following are ignored during SSR
// on: noopDirectiveTransform,
cloak: noopDirectiveTransform,
diff --git a/packages/compiler-ssr/src/transforms/ssrVHtml.ts b/packages/compiler-ssr/src/transforms/ssrVHtml.ts
new file mode 100644
index 000000000..5aa59e0ac
--- /dev/null
+++ b/packages/compiler-ssr/src/transforms/ssrVHtml.ts
@@ -0,0 +1,26 @@
+import {
+ type DirectiveTransform,
+ ElementTypes,
+ createObjectProperty,
+ createSimpleExpression,
+} from '@vue/compiler-core'
+
+export const ssrTransformHtml: DirectiveTransform = (dir, node) => {
+ const { exp, loc } = dir
+
+ if (node.tagType !== ElementTypes.COMPONENT || node.tag !== 'component')
+ return { props: [] }
+
+ if (node.children.length) {
+ node.children.length = 0
+ }
+
+ return {
+ props: [
+ createObjectProperty(
+ createSimpleExpression(`innerHTML`, true, loc),
+ exp || createSimpleExpression('', true),
+ ),
+ ],
+ }
+}
diff --git a/packages/compiler-ssr/src/transforms/ssrVText.ts b/packages/compiler-ssr/src/transforms/ssrVText.ts
new file mode 100644
index 000000000..81c3ebee7
--- /dev/null
+++ b/packages/compiler-ssr/src/transforms/ssrVText.ts
@@ -0,0 +1,37 @@
+import {
+ type DirectiveTransform,
+ ElementTypes,
+ TO_DISPLAY_STRING,
+ createCallExpression,
+ createObjectProperty,
+ createSimpleExpression,
+ getConstantType,
+} from '@vue/compiler-core'
+
+export const ssrTransformText: DirectiveTransform = (dir, node, context) => {
+ const { exp, loc } = dir
+
+ if (node.tagType !== ElementTypes.COMPONENT || node.tag !== 'component')
+ return { props: [] }
+
+ if (node.children.length) {
+ node.children.length = 0
+ }
+
+ return {
+ props: [
+ createObjectProperty(
+ createSimpleExpression(`textContent`, true),
+ exp
+ ? getConstantType(exp, context) > 0
+ ? exp
+ : createCallExpression(
+ context.helperString(TO_DISPLAY_STRING),
+ [exp],
+ loc,
+ )
+ : createSimpleExpression('', true),
+ ),
+ ],
+ }
+}