Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@
"npm-run-all": "^4.1.5",
"oxfmt": "^0.47.0",
"pkg-pr-new": "^0.0.68",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
"rimraf": "^3.0.2",
"sharp": "^0.35.1",
Expand Down
5 changes: 2 additions & 3 deletions packages/docusaurus-module-type-aliases/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
},
"dependencies": {
"@docusaurus/types": "3.10.1",
"@types/history": "^4.7.11",
"@types/react": "19.2.14",
"@types/react-router-config": "*",
"@types/react-router-dom": "*",
"history": "^5.3.0",
"react-router": "^8.0.1",
"react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
"react-loadable": "npm:@docusaurus/react-loadable@6.0.0"
},
Expand Down
46 changes: 40 additions & 6 deletions packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ declare module '@generated/registry' {
}

declare module '@generated/routes' {
import type {RouteConfig as RRRouteConfig} from 'react-router-config';
import type {RouteConfig as DocusaurusRouteConfig} from '@docusaurus/types';
import type Loadable from 'react-loadable';

type RouteConfig = RRRouteConfig & {
type RouteConfig = DocusaurusRouteConfig & {
path: string;
component: ReturnType<typeof Loadable>;
};
Expand Down Expand Up @@ -169,7 +169,7 @@ declare module '@docusaurus/Head' {

declare module '@docusaurus/Link' {
import type {CSSProperties, ComponentProps, ReactNode} from 'react';
import type {NavLinkProps as RRNavLinkProps} from 'react-router-dom';
import type {NavLinkProps as RRNavLinkProps} from 'react-router';

type NavLinkProps = Partial<RRNavLinkProps>;
export type Props = NavLinkProps &
Expand Down Expand Up @@ -260,7 +260,40 @@ declare module '@docusaurus/Translate' {
}

declare module '@docusaurus/router' {
export {useHistory, useLocation, Redirect, matchPath} from 'react-router-dom';
import type {ReactNode} from 'react';
import type {History, Location} from 'history';

export {
useLocation,
useNavigate,
useNavigationType,
Link,
NavLink,
BrowserRouter,
HashRouter,
unstable_HistoryRouter as HistoryRouter,
StaticRouter,
} from 'react-router';

export function useHistory(): History;
export function Redirect(props: {
push?: boolean;
to: string | Partial<Location>;
}): ReactNode;
export function matchPath(
pathname: string,
options: {
path: string;
exact?: boolean;
strict?: boolean;
sensitive?: boolean;
},
): {
path: string;
url: string;
isExact: boolean;
params: Record<string, string | undefined>;
} | null;
}

declare module '@docusaurus/useIsomorphicLayoutEffect' {
Expand Down Expand Up @@ -351,9 +384,10 @@ declare module '@docusaurus/Noop' {
}

declare module '@docusaurus/renderRoutes' {
import {renderRoutes} from 'react-router-config';
import type {ReactNode} from 'react';
import type {RouteConfig} from '@generated/routes';

export default renderRoutes;
export default function renderRoutes(routes: RouteConfig[]): ReactNode;
}

declare module '@docusaurus/useGlobalData' {
Expand Down
1 change: 0 additions & 1 deletion packages/docusaurus-plugin-content-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
"@docusaurus/utils": "3.10.1",
"@docusaurus/utils-common": "3.10.1",
"@docusaurus/utils-validation": "3.10.1",
"@types/react-router-config": "^5.0.7",
"combine-promises": "^1.1.0",
"fs-extra": "^11.2.0",
"js-yaml": "^4.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,21 +635,22 @@ declare module '@theme/DocBreadcrumbs' {

declare module '@theme/DocsRoot' {
import type {ReactNode} from 'react';
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';
import type {RouteConfig} from '@docusaurus/types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
export interface Props {
readonly route: RouteConfig;
}

export default function DocsRoot(props: Props): ReactNode;
}

declare module '@theme/DocVersionRoot' {
import type {ReactNode} from 'react';
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';
import type {RouteConfig} from '@docusaurus/types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {
export interface Props {
readonly route: RouteConfig;
readonly version: PropVersionMetadata;
}

Expand All @@ -658,10 +659,11 @@ declare module '@theme/DocVersionRoot' {

declare module '@theme/DocRoot' {
import type {ReactNode} from 'react';
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';
import type {RouteConfig} from '@docusaurus/types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
export interface Props {
readonly route: RouteConfig;
}

export default function DocRoot(props: Props): ReactNode;
}
5 changes: 2 additions & 3 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"postcss": "^8.5.12",
"prism-react-renderer": "^2.4.1",
"prismjs": "^1.29.0",
"react-router-dom": "^5.3.4",
"rtlcss": "^4.1.0",
"tslib": "^2.6.0",
"utility-types": "^3.10.0"
Expand All @@ -54,8 +53,8 @@
"fs-extra": "^11.2.0"
},
"peerDependencies": {
"react": "^19.2.5",
"react-dom": "^19.2.5"
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"engines": {
"node": ">=24.14"
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus-theme-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@
"@docusaurus/module-type-aliases": "3.10.1",
"@docusaurus/utils": "3.10.1",
"@docusaurus/utils-common": "3.10.1",
"@types/history": "^4.7.11",
"@types/react": "19.2.14",
"@types/react-router-config": "*",
"history": "^5.3.0",
"clsx": "^2.0.0",
"parse-numeric-range": "^1.3.0",
"prism-react-renderer": "^2.4.1",
Expand All @@ -51,8 +50,8 @@
"lodash": "^4.17.21"
},
"peerDependencies": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"engines": {
"node": ">=24.14"
Expand Down
10 changes: 8 additions & 2 deletions packages/docusaurus-theme-common/src/utils/historyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ function useHistoryActionHandler(handler: HistoryBlockHandler): void {
const stableHandler = useEvent(handler);
useEffect(
// See https://github.com/remix-run/history/blob/main/docs/blocking-transitions.md
() => history.block((location, action) => stableHandler(location, action)),
() =>
history.block((transition) => {
const result = stableHandler(transition.location, transition.action);
if (result !== false) {
transition.retry();
}
}),
[history, stableHandler],
);
}
Expand Down Expand Up @@ -51,7 +57,7 @@ export function useHistoryPopHandler(handler: HistoryBlockHandler): void {
* @param selector
*/
export function useHistorySelector<Value>(
selector: (history: History<unknown>) => Value,
selector: (history: History) => Value,
): Value {
const history = useHistory();
return useSyncExternalStore(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {useMemo} from 'react';
import generatedRoutes from '@generated/routes';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import type {RouteConfig} from 'react-router-config';
import type {RouteConfig} from '@docusaurus/types';

/**
* Compare the 2 paths, case insensitive and ignoring trailing slash
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"license": "MIT",
"dependencies": {
"@mdx-js/mdx": "^3.1.1",
"@types/history": "^4.7.11",
"history": "^5.3.0",
"@types/mdast": "^4.0.2",
"@types/react": "19.2.14",
"commander": "^5.1.0",
Expand Down
12 changes: 4 additions & 8 deletions packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@
"react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
"react-loadable": "npm:@docusaurus/react-loadable@6.0.0",
"react-loadable-ssr-addon-v5-slorber": "^1.0.3",
"react-router": "^5.3.4",
"react-router-config": "^5.1.1",
"react-router-dom": "^5.3.4",
"history": "^5.3.0",
"react-router": "^8.0.1",
"semver": "^7.7.4",
"serve-handler": "^6.1.7",
"tinypool": "^2.1.0",
Expand All @@ -81,10 +80,7 @@
"@docusaurus/types": "3.10.1",
"@total-typescript/shoehorn": "^0.1.2",
"@types/escape-html": "^1.0.4",
"@types/history": "^4.7.11",
"@types/react-dom": "^19.2.3",
"@types/react-router-dom": "^5.3.3",
"@types/react-router-config": "^5.0.7",
"@types/serve-handler": "^6.1.4",
"@types/update-notifier": "^6.0.4",
"@types/webpack-bundle-analyzer": "^4.7.0",
Expand All @@ -94,8 +90,8 @@
"peerDependencies": {
"@docusaurus/faster": "*",
"@mdx-js/react": "^3.1.1",
"react": "^19.2.5",
"react-dom": "^19.2.5"
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"peerDependenciesMeta": {
"@docusaurus/faster": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import type {ReactElement, ReactNode} from 'react';
import type {ReactNode} from 'react';
import clientModules from '@generated/client-modules';
import useIsomorphicLayoutEffect from './exports/useIsomorphicLayoutEffect';
import type {ClientModule} from '@docusaurus/types';
Expand Down Expand Up @@ -63,7 +63,7 @@ function ClientLifecyclesDispatcher({
location,
previousLocation,
}: {
children: ReactElement;
children: ReactNode;
location: Location;
previousLocation: Location | null;
}): ReactNode {
Expand Down
5 changes: 1 addition & 4 deletions packages/docusaurus/src/client/PendingNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import React, {type ReactNode} from 'react';
import {Route} from 'react-router-dom';
import ClientLifecyclesDispatcher, {
dispatchLifecycleAction,
} from './ClientLifecyclesDispatcher';
Expand Down Expand Up @@ -82,13 +81,11 @@ class PendingNavigation extends React.Component<Props, State> {

override render(): ReactNode {
const {children, location} = this.props;
// Use a controlled <Route> to trick all descendants into rendering the old
// location.
return (
<ClientLifecyclesDispatcher
previousLocation={this.previousLocation}
location={location}>
<Route location={location} render={() => children} />
{children}
</ClientLifecyclesDispatcher>
);
}
Expand Down
36 changes: 31 additions & 5 deletions packages/docusaurus/src/client/clientEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,44 @@
import React, {startTransition, type ReactNode} from 'react';
import ReactDOM, {type ErrorInfo} from 'react-dom/client';
import {HelmetProvider} from 'react-helmet-async';
import {BrowserRouter, HashRouter} from 'react-router-dom';
import {parsePath} from 'react-router';
import {unstable_HistoryRouter as HistoryRouter} from 'react-router';
import {createBrowserHistory, createHashHistory} from 'history';
import siteConfig from '@generated/docusaurus.config';
import ExecutionEnvironment from './exports/ExecutionEnvironment';
import App from './App';
import preload from './preload';
import docusaurus from './docusaurus';
import {HistoryProvider} from './historyContext';
import type {History, To} from 'history';

type ReactRouterHistory = History & {
createURL: (to: To) => URL;
encodeLocation: (to: To) => Partial<Location>;
};

function addReactRouterHistoryMethods(history: History): ReactRouterHistory {
return Object.assign(history, {
createURL(to: To) {
return new URL(history.createHref(to), window.location.origin);
},
encodeLocation(to: To) {
return typeof to === 'string' ? parsePath(to) : to;
},
});
}

const history = addReactRouterHistoryMethods(
siteConfig.future.experimental_router === 'hash'
? createHashHistory()
: createBrowserHistory(),
);

function Router({children}: {children: ReactNode}): ReactNode {
return siteConfig.future.experimental_router === 'hash' ? (
<HashRouter>{children}</HashRouter>
) : (
<BrowserRouter>{children}</BrowserRouter>
return (
<HistoryProvider history={history}>
<HistoryRouter history={history as never}>{children}</HistoryRouter>
</HistoryProvider>
);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus/src/client/docusaurus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {matchRoutes} from 'react-router-config';
import {matchRoutes} from './exports/routerCompat';
import routesChunkNames from '@generated/routesChunkNames';
import routes from '@generated/routes';
import prefetchHelper from './prefetch';
Expand Down Expand Up @@ -55,7 +55,7 @@ const prefetch: Docusaurus['prefetch'] = (
fetched.add(routePath);

// Find all webpack chunk names needed.
const matches = matchRoutes(routes, routePath);
const matches = matchRoutes(routes as never, routePath);

const chunkNamesNeeded = matches.flatMap((match) =>
getChunkNamesToLoad(match.route.path),
Expand Down
Loading
Loading