Skip to content

scope page styles in vue templates using style scoped#34571

Open
nitzan-treg wants to merge 1 commit into
storybookjs:nextfrom
nitzan-treg:fix/23862-bug-react-storybook-vite-example-compone
Open

scope page styles in vue templates using style scoped#34571
nitzan-treg wants to merge 1 commit into
storybookjs:nextfrom
nitzan-treg:fix/23862-bug-react-storybook-vite-example-compone

Conversation

@nitzan-treg
Copy link
Copy Markdown

@nitzan-treg nitzan-treg commented Apr 17, 2026

hey, saw #23862 and took a look

the page component in the vue example templates was importing page.css globally, which could let styles leak into other stories. switched to using vue's built-in <style scoped> block instead, which properly isolates the styles to the Page component. this affects both the vue3-vite framework templates and the vue3 renderer templates (js and ts variants).

fixes #23862


Closes #

What I did

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Refactor
    • Reorganized component styling in Vue templates to use scoped inline styles instead of external CSS files, improving style encapsulation across multiple template variations.

`the page component in the vue example templates was importing page.css globally, which could let styles leak into other stories. switched to using vue's built-in <style scoped> block instead, which properly isolates the styles to the page component. this affects both the vue3-vite framework templates and the vue3 renderer templates (js and ts variants).`

Signed-off-by: nitzan-treg <nitzan.tregerman@gmail.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

Four Vue3 Page component files (across two framework/renderer locations, in both JavaScript and TypeScript variants) are refactored to move styling from external ./page.css imports to inline scoped <style> blocks containing all previously external CSS rules.

Changes

Cohort / File(s) Summary
Vue3-Vite Templates
code/frameworks/vue3-vite/template/cli/js/Page.vue, code/frameworks/vue3-vite/template/cli/ts/Page.vue
Removed ./page.css import and added inline <style scoped> block with styles for .storybook-page layout, typography, and nested elements (h2, p, a, ul/li, .tip, .tip-wrapper, SVG paths).
Vue3 Renderer Templates
code/renderers/vue3/template/cli/js/Page.vue, code/renderers/vue3/template/cli/ts/Page.vue
Removed ./page.css import and added inline <style scoped> block with styles for .storybook-page layout, typography, and nested elements (h2, p, a, ul/li, .tip, .tip-wrapper, SVG paths).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes


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

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

Copy link
Copy Markdown
Contributor

@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: 1

🧹 Nitpick comments (1)
code/renderers/vue3/template/cli/js/Page.vue (1)

3-3: Kebab-case vs. camelCase event name inconsistency across Vue3 templates.

This file uses @createAccount="onCreateAccount" while the TS siblings (code/renderers/vue3/template/cli/ts/Page.vue line 3 and code/frameworks/vue3-vite/template/cli/ts/Page.vue line 3) use kebab-case @create-account. Vue 3 recommends kebab-case in DOM templates; worth aligning the JS templates with the TS ones for consistency (pre-existing, but visible in the diff context). Out of scope for this PR — flagging only.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/renderers/vue3/template/cli/js/Page.vue` at line 3, The my-header event
name in the JS template is using camelCase: change the event binding on the
my-header component from `@createAccount`="onCreateAccount" to kebab-case
`@create-account`="onCreateAccount" so it matches the TS templates and Vue 3 DOM
template recommendations; locate the binding in the Page.vue JS template
(component: my-header, props: user, handlers: onLogin/onLogout/onCreateAccount)
and replace the createAccount event name with create-account.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/renderers/vue3/template/cli/ts/Page.vue`:
- Line 73: The comment notes page.css is unused by the two Vue3 Page.vue
templates but is still copied via copyTemplateFiles() using commonAssetsDir; to
fix, remove rendererAssets/common/page.css from commonAssetsDir so Vue3 projects
don't receive it (either delete it entirely or move it into the specific
renderer asset directories that actually import it such as
HTML/React/Svelte/Web-Components), and update copyTemplateFiles() or the assets
registration so only renderer-specific asset dirs are included; verify Page.vue
in the Vue3 renderer does not import ./page.css and that no other shared code
expects rendererAssets/common/page.css.

---

Nitpick comments:
In `@code/renderers/vue3/template/cli/js/Page.vue`:
- Line 3: The my-header event name in the JS template is using camelCase: change
the event binding on the my-header component from
`@createAccount`="onCreateAccount" to kebab-case `@create-account`="onCreateAccount"
so it matches the TS templates and Vue 3 DOM template recommendations; locate
the binding in the Page.vue JS template (component: my-header, props: user,
handlers: onLogin/onLogout/onCreateAccount) and replace the createAccount event
name with create-account.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3692cdaa-0b0e-4d14-9ebf-cbd9243ec012

