diff --git a/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx index 43725ee1e1..babbadbe05 100644 --- a/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx @@ -8,17 +8,221 @@ import React from 'react'; import {renderHook} from '@testing-library/react-hooks'; import {fromPartial} from '@total-typescript/shoehorn'; -import useBaseUrl, {useBaseUrlUtils} from '../useBaseUrl'; +import useBaseUrl, {addBaseUrl, useBaseUrlUtils} from '../useBaseUrl'; import {Context} from '../../docusaurusContext'; import type {DocusaurusContext, FutureConfig} from '@docusaurus/types'; import type {BaseUrlOptions} from '@docusaurus/useBaseUrl'; +type AddBaseUrlParams = Parameters[0]; + const future: FutureConfig = fromPartial({ experimental_router: 'browser', }); const forcePrepend = {forcePrependBaseUrl: true}; +// TODO migrate more tests here, it's easier to test a pure function +describe('addBaseUrl', () => { + function baseTest(params: Partial) { + return addBaseUrl({ + siteUrl: 'https://docusaurus.io', + baseUrl: '/baseUrl/', + url: 'hello', + router: 'browser', + ...params, + }); + } + + describe('with browser router', () => { + function test(params: { + url: AddBaseUrlParams['url']; + baseUrl: AddBaseUrlParams['baseUrl']; + options?: AddBaseUrlParams['options']; + }) { + return baseTest({ + ...params, + router: 'browser', + }); + } + + it('/baseUrl/ + hello', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: 'hello', + }), + ).toBe('/baseUrl/hello'); + }); + + it('/baseUrl/ + hello - absolute option', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('https://docusaurus.io/baseUrl/hello'); + }); + + it('/baseUrl/ + /hello', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: '/hello', + }), + ).toBe('/baseUrl/hello'); + }); + + it('/baseUrl/ + /hello - absolute option', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: '/hello', + options: {absolute: true}, + }), + ).toBe('https://docusaurus.io/baseUrl/hello'); + }); + + it('/ + hello', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + }), + ).toBe('/hello'); + }); + + it('/ + hello - absolute', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('https://docusaurus.io/hello'); + }); + + it('/ + /hello', () => { + expect( + test({ + baseUrl: '/', + url: '/hello', + }), + ).toBe('/hello'); + }); + + it('/ + /hello - absolute', () => { + expect( + test({ + baseUrl: '/', + url: '/hello', + options: {absolute: true}, + }), + ).toBe('https://docusaurus.io/hello'); + }); + }); + + describe('with hash router', () => { + function test(params: { + url: AddBaseUrlParams['url']; + baseUrl: AddBaseUrlParams['baseUrl']; + options?: AddBaseUrlParams['options']; + }) { + return baseTest({ + ...params, + router: 'hash', + }); + } + + it('/baseUrl/ + hello', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: 'hello', + }), + ).toBe('./hello'); + }); + + it('/baseUrl/ + hello - absolute option', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('./hello'); + }); + + it('/baseUrl/ + /hello', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: '/hello', + }), + ).toBe('./hello'); + }); + + it('/baseUrl/ + /hello - absolute option', () => { + expect( + test({ + baseUrl: '/baseUrl/', + url: '/hello', + options: {absolute: true}, + }), + ).toBe('./hello'); + }); + + it('/ + hello', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + }), + ).toBe('./hello'); + }); + + it('/ + hello - absolute', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('./hello'); + }); + + it('/ + /hello', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('./hello'); + }); + + it('/ + /hello - absolute', () => { + expect( + test({ + baseUrl: '/', + url: 'hello', + options: {absolute: true}, + }), + ).toBe('./hello'); + }); + }); + + /* + +src +: +"img/docusaurus.svg" +srcDark +: +"img/docusaurus_keytar.svg" + */ +}); + describe('useBaseUrl', () => { const createUseBaseUrlMock = (context: DocusaurusContext) => (url: string, options?: BaseUrlOptions) => diff --git a/packages/docusaurus/src/client/exports/useBaseUrl.ts b/packages/docusaurus/src/client/exports/useBaseUrl.ts index f9d17b93a2..609e9c8447 100644 --- a/packages/docusaurus/src/client/exports/useBaseUrl.ts +++ b/packages/docusaurus/src/client/exports/useBaseUrl.ts @@ -11,7 +11,7 @@ import {hasProtocol} from './isInternalUrl'; import type {BaseUrlOptions, BaseUrlUtils} from '@docusaurus/useBaseUrl'; import type {RouterType} from '@docusaurus/types'; -function addBaseUrl({ +export function addBaseUrl({ siteUrl, baseUrl, url, @@ -30,9 +30,11 @@ function addBaseUrl({ return url; } - // TODO temp hack - if (router === 'hash' && url.startsWith('/')) { - return `.${url}`; + // TODO hash router + /baseUrl/ is unlikely to work well in all situations + // This will support most cases, but not all + // See https://github.com/facebook/docusaurus/pull/9859 + if (router === 'hash') { + return url.startsWith('/') ? `.${url}` : `./${url}`; } if (forcePrependBaseUrl) {