Skip to content

fix(compiler-vapor): only treat html whitespace as empty slot content - #16161

Open
simonkundrik wants to merge 1 commit into
vuejs:minorfrom
simonkundrik:fix/vapor-nbsp-default-slot
Open

simonkundrik wants to merge 1 commit into
vuejs:minorfrom
simonkundrik:fix/vapor-nbsp-default-slot

Conversation

@simonkundrik

Copy link
Copy Markdown

A default slot that only holds a non-breaking space (or another Unicode space like U+3000) is treated as empty in vapor mode, so the child renders its fallback. In vdom the space is rendered.

<!-- Child.vue -->
<template><b><slot>fallback</slot></b></template>

<!-- App.vue -->
<template><Child>&nbsp;</Child></template>

vdom renders <b>&nbsp;</b> and vapor renders <b>fallback</b>. When the child has no fallback, vapor renders nothing instead of the space, so something like <Button>&nbsp;</Button> or <Cell> </Cell> comes out empty.

isNonWhitespaceContent in compiler-vapor/src/transforms/vSlot.ts used String.prototype.trim(), which also strips NBSP, U+3000, U+FEFF and the other Unicode spaces. Core's buildSlots uses isWhitespaceText, which only counts HTML whitespace. This switches it to isAllWhitespace so the two agree. Explicit <template #default>&nbsp;</template> already worked.

I added a parity test for &nbsp;, &emsp;, &#x3000; and &#xFEFF;. It fails on minor and passes with the change. The compiler-vapor and runtime-vapor unit suites pass, and so do tsc and lint and format check on the changed files.

Found by rendering random templates in both modes and diffing the DOM.

String.prototype.trim also strips NBSP, U+3000, U+FEFF and the other
Unicode spaces, so an implicit default slot that only held one of them
was dropped and the child rendered its fallback. Core only counts html
whitespace here, so use the same check.
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 430d38db-781e-4331-98a9-b7703aeafe75

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant