@docusaurus/core 3.3.2 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/bin/docusaurus.mjs +13 -12
  2. package/lib/babel/preset.js +1 -1
  3. package/lib/client/App.d.ts +0 -2
  4. package/lib/client/BaseUrlIssueBanner/index.d.ts +0 -1
  5. package/lib/client/BrokenLinksContext.d.ts +0 -1
  6. package/lib/client/SiteMetadataDefaults.d.ts +0 -1
  7. package/lib/client/clientEntry.js +7 -3
  8. package/lib/client/exports/BrowserOnly.d.ts +0 -2
  9. package/lib/client/exports/ErrorBoundary.d.ts +0 -1
  10. package/lib/client/exports/Head.d.ts +0 -2
  11. package/lib/client/exports/Interpolate.d.ts +0 -1
  12. package/lib/client/exports/Link.d.ts +0 -1
  13. package/lib/client/exports/Link.js +26 -5
  14. package/lib/client/exports/Translate.d.ts +0 -2
  15. package/lib/client/exports/useBaseUrl.d.ts +8 -1
  16. package/lib/client/exports/useBaseUrl.js +11 -3
  17. package/lib/client/exports/useBrokenLinks.d.ts +0 -1
  18. package/lib/client/hasHydratedDataAttribute.d.ts +0 -1
  19. package/lib/client/theme-fallback/Error/index.d.ts +0 -2
  20. package/lib/client/theme-fallback/Layout/index.d.ts +0 -2
  21. package/lib/client/theme-fallback/Loading/index.d.ts +0 -1
  22. package/lib/client/theme-fallback/NotFound/index.d.ts +0 -1
  23. package/lib/client/theme-fallback/Root/index.d.ts +0 -2
  24. package/lib/client/theme-fallback/SiteMetadata/index.d.ts +0 -1
  25. package/lib/commands/build.js +36 -23
  26. package/lib/commands/clear.js +1 -2
  27. package/lib/commands/deploy.js +1 -2
  28. package/lib/commands/external.js +1 -2
  29. package/lib/commands/serve.js +16 -6
  30. package/lib/commands/start/start.js +1 -2
  31. package/lib/commands/start/utils.d.ts +3 -2
  32. package/lib/commands/start/utils.js +9 -5
  33. package/lib/commands/start/watcher.js +5 -6
  34. package/lib/commands/start/webpack.js +4 -5
  35. package/lib/commands/swizzle/actions.js +4 -4
  36. package/lib/commands/swizzle/common.js +7 -7
  37. package/lib/commands/swizzle/components.js +5 -6
  38. package/lib/commands/swizzle/config.js +2 -3
  39. package/lib/commands/swizzle/context.js +19 -8
  40. package/lib/commands/swizzle/index.js +1 -2
  41. package/lib/commands/swizzle/prompts.js +4 -5
  42. package/lib/commands/swizzle/tables.js +2 -3
  43. package/lib/commands/swizzle/themes.js +5 -6
  44. package/lib/commands/writeHeadingIds.js +1 -2
  45. package/lib/commands/writeTranslations.js +1 -2
  46. package/lib/server/brokenLinks.js +10 -3
  47. package/lib/server/clientModules.js +1 -2
  48. package/lib/server/codegen/codegen.d.ts +2 -1
  49. package/lib/server/codegen/codegen.js +5 -2
  50. package/lib/server/codegen/codegenRoutes.d.ts +1 -0
  51. package/lib/server/codegen/codegenRoutes.js +22 -9
  52. package/lib/server/config.js +1 -2
  53. package/lib/server/configValidation.d.ts +4 -1
  54. package/lib/server/configValidation.js +30 -2
  55. package/lib/server/getHostPort.js +1 -2
  56. package/lib/server/htmlTags.d.ts +5 -2
  57. package/lib/server/htmlTags.js +16 -8
  58. package/lib/server/i18n.js +39 -11
  59. package/lib/server/plugins/actions.js +1 -2
  60. package/lib/server/plugins/configs.js +1 -2
  61. package/lib/server/plugins/init.d.ts +11 -0
  62. package/lib/server/plugins/init.js +42 -7
  63. package/lib/server/plugins/moduleShorthand.d.ts +0 -1
  64. package/lib/server/plugins/moduleShorthand.js +2 -3
  65. package/lib/server/plugins/pluginIds.js +1 -2
  66. package/lib/server/plugins/plugins.js +2 -3
  67. package/lib/server/plugins/pluginsUtils.js +7 -8
  68. package/lib/server/plugins/presets.js +1 -2
  69. package/lib/server/plugins/routeConfig.js +2 -3
  70. package/lib/server/plugins/synthetic.js +2 -3
  71. package/lib/server/routes.js +2 -3
  72. package/lib/server/site.js +17 -10
  73. package/lib/server/siteMetadata.js +3 -4
  74. package/lib/server/storage.d.ts +13 -0
  75. package/lib/server/storage.js +35 -0
  76. package/lib/server/translations/translations.js +9 -10
  77. package/lib/server/translations/translationsExtractor.js +4 -5
  78. package/lib/server/utils.js +1 -2
  79. package/lib/ssg.d.ts +4 -1
  80. package/lib/ssg.js +10 -3
  81. package/lib/templates/templates.d.ts +3 -0
  82. package/lib/templates/templates.js +27 -3
  83. package/lib/webpack/aliases/index.js +4 -5
  84. package/lib/webpack/base.js +4 -4
  85. package/lib/webpack/client.js +13 -22
  86. package/lib/webpack/configure.d.ts +25 -0
  87. package/lib/webpack/configure.js +99 -0
  88. package/lib/webpack/minification.js +1 -2
  89. package/lib/webpack/plugins/ForceTerminatePlugin.d.ts +10 -0
  90. package/lib/webpack/plugins/ForceTerminatePlugin.js +25 -0
  91. package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.d.ts +11 -0
  92. package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.js +38 -0
  93. package/lib/webpack/server.js +1 -29
  94. package/lib/webpack/utils.d.ts +1 -24
  95. package/lib/webpack/utils.js +8 -87
  96. package/package.json +10 -10
