Revert react-router v7 future flags from #31818

Roll back the v7_relativeSplatPath and v7_startTransition future flags
and the Outlet-based route structure, keeping the version bump to
react-router-dom@^6.30.2.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-02-12 09:59:49 +01:00
parent 36573c6dd0
commit 47d064a51b
6 changed files with 20 additions and 78 deletions
+1 -1
View File
@@ -53,4 +53,4 @@
'@backstage/plugin-org': patch
---
Prepare for React Router v7 migration by updating to v6.30.2 across all NFS packages and enabling v7 future flags. Convert routes from splat paths to parent/child structure with Outlet components.
Updated `react-router-dom` peer dependency to `^6.30.2`.
@@ -208,13 +208,7 @@ export function renderInTestApp<const TApiPairs extends any[] = any[]>(
RouterBlueprint.make({
params: {
component: ({ children }) => (
<MemoryRouter
initialEntries={options?.initialRouteEntries}
future={{
v7_relativeSplatPath: true,
v7_startTransition: true,
}}
>
<MemoryRouter initialEntries={options?.initialRouteEntries}>
{children}
</MemoryRouter>
),
@@ -150,13 +150,7 @@ export function renderTestApp<const TApiPairs extends any[] = any[]>(
RouterBlueprint.make({
params: {
component: ({ children }) => (
<MemoryRouter
initialEntries={options?.initialRouteEntries}
future={{
v7_relativeSplatPath: true,
v7_startTransition: true,
}}
>
<MemoryRouter initialEntries={options?.initialRouteEntries}>
{children}
</MemoryRouter>
),
+1 -11
View File
@@ -198,17 +198,7 @@ export interface AppRouterProps {
function DefaultRouter(props: PropsWithChildren<{}>) {
const configApi = useApi(configApiRef);
const basePath = getBasePath(configApi);
return (
<BrowserRouter
basename={basePath}
future={{
v7_relativeSplatPath: true,
v7_startTransition: true,
}}
>
{props.children}
</BrowserRouter>
);
return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;
}
/**
+7 -35
View File
@@ -20,7 +20,7 @@ import {
createExtensionInput,
NotFoundErrorPage,
} from '@backstage/frontend-plugin-api';
import { useRoutes, Outlet } from 'react-router-dom';
import { useRoutes } from 'react-router-dom';
export const AppRoutes = createExtension({
name: 'routes',
@@ -38,42 +38,14 @@ export const AppRoutes = createExtension({
const element = useRoutes([
...inputs.routes.map(route => {
const routePath = route.get(coreExtensionData.routePath);
const routeElement = route.get(coreExtensionData.reactElement);
// For v7_relativeSplatPath: convert splat paths to parent/child structure
if (routePath === '/') {
// Root route: parent with index and splat children
return {
path: '/',
element: <Outlet />,
children: [
{
index: true,
element: routeElement,
},
{
path: '*',
element: routeElement,
},
],
};
}
// Non-root routes: parent route with splat child
const normalizedPath = routePath.replace(/\/$/, '');
return {
path: normalizedPath,
element: <Outlet />,
children: [
{
index: true,
element: routeElement,
},
{
path: '*',
element: routeElement,
},
],
path:
routePath === '/'
? routePath
: `${routePath.replace(/\/$/, '')}/*`,
element: route.get(coreExtensionData.reactElement),
};
}),
{
@@ -15,7 +15,7 @@
*/
import { ReactElement, useMemo } from 'react';
import { Helmet } from 'react-helmet';
import { matchRoutes, useParams, useRoutes, Outlet } from 'react-router-dom';
import { matchRoutes, useParams, useRoutes } from 'react-router-dom';
import { EntityTabsPanel } from './EntityTabsPanel';
import { EntityTabsList } from './EntityTabsList';
import { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';
@@ -35,25 +35,17 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): {
} {
const params = useParams();
// For v7_relativeSplatPath: convert splat paths to parent/child structure
const routes = subRoutes.map(({ path, children }) => ({
caseSensitive: false,
path: path,
element: <Outlet />,
children: [
{
index: true,
element: children,
},
{
path: '*',
element: children,
},
],
path: `${path}/*`,
element: children,
}));
// Sort routes by path length (longest first) for proper matching
const sortedRoutes = routes.sort((a, b) => b.path.localeCompare(a.path));
// TODO: remove once react-router updated
const sortedRoutes = routes.sort((a, b) =>
// remove "/*" symbols from path end before comparing
b.path.replace(/\/\*$/, '').localeCompare(a.path.replace(/\/\*$/, '')),
);
const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;
@@ -67,7 +59,7 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): {
const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];
const foundIndex = matchedRoute
? subRoutes.findIndex(t => t.path === matchedRoute.route.path)
? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)
: 0;
return {