📥 Commits

Reviewing files that changed from the base of the PR and between 09fb0ba and 9771d2f.

📒 Files selected for processing (4)
  • code/frameworks/vue3-vite/template/cli/js/Page.vue
  • code/frameworks/vue3-vite/template/cli/ts/Page.vue
  • code/renderers/vue3/template/cli/js/Page.vue
  • code/renderers/vue3/template/cli/ts/Page.vue

user.value = { name: 'Jane Doe' };
};
</script>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find any remaining references to page.css in vue3 template paths and in the rendererAssets wiring.
fd -t f 'page\.css$'
rg -nP -C2 "page\.css" --type=ts --type=js --type=vue
rg -nP -C2 "rendererAssets|template/cli" --type=ts --type=js -g '!**/node_modules/**' | rg -n "vue3|page"

Repository: storybookjs/storybook

Length of output: 212


🏁 Script executed:

# Find the rendererAssets directory structure and configuration
find code/lib/create-storybook/rendererAssets -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | head -20

Repository: storybookjs/storybook

Length of output: 120


🏁 Script executed:

# Check the structure of rendererAssets to understand how templates are organized
ls -la code/lib/create-storybook/rendererAssets/

Repository: storybookjs/storybook

Length of output: 291


🏁 Script executed:

# Look for Vue3-specific template configuration
find code/lib/create-storybook -type f \( -name "*.ts" -o -name "*.js" \) | xargs grep -l "vue3\|vue-3" | head -10

Repository: storybookjs/storybook

Length of output: 321


🏁 Script executed:

# Find all Vue3 Page.vue templates
find code/renderers/vue3/template -name "Page.vue" -type f

Repository: storybookjs/storybook

Length of output: 154


🏁 Script executed:

# Check the content of Vue3 Page.vue templates to see if they import page.css
find code/renderers/vue3/template -name "Page.vue" -type f -exec cat {} \;

Repository: storybookjs/storybook

Length of output: 7330


🏁 Script executed:

# Find files that handle asset copying/template generation
find code/lib/create-storybook -type f \( -name "*.ts" -o -name "*.js" \) | xargs grep -l "rendererAssets\|page\.css" | head -20

Repository: storybookjs/storybook

Length of output: 122


🏁 Script executed:

# Check the common rendererAssets directory contents
find code/lib/create-storybook/rendererAssets/common -type f

Repository: storybookjs/storybook

Length of output: 1400


🏁 Script executed:

# Look for generator or template copy logic that might reference page.css
rg -n "page\.css|rendererAssets/common" code/lib/create-storybook/src --type=ts -A 3 -B 3

Repository: storybookjs/storybook

Length of output: 47


🏁 Script executed:

# Read baseGenerator.ts to see how assets are copied
cat code/lib/create-storybook/src/generators/baseGenerator.ts

Repository: storybookjs/storybook

Length of output: 10036


🏁 Script executed:

# Search for vue3 specific generator or asset handling
find code/lib/create-storybook/src/generators -type f -name "*.ts" | xargs grep -l "vue3\|Vue3"

Repository: storybookjs/storybook

Length of output: 185


🏁 Script executed:

# Find and read the copyTemplateFiles function to see what it does with commonAssetsDir
find code/lib -name "*.ts" -o -name "*.js" | xargs grep -l "export.*copyTemplateFiles" | head -5

Repository: storybookjs/storybook

Length of output: 47


🏁 Script executed:

# Search in cli package for the copyTemplateFiles implementation
find code -path "*/cli/*" -name "*.ts" | xargs grep -l "copyTemplateFiles" 2>/dev/null | head -10

Repository: storybookjs/storybook

Length of output: 127


🏁 Script executed:

# Look for copyTemplateFiles in storybook/internal/cli
find code -type f -name "*.ts" | xargs grep -l "function copyTemplateFiles\|export.*copyTemplateFiles" | head -5

Repository: storybookjs/storybook

Length of output: 93


🏁 Script executed:

# Read the copyTemplateFiles function in helpers.ts
cat code/core/src/cli/helpers.ts

Repository: storybookjs/storybook

Length of output: 7872


🏁 Script executed:

# Check all renderer templates to see if any still import page.css
find code/renderers -name "Page.vue" -o -name "Page.svelte" -o -name "Page.tsx" -o -name "Page.ts" | xargs grep -l "page\.css" 2>/dev/null

Repository: storybookjs/storybook

Length of output: 308


🏁 Script executed:

# Search more broadly for page.css imports across all templates
rg "page\.css" code/renderers --type=ts --type=js --type=svelte -l

Repository: storybookjs/storybook

Length of output: 95


