fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(react): Remove routes from shared set on <Routes> unmount - #22792

Merged
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across
Jul 30, 2026
Merged

fix(react): Remove routes from shared set on <Routes> unmount#22792
logaretm merged 3 commits into
developfrom
awad/js-3213-react-router-v6-integration-allroutes-accumulates-across

Conversation

@logaretm

@logaretmlogaretm commented Jul 28, 2026

Copy link
Copy Markdown
Member

Removes a <Routes>'s routes from the module-level allRoutes set when it unmounts, so they can't be matched against a later, unrelated navigation.

The set accumulated every route ever mounted and never removed any. Once two independent routers had each been mounted, matchRoutes ran over the union of both, so a navigation into one could pick up a param name from the other and produce a hybrid transaction name like /bar/:fooId instead of /bar/:barId.

I've taken out the route adding logic from the effect we had and added another one so that we can isolate the add/remove to the same effect to avoid relying on refs that can be fidgity in dev/prod and strict modes.

closes#22782

Will backport to v10

@linear-code

Copy link
Copy Markdown

JS-3213

…ent routers
Adds two independent descendant <SentryRoutes> trees (foo/*, bar/*) and a
cross-router client-side navigation. Because allRoutes is a shared module-level
set, navigating into the second router picks up the first router's param name,
producing the hybrid /bar/:fooId instead of /bar/:barId.
This test currently fails, documenting issue #22782.
The module-level `allRoutes` set accumulated every route ever mounted and
never removed any, so once two independent routers had each been mounted,
`matchRoutes` ran over the union of both and could name a transaction with
one router's static segment and another's param (e.g. `/bar/:fooId`).
Removing a `<Routes>`'s routes when it unmounts keeps the set to what is
currently mounted, so stale routes from an unrelated router can't be matched
against a later navigation.
Fixes#22782
@logaretm
logaretmforce-pushed the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch from 8771f29 to 1e33054CompareJuly 29, 2026 12:47
The previous cleanup added routes only during the mount render pass but removed
them on every unmount. Under StrictMode (mount, unmount, remount) the remount
skipped the add, leaving the shared set missing routes and breaking descendant
name reconstruction in cross-usage scenarios.
Add and remove now share one effect lifecycle, so a StrictMode remount re-adds
the routes it removed on the intermediate unmount.
@logaretm
logaretm marked this pull request as ready for review July 29, 2026 15:32
@logaretm
logaretm requested a review from a team as a code ownerJuly 29, 2026 15:32
@logaretm
logaretm requested review from nicohrubec and s1gr1d and removed request for a teamJuly 29, 2026 15:32
@logaretm
logaretm merged commit fa8babb into developJul 30, 2026
271 checks passed
@logaretm
logaretm deleted the awad/js-3213-react-router-v6-integration-allroutes-accumulates-across branch July 30, 2026 13:17
Sign up for freeto 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.

React Router v6 integration: allRoutes accumulates across independent/unrelated routers, causing incorrect transaction names

3 participants

@logaretm@nicohrubec@s1gr1d