feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

@JPeer264@nicohrubec
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
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;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} 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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

@JPeer264@nicohrubec
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } 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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

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

feat(react-router): support react router v8 - #21633

Merged
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8
Jun 19, 2026
Merged

feat(react-router): support react router v8#21633
JPeer264 merged 5 commits into
developfrom
jp/support-react-router-8

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 18, 2026

Copy link
Copy Markdown
Member

closes#21622
closes JS-2800

Basically only packages/react/src/reactrouterv8.tsx has been added to make it work. I copied over 3 tests: -cross-usage, -spa and -framework that covers the exports.

To make it easier to check what actually changed in the apps, I made one commit with the copy and another with the changes. So it might be easier to review only the actual changes: b084c55

Docs will be updated once the PR lands

@JPeer264JPeer264 self-assigned this Jun 18, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 18, 2026 12:18
@JPeer264
JPeer264 requested review from Lms24, chargome, nicohrubec and s1gr1d and removed request for a teamJune 18, 2026 12:18

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

],
},
// todo: should be 'GET /errors/server-loader'
transaction: 'GET /{*splat}',

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222849

"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "bundler",

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just as a reference, because commit comments are not shown in PRs: b084c55#r189222251

@linear-code

Copy link
Copy Markdown

JS-2800

@JPeer264
JPeer264 requested a review from nicohrubecJune 19, 2026 08:07
@JPeer264
JPeer264force-pushed the jp/support-react-router-8 branch from 84142b2 to feb5a0dCompareJune 19, 2026 08:16
@JPeer264

Copy link
Copy Markdown
MemberAuthor

as discussed offline maybe we could simplify this so we don't have to ship one integration per major and instead use one generic one

As a written update. Now the version additions in the origin are removed. And v6 and v7 exports are deprecated as it would be safe to use the new ones (also 1-2 of the v6 and v7 e2e-tests were updated, to still check against the old, but also against the new export)

The withSentryReactRouterV*Routing has been unified with the wording of the others: wrapReactRouterRouting

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

const user: User = await getUser();
context.set(userContext, user);
await next();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware omits awaiting startSpan

Medium Severity

The authMiddleware handler invokes Sentry.startSpan without return or await, so the middleware promise can settle before the span callback runs await next(). That breaks the usual React Router middleware contract and can race the loader against context setup or tracing.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

});

await page.goto(`/performance`); // pageload
await page.waitForTimeout(1000); // give it a sec before navigation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

E2E tests use fixed sleeps

Low Severity

Several new React Router 8 framework performance tests call page.waitForTimeout(1000) before navigation instead of waiting on a concrete telemetry or UI signal. Fixed sleeps are a common source of flaky CI when load timing varies.

Additional Locations (1)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 694f162. Configure here.

* Works with React Router v6+.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapReactRouterRouting<P extends Record<string, any>, R extends React.FC<P>>(routes: R): R {

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.

Bug: The file uses React.FC in its type definitions without explicitly importing the React namespace, creating an implicit dependency and code inconsistency.
Severity: LOW

Suggested Fix

Add import * as React from 'react'; to the top of packages/react/src/reactrouter.compat.tsx to make the dependency on the React namespace explicit and improve code consistency and maintainability.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/react/src/reactrouter.compat.tsx#L32
Potential issue: The file `reactrouter.compat.tsx` uses the `React.FC` type in its
definitions without an explicit `import * as React from 'react';` statement. While this
may compile successfully due to TypeScript resolving `React` as a global type from
ambient declarations, it creates an implicit dependency on the toolchain's
configuration. This is inconsistent with other files like `reactrouter.tsx` which do
import React, making the code less maintainable and potentially brittle to future build
system changes.

Did we get this right? 👍 / 👎 to inform future reviews.

@nicohrubecnicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

JPeer264 added a commit that referenced this pull request Jun 24, 2026
ref: #21622 Updating peerDependencies for React Router 8 support. That was forgotten
in #21633
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.

Add support for React Router v8

2 participants

@JPeer264@nicohrubec