Skip to content

Core: Prevent story-local viewport from persisting in URL#34153

Merged
ghengeveld merged 1 commit into
nextfrom
fix-persistent-story-viewport
Mar 19, 2026
Merged

Core: Prevent story-local viewport from persisting in URL#34153
ghengeveld merged 1 commit into
nextfrom
fix-persistent-story-viewport

Conversation

@ghengeveld
Copy link
Copy Markdown
Member

@ghengeveld ghengeveld commented Mar 16, 2026

Closes #34133

What I did

When a story has a defined viewport global (in code), that value should not be synced with the URL, because otherwise the value will stick around in the URL and apply to stories which otherwise do not have a viewport specified. To fix this issue, I've updated the globals state handler to only sync userGlobals (rather than globals) back to the globals state when SET_GLOBALS is emitted.

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

  1. Have a Storybook with some stories defined with a viewport global, and some without.
  2. Navigate back and forth between some stories with and some stories without a specified viewport. Confirm the URL does not include any viewport global at any point.
  3. Navigate to a normal story (no viewport) and change the viewport via the toolbar. Confirm the URL reflects this change.
  4. Navigate to a story with viewport. Confirm that viewport is applied, but the previously selected viewport is still present in the URL.
  5. Navigate to a normal story again. Confirm the previously selected viewport is applied once again.
  6. Reset the viewport tool. Confirm the global is removed from the URL.
  7. Navigate back and forth between some stories with and some stories without a specified viewport. Confirm the URL does not include any viewport global at any point.

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 pull request has been released as version 0.0.0-pr-34153-sha-e6470d88. Try it out in a new sandbox by running npx storybook@0.0.0-pr-34153-sha-e6470d88 sandbox or in an existing project with npx storybook@0.0.0-pr-34153-sha-e6470d88 upgrade.

More information
Published version 0.0.0-pr-34153-sha-e6470d88
Triggered by @ghengeveld
Repository storybookjs/storybook
Branch fix-persistent-story-viewport
Commit e6470d88
Datetime Mon Mar 16 09:42:53 UTC 2026 (1773654173)
Workflow run 23137334965

To request a new release of this pull request, mention the @storybookjs/core team.

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

Summary by CodeRabbit

  • Bug Fixes
    • Fixed global settings handling to properly distinguish between user-defined and system globals, preventing unnecessary updates when globals are empty or unchanged.

@ghengeveld ghengeveld requested review from ndelangen and yannbf March 16, 2026 09:38
@ghengeveld ghengeveld self-assigned this Mar 16, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

The SET_GLOBALS handler in the globals module has been modified to reference currentUserGlobals from store state instead of currentGlobals when determining whether to call the update API. Corresponding test coverage was added to validate this behavior change, including a new test case for empty globals scenarios.

Changes

Cohort / File(s) Summary
Globals Handler Implementation
code/core/src/manager-api/modules/globals.ts
Modified SET_GLOBALS handler to check and compare currentUserGlobals instead of currentGlobals when deciding whether to invoke api.updateGlobals; affects state update path logic.
Globals Module Tests
code/core/src/manager-api/tests/globals.test.ts
Updated test descriptions to clarify "user globals" vs "globals"; added test case verifying empty globals do not trigger UPDATE_GLOBALS emission or preview changes; explicitly sets userGlobals in store state for divergence testing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
📝 Coding Plan
  • Generate coding plan for human review comments

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

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

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/core/src/manager-api/tests/globals.test.ts (1)

107-130: Consider asserting post-event state alongside “no emit”.

The new test is useful; adding explicit assertions for globals/userGlobals after SET_GLOBALS would make the regression guard tighter and less emission-only.

✅ Optional strengthening
   channel.emit(SET_GLOBALS, {
     globals: {},
     globalTypes: {},
   } satisfies SetGlobalsPayload);

   expect(listener).not.toHaveBeenCalled();
+  expect(store.getState()).toMatchObject({
+    userGlobals: {},
+    globals: {},
+  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/core/src/manager-api/tests/globals.test.ts` around lines 107 - 130, Add
assertions after channel.emit(SET_GLOBALS, ...) to verify the module state did
not change: assert that store.getState().globals and
store.getState().userGlobals remain equal to the pre-event values (the values
set via store.setState: globals: { viewport: 'mobile1' } and userGlobals: {}).
Locate the test using createMockStore, initModule, and the EventEmitter emitting
SET_GLOBALS (and the listener registered on UPDATE_GLOBALS) and add expectations
that globals and userGlobals are unchanged in addition to
expect(listener).not.toHaveBeenCalled().
🤖 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/core/src/manager-api/modules/globals.ts`:
- Around line 141-147: The current block calls
api.updateGlobals(currentUserGlobals) even when handling non-local refs; tighten
the guard so updateGlobals is only invoked for local refs by adding the same
local-ref condition used elsewhere (the !ref branch) — i.e., ensure you check
the ref/local flag before comparing globals and calling api.updateGlobals (use
the existing symbols currentUserGlobals, globals, deepEqual, and
api.updateGlobals) so non-local SET_GLOBALS cannot trigger an UPDATE_GLOBALS.

---

Nitpick comments:
In `@code/core/src/manager-api/tests/globals.test.ts`:
- Around line 107-130: Add assertions after channel.emit(SET_GLOBALS, ...) to
verify the module state did not change: assert that store.getState().globals and
store.getState().userGlobals remain equal to the pre-event values (the values
set via store.setState: globals: { viewport: 'mobile1' } and userGlobals: {}).
Locate the test using createMockStore, initModule, and the EventEmitter emitting
SET_GLOBALS (and the listener registered on UPDATE_GLOBALS) and add expectations
that globals and userGlobals are unchanged in addition to
expect(listener).not.toHaveBeenCalled().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9332071-6db7-40be-bcc3-e6908860604c

📥 Commits

Reviewing files that changed from the base of the PR and between ebc6315 and e6470d8.

📒 Files selected for processing (2)
  • code/core/src/manager-api/modules/globals.ts
  • code/core/src/manager-api/tests/globals.test.ts

Comment thread code/core/src/manager-api/modules/globals.ts
@ghengeveld ghengeveld added bug patch:yes Bugfix & documentation PR that need to be picked to main branch ci:normal labels Mar 16, 2026
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 16, 2026

View your CI Pipeline Execution ↗ for commit e6470d8

Command Status Duration Result
nx run-many -t compile -c production --parallel=1 ✅ Succeeded 5m 43s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-16 09:54:35 UTC

@ghengeveld ghengeveld merged commit b00ebfa into next Mar 19, 2026
134 of 141 checks passed
@ghengeveld ghengeveld deleted the fix-persistent-story-viewport branch March 19, 2026 12:03
yannbf pushed a commit that referenced this pull request Mar 19, 2026
Core: Prevent story-local viewport from persisting in URL
(cherry picked from commit b00ebfa)
@github-actions github-actions Bot added the patch:done Patch/release PRs already cherry-picked to main/release branch label Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug ci:normal patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Viewport persisting story globals to toolbar

2 participants