Skip to content

Conversation

linzhe141
Copy link
Contributor

@linzhe141 linzhe141 commented Oct 14, 2024

close #12162

Summary by CodeRabbit

  • Bug Fixes
    • Corrected SSR handling of v-show so visibility is computed reliably with other props.
    • Inline display styles now work as expected alongside v-show; server output applies the intended display with conditional hiding.
    • Adjusted prop processing order to prevent unexpected overrides affecting v-show behavior.
    • Produces more predictable HTML output, aligning SSR results more closely with client-side rendering.

@linzhe141 linzhe141 marked this pull request as draft October 14, 2024 04:17
Copy link

github-actions bot commented Oct 14, 2024

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB 38.5 kB 34.6 kB
vue.global.prod.js 159 kB 58.6 kB 52.1 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.6 kB 18.2 kB 16.7 kB
createApp 54.6 kB 21.3 kB 19.4 kB
createSSRApp 58.9 kB 23 kB 21 kB
defineCustomElement 59.6 kB 22.8 kB 20.9 kB
overall 68.8 kB 26.4 kB 24.2 kB

Copy link

pkg-pr-new bot commented Oct 14, 2024

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@12171

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@12171

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@12171

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@12171

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@12171

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@12171

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@12171

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@12171

@vue/shared

npm i https://pkg.pr.new/@vue/shared@12171

vue

npm i https://pkg.pr.new/vue@12171

@vue/compat

npm i https://pkg.pr.new/@vue/compat@12171

commit: c840515

@linzhe141 linzhe141 closed this Oct 14, 2024
@linzhe141 linzhe141 reopened this Oct 14, 2024
@linzhe141 linzhe141 marked this pull request as ready for review October 14, 2024 06:09
@linzhe141 linzhe141 marked this pull request as draft October 14, 2024 06:52
@linzhe141 linzhe141 marked this pull request as ready for review October 14, 2024 09:14
@edison1105 edison1105 changed the title wip: handle v-show in ssr fix(ssr): v-show has a higher priority in SSR Oct 14, 2024
@edison1105 edison1105 added scope: ssr 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. ready to merge The PR is ready to be merged. labels Oct 14, 2024
@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. and removed 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. labels Sep 20, 2025
Copy link

coderabbitai bot commented Sep 23, 2025

Walkthrough

SSR transform now reorders v-show to be processed last and updates SSR codegen/tests to merge _attrs directly via _mergeProps. A new test covers v-show combined with inline display style to validate composed style generation with _ssrRenderStyle.

Changes

Cohort / File(s) Summary
SSR transform: v-show ordering
packages/compiler-ssr/src/transforms/ssrTransformElement.ts
Detects v-show in node.props, removes it, and appends it to the end so it is processed last during SSR prop handling.
SSR v-show tests and codegen expectations
packages/compiler-ssr/__tests__/ssrVShow.spec.ts
Updates expected SSR output: merges \_attrs inside the \_mergeProps call rather than as a separate argument. Adds test: v-show with inline display style combining explicit display and conditional display none via \_ssrRenderStyle.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant T as Template Compiler (SSR)
  participant N as AST Node (Element)
  participant P as Props Processor
  participant G as SSR Codegen

  T->>N: Parse element with props (incl. v-show)
  N->>P: Provide props array
  P->>P: Reorder props (move v-show to end)
  P->>G: Emit merged props via _mergeProps({... , ...})
  G->>G: Compose style via _ssrRenderStyle(display + v-show toggle)
  G-->>T: Return SSR render output
  note over P,G: v-show handled last to finalize display style and merging
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

scope:hydration

Poem

