Skip to content

Core: Fix event source URL based on refId when multiple iframes share the same origin#34105

Open
ghengeveld wants to merge 1 commit intonextfrom
fix-composition-on-common-base-url
Open

Core: Fix event source URL based on refId when multiple iframes share the same origin#34105
ghengeveld wants to merge 1 commit intonextfrom
fix-composition-on-common-base-url

Conversation

@ghengeveld
Copy link
Member

@ghengeveld ghengeveld commented Mar 11, 2026

Closes #34094

What I did

Updated channel event handling to consider refId when multiple iframes with the same origin exist.

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

  • Take a working Storybook and upgrade it
    • npx storybook@0.0.0-pr-34105-sha-d0a83f8a upgrade
  • Build the Storybook to storybook-static
  • Move the storybook-static folder into the public folder.
  • Modify .storybook/main.ts with the below refs config.
  • Start the (outer) Storybook and navigate to one of the stories on the Inner Storybook.
  • Refresh the browser.
  • Stories should load and work normally.
  refs: {
    'inner': {
      title: 'Inner Storybook',
      url: 'http://localhost:6006/storybook-static/',
    },
  }

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-34105-sha-d0a83f8a. Try it out in a new sandbox by running npx storybook@0.0.0-pr-34105-sha-d0a83f8a sandbox or in an existing project with npx storybook@0.0.0-pr-34105-sha-d0a83f8a upgrade.

More information
Published version 0.0.0-pr-34105-sha-d0a83f8a
Triggered by @shilman
Repository storybookjs/storybook
Branch fix-composition-on-common-base-url
Commit d0a83f8a
Datetime Thu Mar 12 03:06:16 UTC 2026 (1773284776)
Workflow run 22984743009

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=34105

Summary by CodeRabbit

  • Bug Fixes
    • Improved iframe source identification in multi-frame scenarios using reference identifiers for better disambiguation
    • Enhanced error handling when message source resolution encounters multiple candidate frames
    • Refined event source resolution logic for more accurate and reliable source determination

@nx-cloud
Copy link

nx-cloud bot commented Mar 11, 2026

View your CI Pipeline Execution ↗ for commit d0a83f8

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

☁️ Nx Cloud last updated this comment at 2026-03-12 10:09:41 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

Added an optional refId parameter to getEventSourceUrl function to disambiguate multiple matching iframe candidates. Introduced an internal helper pickFrameByRefId that uses refId to select the correct iframe when multiple candidates exist. Updated the calling code to pass refId during iframe source resolution.

Changes

Cohort / File(s) Summary
PostMessage Event Source Resolution
code/core/src/channels/postmessage/getEventSourceUrl.ts
Added internal pickFrameByRefId helper function for iframe disambiguation by refId. Updated function signature to accept optional refId?: string parameter and explicitly return string | null. Refactored candidate frame filtering logic to use candidates array and delegate selection to the new helper. Enhanced error handling with logging when multiple candidates remain after refId filtering.
PostMessage Event Handler
code/core/src/channels/postmessage/index.ts
Updated call to getEventSourceUrl to pass refId parameter when resolving event source URL in non-preview mode.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)

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

Copy link
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.

🧹 Nitpick comments (1)
code/core/src/channels/postmessage/getEventSourceUrl.ts (1)

59-64: Consider wrapping URL parsing in try-catch for robustness.

The new URL() call at line 62 is outside any try-catch block. While iframe src attributes are typically valid URLs, a malformed value could cause an uncaught exception. This is a minor edge case, but for consistency with the defensive approach used elsewhere in this function, you may want to handle it.

