Skip to content

Commit

Permalink
fix(core): sortRoutes shouldn't have a default baseUrl value, this le…
Browse files Browse the repository at this point in the history
…d to a bug (#10054)
  • Loading branch information
slorber committed Apr 18, 2024
1 parent 4772b27 commit 1287387
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Available ids are:\n- ${version.docs.map((d) => d.id).join('\n- ')}`,
}

const createFakeActions = (contentDir: string) => {
const routeConfigs: RouteConfig[] = [];
let routeConfigs: RouteConfig[] = [];
const dataContainer: {[key: string]: unknown} = {};
const globalDataContainer: {pluginName?: {pluginId: unknown}} = {};

Expand All @@ -83,7 +83,7 @@ const createFakeActions = (contentDir: string) => {
expectSnapshot: () => {
// Sort the route config like in src/server/plugins/index.ts for
// consistent snapshot ordering
sortRoutes(routeConfigs);
routeConfigs = sortRoutes(routeConfigs, '/');
expect(routeConfigs).not.toEqual([]);
expect(routeConfigs).toMatchSnapshot('route config');
expect(dataContainer).toMatchSnapshot('data');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,7 @@ describe('sortRoutes', () => {
},
];

sortRoutes(routes);

expect(routes).toMatchSnapshot();
expect(sortRoutes(routes, '/')).toMatchSnapshot();
});

it('sorts route config recursively', () => {
Expand Down Expand Up @@ -248,9 +246,7 @@ describe('sortRoutes', () => {
},
];

sortRoutes(routes);

expect(routes).toMatchSnapshot();
expect(sortRoutes(routes, '/')).toMatchSnapshot();
});

it('sorts route config given a baseURL', () => {
Expand Down Expand Up @@ -290,8 +286,27 @@ describe('sortRoutes', () => {
},
];

sortRoutes(routes, baseURL);
expect(sortRoutes(routes, baseURL)).toMatchSnapshot();
});

it('sorts parent route configs when one included in another', () => {
const r1: RouteConfig = {
path: '/one',
component: '',
routes: [{path: `/one/myDoc`, component: ''}],
};
const r2: RouteConfig = {
path: '/',
component: '',
routes: [{path: `/someDoc`, component: ''}],
};
const r3: RouteConfig = {
path: '/one/another',
component: '',
routes: [{path: `/one/another/myDoc`, component: ''}],
};

expect(routes).toMatchSnapshot();
expect(sortRoutes([r1, r2, r3], '/')).toEqual([r3, r1, r2]);
expect(sortRoutes([r3, r1, r2], '/')).toEqual([r3, r1, r2]);
});
});
13 changes: 8 additions & 5 deletions packages/docusaurus/src/server/plugins/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,18 @@ async function executeAllPluginsAllContentLoaded({
// - contentLoaded()
// - allContentLoaded()
function mergeResults({
baseUrl,
plugins,
allContentLoadedResult,
}: {
baseUrl: string;
plugins: LoadedPlugin[];
allContentLoadedResult: AllContentLoadedResult;
}) {
const routes: PluginRouteConfig[] = [
...aggregateRoutes(plugins),
...allContentLoadedResult.routes,
];
sortRoutes(routes);
const routes: PluginRouteConfig[] = sortRoutes(
[...aggregateRoutes(plugins), ...allContentLoadedResult.routes],
baseUrl,
);

const globalData: GlobalData = mergeGlobalData(
aggregateGlobalData(plugins),
Expand Down Expand Up @@ -279,6 +280,7 @@ export async function loadPlugins(
});

const {routes, globalData} = mergeResults({
baseUrl: context.baseUrl,
plugins,
allContentLoadedResult,
});
Expand Down Expand Up @@ -324,6 +326,7 @@ export async function reloadPlugin({
});

const {routes, globalData} = mergeResults({
baseUrl: context.baseUrl,
plugins,
allContentLoadedResult,
});
Expand Down
30 changes: 25 additions & 5 deletions packages/docusaurus/src/server/plugins/routeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export function applyRouteTrailingSlash<Route extends RouteConfig>(
};
}

export function sortRoutes(
routeConfigs: RouteConfig[],
baseUrl: string = '/',
): void {
export function sortRoutes<Route extends RouteConfig>(
routesToSort: Route[],
baseUrl: string,
): Route[] {
const routeConfigs = [...routesToSort];
// Sort the route config. This ensures that route with nested
// routes is always placed last.
routeConfigs.sort((a, b) => {
Expand All @@ -48,6 +49,23 @@ export function sortRoutes(
if (!a.routes && b.routes) {
return -1;
}

// If both are parent routes (for example routeBasePath: "/" and "/docs/"
// We must order them carefully in case of overlapping paths
if (a.routes && b.routes) {
if (a.path === b.path) {
// We don't really support that kind of routing ATM
// React-Router by default will only "enter" a single parent route
} else {
if (a.path.includes(b.path)) {
return -1;
}
if (b.path.includes(a.path)) {
return 1;
}
}
}

// Higher priority get placed first.
if (a.priority || b.priority) {
const priorityA = a.priority ?? 0;
Expand All @@ -64,7 +82,9 @@ export function sortRoutes(

routeConfigs.forEach((routeConfig) => {
if (routeConfig.routes) {
sortRoutes(routeConfig.routes, baseUrl);
routeConfig.routes = sortRoutes(routeConfig.routes, baseUrl);
}
});

return routeConfigs;
}

0 comments on commit 1287387

Please sign in to comment.