diff --git a/jest.config.mjs b/jest.config.mjs index 5c241b301ed8..2bbb403b68be 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -12,6 +12,7 @@ process.env.TZ = 'UTC'; const ignorePatterns = [ '/node_modules/', '__fixtures__', + '__mocks__', '/testUtils.ts', '/packages/docusaurus/lib', '/packages/docusaurus-logger/lib', diff --git a/packages/docusaurus/src/client/__tests__/__mocks__/@generated/routes.ts b/packages/docusaurus/src/client/__tests__/__mocks__/@generated/routes.ts new file mode 100644 index 000000000000..ce2206070e1d --- /dev/null +++ b/packages/docusaurus/src/client/__tests__/__mocks__/@generated/routes.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export default [ + { + path: '/page.html', + exact: true, + component: '', + }, + { + path: '/docs', + exact: false, + component: '', + routes: [ + { + path: '/docs/installation', + exact: true, + component: '', + }, + ], + }, + { + path: '*', + component: '', + }, +]; diff --git a/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts b/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts index 9517a5b0f15d..fad94198575c 100644 --- a/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts +++ b/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts @@ -43,6 +43,33 @@ describe('normalizeLocation', () => { }); }); + it('removes html extension', () => { + expect( + normalizeLocation({ + pathname: '/docs/installation.html', + }), + ).toEqual({ + pathname: '/docs/installation', + }); + expect( + normalizeLocation({ + pathname: '/docs/introduction/foo.html', + search: '', + hash: '#bar', + }), + ).toEqual({ + pathname: '/docs/introduction/foo', + search: '', + hash: '#bar', + }); + }); + + it('does not strip extension if the route location has one', () => { + expect(normalizeLocation({pathname: '/page.html'})).toEqual({ + pathname: '/page.html', + }); + }); + it('leaves pathnames untouched', () => { const replaceMock = jest.spyOn(String.prototype, 'replace'); @@ -72,18 +99,6 @@ describe('normalizeLocation', () => { }); expect(replaceMock).toBeCalledTimes(1); - expect( - normalizeLocation({ - pathname: '/docs/introduction/foo.html', - search: '', - hash: '#bar', - }), - ).toEqual({ - pathname: '/docs/introduction/foo.html', - search: '', - hash: '#bar', - }); - expect( normalizeLocation({ pathname: '/', diff --git a/packages/docusaurus/src/client/normalizeLocation.ts b/packages/docusaurus/src/client/normalizeLocation.ts index 94a74da70044..74192a451c08 100644 --- a/packages/docusaurus/src/client/normalizeLocation.ts +++ b/packages/docusaurus/src/client/normalizeLocation.ts @@ -5,23 +5,33 @@ * LICENSE file in the root directory of this source tree. */ +import {matchRoutes} from 'react-router-config'; +import routes from '@generated/routes'; import type {Location} from 'history'; // Memoize previously normalized pathnames. -const pathnames: {[rawPathname: string]: string} = {}; +const pathnames = new Map(); export default function normalizeLocation(location: T): T { - if (pathnames[location.pathname]) { + if (pathnames.has(location.pathname)) { return { ...location, - pathname: pathnames[location.pathname], + pathname: pathnames.get(location.pathname), }; } + // If the location was registered with an `.html` extension, we don't strip it + // away, or it will render to a 404 page. + const matchedRoutes = matchRoutes(routes, location.pathname); + if (matchedRoutes.some(({route}) => route.exact === true)) { + pathnames.set(location.pathname, location.pathname); + return location; + } + const pathname = - location.pathname.trim().replace(/\/index\.html$/, '') || '/'; + location.pathname.trim().replace(/(?:\/index)?\.html$/, '') || '/'; - pathnames[location.pathname] = pathname; + pathnames.set(location.pathname, pathname); return { ...location, diff --git a/website/_dogfooding/_docs tests/dummy.md b/website/_dogfooding/_docs tests/dummy.md index ea913c996231..8ec7fc90fbdb 100644 --- a/website/_dogfooding/_docs tests/dummy.md +++ b/website/_dogfooding/_docs tests/dummy.md @@ -1 +1,5 @@ +--- +slug: dummy.html +--- + # Just a dummy page