@@ -222,7 +222,8 @@ cli
222
222
 
223
223
  cli.arguments('<command>').action((cmd) => {
224
224
  cli.outputHelp();
225
- logger.error` Unknown command name=${cmd}.`;
225
+ logger.error`Unknown Docusaurus CLI command name=${cmd}.`;
226
+ process.exit(1);
226
227
  });
227
228
 
228
229
  // === The above is the commander configuration ===
@@ -247,24 +248,24 @@ function isInternalCommand(command) {
247
248
  );
248
249
  }
249
250
 
250
- // process.argv always looks like this:
251
- // [
252
- // '/path/to/node',
253
- // '/path/to/docusaurus.mjs',
254
- // '<subcommand>',
255
- // ...subcommandArgs
256
- // ]
251
+ /**
252
+ * @param {string | undefined} command
253
+ */
254
+ function isExternalCommand(command) {
255
+ return !!(command && !isInternalCommand(command) && !command.startsWith('-'));
256
+ }
257
257
 
258
- // There is no subcommand
259
- // TODO: can we use commander to handle this case?
260
- if (process.argv.length < 3 || process.argv[2]?.startsWith('--')) {
258
+ // No command? We print the help message because Commander doesn't
259
+ // Note argv looks like this: ['../node','../docusaurus.mjs','<command>',...rest]
260
+ if (process.argv.length < 3) {
261
261
  cli.outputHelp();
262
+ logger.error`Please provide a Docusaurus CLI command.`;
262
263
  process.exit(1);
263
264
  }
264
265
 
265
266
  // There is an unrecognized subcommand
266
267
  // Let plugins extend the CLI before parsing
267
- if (!isInternalCommand(process.argv[2])) {
268
+ if (isExternalCommand(process.argv[2])) {
268
269
  // TODO: in this step, we must assume default site structure because there's
269
270
  // no way to know the siteDir/config yet. Maybe the root cli should be
270
271
  // responsible for parsing these arguments?
@@ -6,6 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.default = babelPresets;
9
10
  const tslib_1 = require("tslib");
10
11
  const path_1 = tslib_1.__importDefault(require("path"));
11
12
  function getTransformOptions(isServer) {
@@ -77,4 +78,3 @@ function babelPresets(api) {
77
78
  const callerName = api.caller((caller) => caller?.name);
78
79
  return getTransformOptions(callerName === 'server');
79
80
  }
80
- exports.default = babelPresets;
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import '@generated/client-modules';
10
8
  export default function App(): JSX.Element;
@@ -4,7 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  import './styles.module.css';
9
8
  /**
10
9
  * We want to help the users with a bad baseUrl configuration (very common
@@ -4,7 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import { type ReactNode } from 'react';
9
8
  import type { BrokenLinks } from '@docusaurus/useBrokenLinks';
10
9
  export type StatefulBrokenLinks = BrokenLinks & {
@@ -4,5 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  export default function SiteMetadataDefaults(): JSX.Element;
@@ -6,12 +6,16 @@
6
6
  */
7
7
  import React, { startTransition } from 'react';
8
8
  import ReactDOM from 'react-dom/client';
9
- import { BrowserRouter } from 'react-router-dom';
10
9
  import { HelmetProvider } from 'react-helmet-async';
10
+ import { BrowserRouter, HashRouter } from 'react-router-dom';
11
+ import siteConfig from '@generated/docusaurus.config';
11
12
  import ExecutionEnvironment from './exports/ExecutionEnvironment';
12
13
  import App from './App';
13
14
  import preload from './preload';
14
15
  import docusaurus from './docusaurus';
16
+ function Router({ children }) {
17
+ return siteConfig.future.experimental_router === 'hash' ? (<HashRouter>{children}</HashRouter>) : (<BrowserRouter>{children}</BrowserRouter>);
18
+ }
15
19
  const hydrate = Boolean(process.env.HYDRATE_CLIENT_ENTRY);
16
20
  // Client-side render (e.g: running in browser) to become single-page
17
21
  // application (SPA).
@@ -19,9 +23,9 @@ if (ExecutionEnvironment.canUseDOM) {
19
23
  window.docusaurus = docusaurus;
20
24
  const container = document.getElementById('__docusaurus');
21
25
  const app = (<HelmetProvider>
22
- <BrowserRouter>
26
+ <Router>
23
27
  <App />
24
- </BrowserRouter>
28
+ </Router>
25
29
  </HelmetProvider>);
26
30
  const onRecoverableError = (error, errorInfo) => {
27
31
  console.error('Docusaurus React Root onRecoverableError:', error, errorInfo);
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import type { Props } from '@docusaurus/BrowserOnly';
10
8
  export default function BrowserOnly({ children, fallback, }: Props): JSX.Element | null;
@@ -4,7 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import React, { type ReactNode } from 'react';
9
8
  import type { Props } from '@docusaurus/ErrorBoundary';
10
9
  type State = {
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import type { Props } from '@docusaurus/Head';
10
8
  export default function Head(props: Props): JSX.Element;
@@ -4,7 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import { type ReactNode } from 'react';
9
8
  import type { InterpolateProps, InterpolateValues } from '@docusaurus/Interpolate';
10
9
  export declare function interpolate<Str extends string>(text: Str, values?: InterpolateValues<Str, string | number>): string;
@@ -4,7 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import React from 'react';
9
8
  import type { Props } from '@docusaurus/Link';
10
9
  declare const _default: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
@@ -19,7 +19,9 @@ import { useBaseUrlUtils } from './useBaseUrl';
19
19
  // like "introduction" to "/baseUrl/introduction" => bad behavior to fix
20
20
  const shouldAddBaseUrlAutomatically = (to) => to.startsWith('/');
21
21
  function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLinkCheck': noBrokenLinkCheck, autoAddBaseUrl = true, ...props }, forwardedRef) {
22
- const { siteConfig: { trailingSlash, baseUrl }, } = useDocusaurusContext();
22
+ const { siteConfig } = useDocusaurusContext();
23
+ const { trailingSlash, baseUrl } = siteConfig;
24
+ const router = siteConfig.future.experimental_router;
23
25
  const { withBaseUrl } = useBaseUrlUtils();
24
26
  const brokenLinks = useBrokenLinks();
25
27
  const innerRef = useRef(null);
@@ -47,6 +49,14 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
47
49
  let targetLink = typeof targetLinkWithoutPathnameProtocol !== 'undefined'
48
50
  ? maybeAddBaseUrl(targetLinkWithoutPathnameProtocol)
49
51
  : undefined;
52
+ // TODO find a way to solve this problem properly
53
+ // Fix edge case when useBaseUrl is used on a link
54
+ // "./" is useful for images and other resources
55
+ // But we don't need it for <Link>
56
+ // unfortunately we can't really make the difference :/
57
+ if (router === 'hash' && targetLink?.startsWith('./')) {
58
+ targetLink = targetLink?.slice(1);
59
+ }
50
60
  if (targetLink && isInternal) {
51
61
  targetLink = applyTrailingSlash(targetLink, { trailingSlash, baseUrl });
52
62
  }
@@ -85,7 +95,7 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
85
95
  };
86
96
  useEffect(() => {
87
97
  // If IO is not supported. We prefetch by default (only once).
88
- if (!IOSupported && isInternal) {
98
+ if (!IOSupported && isInternal && ExecutionEnvironment.canUseDOM) {
89
99
  if (targetLink != null) {
90
100
  window.docusaurus.prefetch(targetLink);
91
101
  }
@@ -103,19 +113,30 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
103
113
  // https://github.com/remix-run/react-router/blob/v5/packages/react-router-dom/modules/Link.js#L47
104
114
  const hasInternalTarget = !props.target || props.target === '_self';
105
115
  // Should we use a regular <a> tag instead of React-Router Link component?
106
- const isRegularHtmlLink = !targetLink || !isInternal || !hasInternalTarget || isAnchorLink;
116
+ const isRegularHtmlLink = !targetLink ||
117
+ !isInternal ||
118
+ !hasInternalTarget ||
119
+ // When using the hash router, we can't use the regular <a> link for anchors
120
+ // We need to use React Router to navigate to /#/pathname/#anchor
121
+ // And not /#anchor
122
+ // See also https://github.com/facebook/docusaurus/pull/10311
123
+ (isAnchorLink && router !== 'hash');
107
124
  if (!noBrokenLinkCheck && (isAnchorLink || !isRegularHtmlLink)) {
108
125
  brokenLinks.collectLink(targetLink);
109
126
  }
110
127
  if (props.id) {
111
128
  brokenLinks.collectAnchor(props.id);
112
129
  }
130
+ // These props are only added in unit tests to assert/capture the type of link
131
+ const testOnlyProps = process.env.NODE_ENV === 'test'
132
+ ? { 'data-test-link-type': isRegularHtmlLink ? 'regular' : 'react-router' }
133
+ : {};
113
134
  return isRegularHtmlLink ? (
114
135
  // eslint-disable-next-line jsx-a11y/anchor-has-content, @docusaurus/no-html-links
115
136
  <a ref={innerRef} href={targetLink} {...(targetLinkUnprefixed &&
116
- !isInternal && { target: '_blank', rel: 'noopener noreferrer' })} {...props}/>) : (<LinkComponent {...props} onMouseEnter={onInteractionEnter} onTouchStart={onInteractionEnter} innerRef={handleRef} to={targetLink}
137
+ !isInternal && { target: '_blank', rel: 'noopener noreferrer' })} {...props} {...testOnlyProps}/>) : (<LinkComponent {...props} onMouseEnter={onInteractionEnter} onTouchStart={onInteractionEnter} innerRef={handleRef} to={targetLink}
117
138
  // Avoid "React does not recognize the `activeClassName` prop on a DOM
118
139
  // element"
119
- {...(isNavLink && { isActive, activeClassName })}/>);
140
+ {...(isNavLink && { isActive, activeClassName })} {...testOnlyProps}/>);
120
141
  }
121
142
  export default React.forwardRef(Link);
@@ -4,8 +4,6 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import { type InterpolateValues } from '@docusaurus/Interpolate';
10
8
  import type { TranslateParam, TranslateProps } from '@docusaurus/Translate';
11
9
  export declare function translate<Str extends string>({ message, id }: TranslateParam<Str>, values?: InterpolateValues<Str, string | number>): string;
@@ -4,7 +4,14 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import type { BaseUrlOptions, BaseUrlUtils } from '@docusaurus/useBaseUrl';
8
+ import type { RouterType } from '@docusaurus/types';
9
+ export declare function addBaseUrl({ siteUrl, baseUrl, url, options: { forcePrependBaseUrl, absolute }, router, }: {
10
+ siteUrl: string;
11
+ baseUrl: string;
12
+ url: string;
13
+ router: RouterType;
14
+ options?: BaseUrlOptions;
15
+ }): string;
9
16
  export declare function useBaseUrlUtils(): BaseUrlUtils;
10
17
  export default function useBaseUrl(url: string, options?: BaseUrlOptions): string;
@@ -7,12 +7,18 @@
7
7
  import { useCallback } from 'react';
8
8
  import useDocusaurusContext from './useDocusaurusContext';
9
9
  import { hasProtocol } from './isInternalUrl';
10
- function addBaseUrl(siteUrl, baseUrl, url, { forcePrependBaseUrl = false, absolute = false } = {}) {
10
+ export function addBaseUrl({ siteUrl, baseUrl, url, options: { forcePrependBaseUrl = false, absolute = false } = {}, router, }) {
11
11
  // It never makes sense to add base url to a local anchor url, or one with a
12
12
  // protocol
13
13
  if (!url || url.startsWith('#') || hasProtocol(url)) {
14
14
  return url;
15
15
  }
16
+ // TODO hash router + /baseUrl/ is unlikely to work well in all situations
17
+ // This will support most cases, but not all
18
+ // See https://github.com/facebook/docusaurus/pull/9859
19
+ if (router === 'hash') {
20
+ return url.startsWith('/') ? `.${url}` : `./${url}`;
21
+ }
16
22
  if (forcePrependBaseUrl) {
17
23
  return baseUrl + url.replace(/^\//, '');
18
24
  }
@@ -27,8 +33,10 @@ function addBaseUrl(siteUrl, baseUrl, url, { forcePrependBaseUrl = false, absolu
27
33
  return absolute ? siteUrl + basePath : basePath;
28
34
  }
29
35
  export function useBaseUrlUtils() {
30
- const { siteConfig: { baseUrl, url: siteUrl }, } = useDocusaurusContext();
31
- const withBaseUrl = useCallback((url, options) => addBaseUrl(siteUrl, baseUrl, url, options), [siteUrl, baseUrl]);
36
+ const { siteConfig } = useDocusaurusContext();
37
+ const { baseUrl, url: siteUrl } = siteConfig;
38
+ const router = siteConfig.future.experimental_router;
39
+ const withBaseUrl = useCallback((url, options) => addBaseUrl({ siteUrl, baseUrl, url, options, router }), [siteUrl, baseUrl, router]);
32
40
  return {
33
41
  withBaseUrl,
34
42
  };
@@ -4,6 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
7
  import type { BrokenLinks } from '@docusaurus/useBrokenLinks';
9
8
  export default function useBrokenLinks(): BrokenLinks;
@@ -4,5 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  export default function HasHydratedDataAttribute(): JSX.Element;
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import type { Props } from '@theme/Error';
10
8
  export default function Error({ error, tryAgain }: Props): JSX.Element;
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import type { Props } from '@theme/Layout';
10
8
  export default function Layout({ children }: Props): JSX.Element;
@@ -4,6 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  import type { LoadingComponentProps } from 'react-loadable';
9
8
  export default function Loading({ error, retry, pastDelay, }: LoadingComponentProps): JSX.Element | null;
@@ -4,5 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  export default function NotFound(): JSX.Element;
@@ -4,7 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="@docusaurus/module-type-aliases" />
8
- /// <reference types="react" />
9
7
  import type { Props } from '@theme/Root';
10
8
  export default function Root({ children }: Props): JSX.Element;
@@ -4,5 +4,4 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- /// <reference types="react" />
8
7
  export default function SiteMetadata(): JSX.Element | null;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.build = void 0;
9
+ exports.build = build;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -17,6 +17,7 @@ const site_1 = require("../server/site");
17
17
  const brokenLinks_1 = require("../server/brokenLinks");
18
18
  const client_1 = require("../webpack/client");
19
19
  const server_1 = tslib_1.__importDefault(require("../webpack/server"));
20
+ const configure_1 = require("../webpack/configure");
20
21
  const utils_2 = require("../webpack/utils");
21
22
  const utils_3 = require("../utils");
22
23
  const i18n_1 = require("../server/i18n");
@@ -71,7 +72,6 @@ forceTerminate = true) {
71
72
  }
72
73
  }));
73
74
  }
74
- exports.build = build;
75
75
  async function getLocalesToBuild({ siteDir, cliOptions, }) {
76
76
  if (cliOptions.locale) {
77
77
  return [cliOptions.locale];
@@ -110,7 +110,8 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
110
110
  localizePath: cliOptions.locale ? false : undefined,
111
111
  }));
112
112
  const { props } = site;
113
- const { outDir, plugins } = props;
113
+ const { outDir, plugins, siteConfig } = props;
114
+ const router = siteConfig.future.experimental_router;
114
115
  // We can build the 2 configs in parallel
115
116
  const [{ clientConfig, clientManifestPath }, { serverConfig, serverBundlePath }] = await utils_3.PerfLogger.async('Creating webpack configs', () => Promise.all([
116
117
  getBuildClientConfig({
@@ -122,11 +123,19 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
122
123
  }),
123
124
  ]));
124
125
  // Run webpack to build JS bundle (client) and static html files (server).
125
- await utils_3.PerfLogger.async('Bundling with Webpack', () => (0, utils_2.compile)([clientConfig, serverConfig]));
126
+ await utils_3.PerfLogger.async('Bundling with Webpack', () => {
127
+ if (router === 'hash') {
128
+ return (0, utils_2.compile)([clientConfig]);
129
+ }
130
+ else {
131
+ return (0, utils_2.compile)([clientConfig, serverConfig]);
132
+ }
133
+ });
126
134
  const { collectedData } = await utils_3.PerfLogger.async('SSG', () => executeSSG({
127
135
  props,
128
136
  serverBundlePath,
129
137
  clientManifestPath,
138
+ router,
130
139
  }));
131
140
  // Remove server.bundle.js because it is not needed.
132
141
  await utils_3.PerfLogger.async('Deleting server bundle', () => ensureUnlink(serverBundlePath));
@@ -137,27 +146,35 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
137
146
  logger_1.default.success `Generated static files in path=${path_1.default.relative(process.cwd(), outDir)}.`;
138
147
  return outDir;
139
148
  }
140
- async function executeSSG({ props, serverBundlePath, clientManifestPath, }) {
149
+ async function executeSSG({ props, serverBundlePath, clientManifestPath, router, }) {
141
150
  const manifest = await utils_3.PerfLogger.async('Read client manifest', () => fs_extra_1.default.readJSON(clientManifestPath, 'utf-8'));
142
151
  const ssrTemplate = await utils_3.PerfLogger.async('Compile SSR template', () => (0, templates_1.compileSSRTemplate)(props.siteConfig.ssrTemplate ?? ssr_html_template_1.default));
152
+ const params = {
153
+ trailingSlash: props.siteConfig.trailingSlash,
154
+ outDir: props.outDir,
155
+ baseUrl: props.baseUrl,
156
+ manifest,
157
+ headTags: props.headTags,
158
+ preBodyTags: props.preBodyTags,
159
+ postBodyTags: props.postBodyTags,
160
+ ssrTemplate,
161
+ noIndex: props.siteConfig.noIndex,
162
+ DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
163
+ };
164
+ if (router === 'hash') {
165
+ utils_3.PerfLogger.start('Generate Hash Router entry point');
166
+ const content = (0, templates_1.renderHashRouterTemplate)({ params });
167
+ await (0, ssg_1.generateHashRouterEntrypoint)({ content, params });
168
+ utils_3.PerfLogger.end('Generate Hash Router entry point');
169
+ return { collectedData: {} };
170
+ }
143
171
  const renderer = await utils_3.PerfLogger.async('Load App renderer', () => (0, ssg_1.loadAppRenderer)({
144
172
  serverBundlePath,
145
173
  }));
146
174
  const ssgResult = await utils_3.PerfLogger.async('Generate static files', () => (0, ssg_1.generateStaticFiles)({
147
175
  pathnames: props.routesPaths,
148
176
  renderer,
149
- params: {
150
- trailingSlash: props.siteConfig.trailingSlash,
151
- outDir: props.outDir,
152
- baseUrl: props.baseUrl,
153
- manifest,
154
- headTags: props.headTags,
155
- preBodyTags: props.preBodyTags,
156
- postBodyTags: props.postBodyTags,
157
- ssrTemplate,
158
- noIndex: props.siteConfig.noIndex,
159
- DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
160
- },
177
+ params,
161
178
  }));
162
179
  return ssgResult;
163
180
  }
@@ -194,11 +211,7 @@ async function getBuildClientConfig({ props, cliOptions, }) {
194
211
  bundleAnalyzer: cliOptions.bundleAnalyzer ?? false,
195
212
  });
196
213
  let { config } = result;
197
- config = (0, utils_2.executePluginsConfigurePostCss)({
198
- plugins,
199
- config,
200
- });
201
- config = (0, utils_2.executePluginsConfigureWebpack)({
214
+ config = (0, configure_1.executePluginsConfigureWebpack)({
202
215
  plugins,
203
216
  config,
204
217
  isServer: false,
@@ -212,7 +225,7 @@ async function getBuildServerConfig({ props }) {
212
225
  props,
213
226
  });
214
227
  let { config } = result;
215
- config = (0, utils_2.executePluginsConfigureWebpack)({
228
+ config = (0, configure_1.executePluginsConfigureWebpack)({
216
229
  plugins,
217
230
  config,
218
231
  isServer: true,
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.clear = void 0;
9
+ exports.clear = clear;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -42,4 +42,3 @@ async function clear(siteDirParam = '.') {
42
42
  }));
43
43
  await Promise.all([generatedFolder, buildFolder, ...cacheFolders].map(removePath));
44
44
  }
45
- exports.clear = clear;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.deploy = void 0;
9
+ exports.deploy = deploy;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -196,4 +196,3 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
196
196
  await runDeploy(outDir);
197
197
  }
198
198
  }
199
- exports.deploy = deploy;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.externalCommand = void 0;
9
+ exports.externalCommand = externalCommand;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const site_1 = require("../server/site");
@@ -20,4 +20,3 @@ async function externalCommand(cli) {
20
20
  plugin.extendCli?.(cli);
21
21
  });
22
22
  }
23
- exports.externalCommand = externalCommand;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.serve = void 0;
9
+ exports.serve = serve;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const http_1 = tslib_1.__importDefault(require("http"));
@@ -52,10 +52,21 @@ async function serve(siteDirParam = '.', cliOptions = {}) {
52
52
  }
53
53
  // We do the redirect ourselves for a good reason
54
54
  // server-handler is annoying and won't include /baseUrl/ in redirects
55
- const normalizedUrl = (0, utils_common_1.applyTrailingSlash)(req.url, { trailingSlash, baseUrl });
56
- if (req.url !== normalizedUrl) {
57
- redirect(res, normalizedUrl);
58
- return;
55
+ // See https://github.com/facebook/docusaurus/issues/10078#issuecomment-2084932934
56
+ if (baseUrl !== '/') {
57
+ // Not super robust, but should be good enough for our use case
58
+ // See https://github.com/facebook/docusaurus/pull/10090
59
+ const looksLikeAsset = !!req.url.match(/\.[a-zA-Z\d]{1,4}$/);
60
+ if (!looksLikeAsset) {
61
+ const normalizedUrl = (0, utils_common_1.applyTrailingSlash)(req.url, {
62
+ trailingSlash,
63
+ baseUrl,
64
+ });
65
+ if (req.url !== normalizedUrl) {
66
+ redirect(res, normalizedUrl);
67
+ return;
68
+ }
69
+ }
59
70
  }
60
71
  // Remove baseUrl before calling serveHandler, because /baseUrl/ should
61
72
  // serve /build/index.html, not /build/baseUrl/index.html (does not exist)
@@ -78,4 +89,3 @@ async function serve(siteDirParam = '.', cliOptions = {}) {
78
89
  (0, openBrowser_1.default)(url);
79
90
  }
80
91
  }
81
- exports.serve = serve;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.start = void 0;
9
+ exports.start = start;
10
10
  const tslib_1 = require("tslib");
11
11
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
12
  const openBrowser_1 = tslib_1.__importDefault(require("react-dev-utils/openBrowser"));
@@ -44,4 +44,3 @@ async function start(siteDirParam = '.', cliOptions = {}) {
44
44
  (0, openBrowser_1.default)(reloadableSite.getOpenUrl());
45
45
  }
46
46
  }
47
- exports.start = start;
@@ -6,12 +6,13 @@
6
6
  */
7
7
  import _ from 'lodash';
8
8
  import type { StartCLIOptions } from './start';
9
- import type { LoadedPlugin } from '@docusaurus/types';
9
+ import type { LoadedPlugin, RouterType } from '@docusaurus/types';
10
10
  export type OpenUrlContext = {
11
11
  host: string;
12
12
  port: number;
13
- getOpenUrl: ({ baseUrl }: {
13
+ getOpenUrl: ({ baseUrl, router, }: {
14
14
  baseUrl: string;
15
+ router: RouterType;
15
16
  }) => string;
16
17
  };
17
18
  export declare function createOpenUrlContext({ cliOptions, }: {