Skip to content

Vue <style scoped> loses [data-v-xxx] scoping after ClientRouter soft navigation in dev mode #16334

@Maxgux

Description

@Maxgux

Astro Info

Astro                    v6.1.6
Node                     v24.11.1
System                   macOS (arm64)
Package Manager          bun
Output                   server
Adapter                  @astrojs/node
Integrations             @astrojs/vue

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

In dev mode, when navigating to a page via ClientRouter (View Transitions soft navigation), Vue <style scoped> blocks lose their [data-v-xxx] scoping. This causes styles to leak between components that use the same class name.

On a full page load (hard refresh), styles are correctly scoped. The issue only appears after a soft navigation.

Maybe Root cause: During SSR, Astro injects <style data-vite-dev-id="..."> tags with raw unscoped CSS (e.g. .box { ... }). Normally, a corresponding <script type="module"> runs and transforms the style content to include Vue's scoped selectors (e.g. .box[data-v-xxxxx] { ... }). After a ClientRouter soft navigation, these scripts are marked data-astro-exec and do not re-execute, so the styles remain unscoped.

Production builds are not affected — only dev mode.

This is maybe related to #15898 (fixed in 6.1.1), but that fix only handles styles that already exist in the current document. It does not handle styles that are new to the document after navigation.

To Reproduce

Cf Stackblitz

Steps:

  • Go to /a
  • Click "Go to Page B" (soft navigation via ClientRouter)
  • All good, go back to Homepage
  • Go to Page B again
  • Observe: both boxes have the same style (styles leak between components)
  • Hard refresh on /b: each box has its correct scoped style

What's the expected result?

After soft navigation to Page B, each component should have its own scoped styles:

BlueBox: blue background, rounded corners
RedBox: red background, square corners
The <style> tags in should contain scoped selectors like .box[data-v-xxxxx].

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-32hu4urc-xbifb7i7

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)pkg: astroRelated to the core `astro` package (scope)pkg: vueRelated to Vue (scope)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions