fix(server-renderer): render className as escaped string#14469
fix(server-renderer): render className as escaped string#14469edison1105 merged 2 commits intomainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR changes SSR attribute rendering by treating Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Size ReportBundles
Usages
|
@vue/compiler-core
@vue/compiler-dom
@vue/compiler-sfc
@vue/compiler-ssr
@vue/reactivity
@vue/runtime-core
@vue/runtime-dom
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/server-renderer/__tests__/ssrRenderAttrs.spec.ts (1)
147-158:⚠️ Potential issue | 🔴 CriticalAdd test coverage for null, undefined, and object
classNamevalues to expose implementation bugsThe
classNametest block only covers string and array cases. However, the implementation usesString(value)without filtering, which causes critical issues:
className: nullrenders asclass="null"(should be ignored or empty)className: undefinedrenders asclass="undefined"(should be ignored or empty)className: { foo: true }renders asclass="[object Object]"(should be ignored or empty)Add explicit tests to expose these bugs:
expect(ssrRenderAttrs({ className: null })).toBe(``) expect(ssrRenderAttrs({ className: undefined })).toBe(``) expect(ssrRenderAttrs({ className: {} })).toBe(``)After adding tests, the implementation at
ssrRenderAttrs.tsline 49-52 needs fixing to validate values before rendering, similar to howssrRenderDynamicAttrusesisRenderableAttrValue().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/server-renderer/__tests__/ssrRenderAttrs.spec.ts` around lines 147 - 158, The className rendering tests miss null/undefined/object cases and the ssrRenderAttrs implementation currently uses String(value) unconditionally, causing invalid outputs; update ssrRenderAttrs to validate values before rendering (use the same check logic as ssrRenderDynamicAttr with isRenderableAttrValue) so that falsy/non-renderable className values (null, undefined, objects) are ignored and return an empty string, and add tests asserting ssrRenderAttrs({ className: null }) === ``, ssrRenderAttrs({ className: undefined }) === ``, and ssrRenderAttrs({ className: {} }) === `` to lock in the behavior.
🧹 Nitpick comments (1)
packages/server-renderer/src/helpers/ssrRenderAttrs.ts (1)
52-52:String(value)call is redundant
escapeHtmlalready acceptsunknownand internally does'' + string(string coercion), soescapeHtml(String(value))is equivalent toescapeHtml(value). The explicitString()wrap adds no behaviour and can be dropped.♻️ Proposed simplification
- ret += ` class="${escapeHtml(String(value))}"` + ret += ` class="${escapeHtml(value)}"`🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/server-renderer/src/helpers/ssrRenderAttrs.ts` at line 52, The template concatenation is calling String(value) redundantly before escapeHtml; update the ssrRenderAttrs code that builds the class attribute (the expression ret += ` class="${escapeHtml(String(value))}"`) to pass the raw value to escapeHtml (i.e., use escapeHtml(value)) and remove the unnecessary String(...) wrapper so the class rendering uses escapeHtml directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/server-renderer/src/helpers/ssrRenderAttrs.ts`:
- Around line 49-52: In ssrRenderAttrs's className branch, guard against
null/undefined so you don't emit class="null" or "undefined": in the branch that
handles key === 'className' (in ssrRenderAttrs), only coerce and append the
attribute when value is not null/undefined (e.g., value != null); otherwise skip
adding the class attribute (or append an empty class string consistent with
ssrRenderClass behavior). Update/add tests to cover className: null and
className: undefined to assert no literal "null"/"undefined" is emitted.
---
Outside diff comments:
In `@packages/server-renderer/__tests__/ssrRenderAttrs.spec.ts`:
- Around line 147-158: The className rendering tests miss null/undefined/object
cases and the ssrRenderAttrs implementation currently uses String(value)
unconditionally, causing invalid outputs; update ssrRenderAttrs to validate
values before rendering (use the same check logic as ssrRenderDynamicAttr with
isRenderableAttrValue) so that falsy/non-renderable className values (null,
undefined, objects) are ignored and return an empty string, and add tests
asserting ssrRenderAttrs({ className: null }) === ``, ssrRenderAttrs({
className: undefined }) === ``, and ssrRenderAttrs({ className: {} }) === `` to
lock in the behavior.
---
Nitpick comments:
In `@packages/server-renderer/src/helpers/ssrRenderAttrs.ts`:
- Line 52: The template concatenation is calling String(value) redundantly
before escapeHtml; update the ssrRenderAttrs code that builds the class
attribute (the expression ret += ` class="${escapeHtml(String(value))}"`) to
pass the raw value to escapeHtml (i.e., use escapeHtml(value)) and remove the
unnecessary String(...) wrapper so the class rendering uses escapeHtml directly.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/server-renderer/__tests__/ssrRenderAttrs.spec.tspackages/server-renderer/src/helpers/ssrRenderAttrs.ts
see #11722 (comment)
Summary by CodeRabbit