I twitch my whiskers, merge away,
Props in a row—v-show comes to play.
Styles now agree, both server and client,
Display’s aligned, hydration compliant.
Hop, hop! No mismatch today—
A bunny bows to SSR’s ballet. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues Check ✅ Passed The changes move the v-show directive to the end of node.props in the SSR transform and update/add tests (including a "with style + display" case) that verify merging inline display with v-show's conditional display, which directly targets the hydration mismatch reported in issue #12162. The provided summaries show the server-side render now produces the combined style handling expected by the client, and a test exercising the specific scenario was added. Based on the diffs and test updates, the code changes implement the required behavior to address the linked issue.
Out of Scope Changes Check ✅ Passed All modifications are confined to packages/compiler-ssr (the SSR transform and its tests) and directly relate to v-show ordering and SSR style merging, which matches the linked issue's scope. There are no unrelated files or features touched in the provided summary. Therefore no out-of-scope changes were detected.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change: it names the affected area (compiler-ssr) and states the intent (ensure v-show has higher priority in SSR), which matches the code change that reorders v-show handling and the updated SSR tests; it is concise, specific, and meaningful for reviewers scanning PR history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/compiler-ssr/src/transforms/ssrTransformElement.ts (1)

92-101: Reordering v-show last is correct; add a small guard to avoid no-op mutation.

This achieves the intended precedence. Minor polish: skip splice/push when v-show is already last; it avoids unnecessary array churn. Optionally, in dev builds, warn on duplicate v-show.

-    const vShowPropIndex = node.props.findIndex(
+    const vShowPropIndex = node.props.findIndex(
       i => i.type === NodeTypes.DIRECTIVE && i.name === 'show',
     )
-    if (vShowPropIndex !== -1) {
-      const vShowProp = node.props[vShowPropIndex]
-      node.props.splice(vShowPropIndex, 1)
-      node.props.push(vShowProp)
-    }
+    const lastIndex = node.props.length - 1
+    if (vShowPropIndex > -1 && vShowPropIndex !== lastIndex) {
+      const [vShowProp] = node.props.splice(vShowPropIndex, 1)
+      node.props.push(vShowProp)
+    }
packages/compiler-ssr/__tests__/ssrVShow.spec.ts (1)

95-111: Good added case; consider two more to harden coverage.

Add:

  • dynamic display in bound style to ensure v-show still wins,
  • root element variant (no wrapper) with inline display.
+  test('with dynamic style + display (v-show overrides)', () => {
+    const code = compileWithWrapper(`<div :style="{ display: 'flex' }" v-show="foo"/>`).code
+    expect(code).toMatch(
+      /_ssrRenderStyle\(\s*\[\s*\{ display: 'flex' \s*\},\s*\(_ctx\.foo\)\s*\?\s*null\s*:\s*\{ display: "none" \}\s*\]\s*\)/
+    )
+  })
+
+  test('root: with style + display', () => {
+    const code = compile(`<div v-show="foo" style="display:flex"/>`).code
+    expect(code).toMatch(/_mergeProps\(_attrs,\s*\{\s*style:\s*\[?\s*[\s\S]*display["']?\s*:\s*["']?flex["']?[\s\S]*\(_ctx\.foo\)\s*\?\s*null\s*:\s*\{ display: "none" \}/)
+  })
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b555f02 and c840515.

📒 Files selected for processing (2)
  • packages/compiler-ssr/__tests__/ssrVShow.spec.ts (2 hunks)
  • packages/compiler-ssr/src/transforms/ssrTransformElement.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test / e2e-test
🔇 Additional comments (1)
packages/compiler-ssr/__tests__/ssrVShow.spec.ts (1)

14-16: Snapshot change looks good.

Merging _attrs as the first arg to _mergeProps is consistent with current SSR attr precedence.

@edison1105 edison1105 changed the title fix(ssr): v-show has a higher priority in SSR fix(compiler-ssr): ensure v-show has a higher priority in SSR Sep 24, 2025
@edison1105 edison1105 merged commit 836b829 into vuejs:main Sep 24, 2025
14 checks passed
@linzhe141 linzhe141 deleted the fix-v-show-ssr branch September 25, 2025 02:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: ssr
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: hydration mismatch when having v-show="false" and style="display: <any>"
2 participants