🏁 Script executed:

# Check if other frameworks still use page.css in their templates
rg "page\.css" code/lib/create-storybook/rendererAssets --type=ts --type=js --type=html

Repository: storybookjs/storybook

Length of output: 47


🏁 Script executed:

# Check if those other templates actually import page.css
grep -n "page\.css" code/renderers/html/template/cli/ts/Page.ts
grep -n "page\.css" code/renderers/react/template/cli/ts/Page.tsx
grep -n "page\.css" code/renderers/web-components/template/cli/ts/Page.ts

Repository: storybookjs/storybook

Length of output: 133


🏁 Script executed:

# Check Svelte templates for page.css import (without specifying file type to avoid error)
grep -n "page\.css" code/renderers/svelte/template/cli/js/Page.svelte
grep -n "page\.css" code/renderers/svelte/template/cli/ts/Page.svelte

Repository: storybookjs/storybook

Length of output: 114


🏁 Script executed:

# Verify once more that Vue3 templates are the only ones NOT importing page.css
echo "=== Vue3 JS Page.vue ===" && grep -n "page\.css\|import" code/renderers/vue3/template/cli/js/Page.vue | head -20
echo -e "\n=== Vue3 TS Page.vue ===" && grep -n "page\.css\|import" code/renderers/vue3/template/cli/ts/Page.vue | head -20

Repository: storybookjs/storybook

Length of output: 225


Fix factual error about template count and confirm orphaned file issue.

There are two (not four) Vue3 Page.vue templates, and neither imports ./page.css. However, the concern about orphaned files is valid: page.css is still being copied to all scaffolded projects via the commonAssetsDir mechanism in copyTemplateFiles() (helpers.ts), including Vue3 projects where it remains unused. Other renderers (HTML, React, Svelte, Web-Components) still import page.css, but it should be removed from rendererAssets/common/page.css and either deleted or moved to renderer-specific asset directories to avoid copying unused files to Vue3 projects.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/renderers/vue3/template/cli/ts/Page.vue` at line 73, The comment notes
page.css is unused by the two Vue3 Page.vue templates but is still copied via
copyTemplateFiles() using commonAssetsDir; to fix, remove
rendererAssets/common/page.css from commonAssetsDir so Vue3 projects don't
receive it (either delete it entirely or move it into the specific renderer
asset directories that actually import it such as
HTML/React/Svelte/Web-Components), and update copyTemplateFiles() or the assets
registration so only renderer-specific asset dirs are included; verify Page.vue
in the Vue3 renderer does not import ./page.css and that no other shared code
expects rendererAssets/common/page.css.

@valentinpalkovic valentinpalkovic moved this to Empathy Queue (prioritized) in Core Team Projects Apr 22, 2026
valentinpalkovic added a commit to valentinpalkovic/storybook that referenced this pull request May 12, 2026
…plate>

The harness's verify-pr.ts already supports sandbox targets, but the
GitHub workflow only booted internal-ui — PRs that touch non-React
renderers / framework template code had no way to be verified in CI.

Changes:
- scripts/verify/sandbox.ts: widen resolveSandboxDir template type from
  the react-vite literal to any string (vue3-vite/default-ts,
  svelte-vite/default-ts, etc).
- .github/workflows/verify-pr.yml: inside the Verify-PR step, after
  compile and before 'yarn verify-pr', parse the materialised recipe
  for a '// @verify-target: sandbox:<template>' header. If found AND
  the template is allowlisted (react-vite/default-ts,
  react-webpack/default-ts, vue3-vite/default-ts, svelte-vite/default-ts,
  angular-cli/default-ts, nextjs/default-ts), run
  'yarn task sandbox --template <tpl> --start-from auto --no-link'.
  Sandbox lands at $RUNNER_TEMP/storybook-sandboxes/<key>, which is the
  third candidate verify-pr's resolveSandboxDir checks.
- .verify-recipes/_recipe-authoring-guide.md §12: add strong-signal
  bullets so the recipe author picks sandbox when the diff touches
  template/cli/** or non-react renderer/framework runtime code; lists
  the workflow's template allowlist verbatim.

Test target: fork PR built from upstream storybookjs#34571
('scope page styles in vue templates using style scoped'), touching
code/frameworks/vue3-vite/template/cli/** + code/renderers/vue3/template/
cli/**. Expected: agent emits 'sandbox:vue3-vite/default-ts', workflow
generates the sandbox, verify-pr boots it + runs the recipe.
@Sidnioulz Sidnioulz self-assigned this May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Empathy Queue (prioritized)

Development

Successfully merging this pull request may close these issues.

[Bug]: React + Storybook + Vite example component Page.css can leak

3 participants