Skip to content

Commit

Permalink
Make it possible to switch router dynamically
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Feb 23, 2024
1 parent 030688a commit 62aa2cb
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
13 changes: 13 additions & 0 deletions packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ declare module '@generated/routes' {
export default routes;
}

declare module '@generated/router' {
import type {ReactNode, ComponentType} from 'react';

export type Props = {
basename?: string | undefined;
children?: ReactNode;
};

const Router: ComponentType<Props>;

export default Router;
}

declare module '@generated/routesChunkNames' {
import type {RouteChunkNames} from '@docusaurus/types';

Expand Down
10 changes: 4 additions & 6 deletions packages/docusaurus/src/client/clientEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React from 'react';
import ReactDOM, {type ErrorInfo} from 'react-dom/client';
import {HashRouter} from 'react-router-dom';
import Router from '@generated/router';
import {HelmetProvider} from 'react-helmet-async';

import ExecutionEnvironment from './exports/ExecutionEnvironment';
Expand All @@ -31,9 +31,9 @@ if (ExecutionEnvironment.canUseDOM) {

const app = (
<HelmetProvider>
<HashRouter>
<Router>
<App />
</HashRouter>
</Router>
</HelmetProvider>
);

Expand All @@ -45,10 +45,8 @@ if (ExecutionEnvironment.canUseDOM) {
);
};

const localBuild = true;

const renderApp = () => {
if (!localBuild && hydrate) {
if (hydrate) {
React.startTransition(() => {
ReactDOM.hydrateRoot(container, app, {
onRecoverableError,
Expand Down
9 changes: 9 additions & 0 deletions packages/docusaurus/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ ${Object.entries(registry)
JSON.stringify(siteMetadata, null, 2),
);

const routerImport =
siteConfig.router === 'hash' ? 'HashRouter' : 'BrowserRouter';
const genRouter = generate(
generatedFilesDir,
'router.js',
`export {${routerImport} as default} from 'react-router-dom';`,
);

await Promise.all([
genWarning,
genClientModules,
Expand All @@ -243,6 +251,7 @@ ${Object.entries(registry)
genSiteMetadata,
genI18n,
genCodeTranslations,
genRouter,
]);

return {
Expand Down
11 changes: 9 additions & 2 deletions packages/docusaurus/src/webpack/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,22 @@ export async function createBuildClientConfig({
bundleAnalyzer: boolean;
}): Promise<{config: Configuration; clientManifestPath: string}> {
// Apply user webpack config.
const {generatedFilesDir} = props;
const {
generatedFilesDir,
siteConfig: {router},
} = props;

// With the hash router, we don't hydrate the React app, even in build mode!
// This is because it will always be a client-rendered React app
const hydrate = router !== 'hash';

const clientManifestPath = path.join(
generatedFilesDir,
'client-manifest.json',
);

const config: Configuration = merge(
await createBaseClientConfig({props, minify, hydrate: true}),
await createBaseClientConfig({props, minify, hydrate}),
{
plugins: [
new ForceTerminatePlugin(),
Expand Down

0 comments on commit 62aa2cb

Please sign in to comment.