🛡️ Optional fix to add defensive error handling
  const src = pickFrameByRefId(candidates, refId)?.getAttribute('src');

  if (src) {
+   try {
      const { protocol, host, pathname } = new URL(src, document.location.toString());
      return `${protocol}//${host}${pathname}`;
+   } catch {
+     // Malformed src, fall through to return null
+   }
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/core/src/channels/postmessage/getEventSourceUrl.ts` around lines 59 -
64, In getEventSourceUrl, wrap the new URL(...) call (where you deconstruct
protocol, host, pathname) in a try-catch so a malformed iframe src from
pickFrameByRefId(...) does not throw; on exception log or silently handle and
return undefined (preserving the existing behavior when src is absent). Ensure
you still pass document.location.toString() as the base to URL and return
`${protocol}//${host}${pathname}` only on success.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@code/core/src/channels/postmessage/getEventSourceUrl.ts`:
- Around line 59-64: In getEventSourceUrl, wrap the new URL(...) call (where you
deconstruct protocol, host, pathname) in a try-catch so a malformed iframe src
from pickFrameByRefId(...) does not throw; on exception log or silently handle
and return undefined (preserving the existing behavior when src is absent).
Ensure you still pass document.location.toString() as the base to URL and return
`${protocol}//${host}${pathname}` only on success.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a63a365c-dbaa-44f6-b3f6-8a349218b126

📥 Commits

Reviewing files that changed from the base of the PR and between 1ba2d07 and d0a83f8.

📒 Files selected for processing (2)
  • code/core/src/channels/postmessage/getEventSourceUrl.ts
  • code/core/src/channels/postmessage/index.ts

@storybook-bot
Copy link
Contributor

Failed to publish canary version of this pull request, triggered by @ghengeveld. See the failed workflow run at: https://github.com/storybookjs/storybook/actions/runs/22962473056

@storybook-bot
Copy link
Contributor

Failed to publish canary version of this pull request, triggered by @Sidnioulz. See the failed workflow run at: https://github.com/storybookjs/storybook/actions/runs/22962473056

1 similar comment
@storybook-bot
Copy link
Contributor

Failed to publish canary version of this pull request, triggered by @Sidnioulz. See the failed workflow run at: https://github.com/storybookjs/storybook/actions/runs/22962473056

@ghengeveld ghengeveld added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Mar 12, 2026
@storybook-app-bot
Copy link

Package Benchmarks

Commit: d0a83f8, ran on 12 March 2026 at 10:12:26 UTC

The following packages have significant changes to their size or dependencies:

@storybook/builder-webpack5

Before After Difference
Dependency count 185 185 0
Self size 76 KB 76 KB 0 B
Dependency size 32.18 MB 32.19 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/angular

Before After Difference
Dependency count 185 185 0
Self size 140 KB 140 KB 0 B
Dependency size 30.39 MB 30.40 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/ember

Before After Difference
Dependency count 189 189 0
Self size 15 KB 15 KB 🚨 +18 B 🚨
Dependency size 28.89 MB 28.90 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/nextjs

Before After Difference
Dependency count 534 534 0
Self size 650 KB 650 KB 0 B
Dependency size 59.89 MB 59.91 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/nextjs-vite

Before After Difference
Dependency count 92 92 0
Self size 1.12 MB 1.12 MB 🎉 -36 B 🎉
Dependency size 22.45 MB 22.47 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-native-web-vite

Before After Difference
Dependency count 124 124 0
Self size 30 KB 30 KB 0 B
Dependency size 23.74 MB 23.75 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-vite

Before After Difference
Dependency count 82 82 0
Self size 35 KB 35 KB 🚨 +18 B 🚨
Dependency size 20.24 MB 20.25 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-webpack5

Before After Difference
Dependency count 271 271 0
Self size 24 KB 24 KB 🎉 -12 B 🎉
Dependency size 44.52 MB 44.53 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/server-webpack5

Before After Difference
Dependency count 197 197 0
Self size 16 KB 16 KB 0 B
Dependency size 33.44 MB 33.45 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 183 183 0
Self size 779 KB 779 KB 0 B
Dependency size 67.35 MB 67.36 MB 🚨 +13 KB 🚨
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 176 176 0
Self size 32 KB 32 KB 🎉 -36 B 🎉
Dependency size 65.88 MB 65.89 MB 🚨 +13 KB 🚨
Bundle Size Analyzer Link Link

@storybook/preset-react-webpack

Before After Difference
Dependency count 167 167 0
Self size 18 KB 18 KB 0 B
Dependency size 31.39 MB 31.40 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react

Before After Difference
Dependency count 58 58 0
Self size 1.19 MB 1.19 MB 🚨 +6 B 🚨
Dependency size 13.19 MB 13.20 MB 🚨 +12 KB 🚨
Bundle Size Analyzer Link Link

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

Labels

bug ci:normal 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]: Storybook crashes when the initial load occurs on a composed story

2 participants