feat(search-algolia): algolia externalUrl regex to navigate with window.href (#5795)

This commit is contained in:
Sergio Moreno 2021-10-29 19:53:47 +02:00 committed by GitHub
parent 8c12983a2a
commit adbc02ea38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 69 additions and 17 deletions

View file

@ -103,6 +103,20 @@ describe('validateThemeConfig', () => {
});
});
test('externalUrlRegex config', () => {
const algolia = {
indexName: 'index',
apiKey: 'apiKey',
externalUrlRegex: 'http://external-domain.com',
};
expect(testValidateThemeConfig({algolia})).toEqual({
algolia: {
...DEFAULT_CONFIG,
...algolia,
},
});
});
test('searchParameters.facetFilters search config', () => {
const algolia = {
indexName: 'index',

View file

@ -13,6 +13,7 @@ import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import Link from '@docusaurus/Link';
import Head from '@docusaurus/Head';
import useSearchQuery from '@theme/hooks/useSearchQuery';
import {isRegexpStringMatch} from '@docusaurus/theme-common';
import {DocSearchButton, useDocSearchKeyboardEvents} from '@docsearch/react';
import useAlgoliaContextualFacetFilters from '@theme/hooks/useAlgoliaContextualFacetFilters';
import {translate} from '@docusaurus/Translate';
@ -34,7 +35,7 @@ function ResultsFooter({state, onClose}) {
);
}
function DocSearch({contextualSearch, ...props}) {
function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
const {siteMetadata} = useDocusaurusContext();
const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters();
@ -102,21 +103,28 @@ function DocSearch({contextualSearch, ...props}) {
const navigator = useRef({
navigate({itemUrl}) {
history.push(itemUrl);
// Algolia results could contain URL's from other domains which cannot
// be served through history and should navigate with window.location
if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
window.location.href = itemUrl;
} else {
history.push(itemUrl);
}
},
}).current;
const transformItems = useRef((items) => {
return items.map((item) => {
// We transform the absolute URL into a relative URL.
// Alternatively, we can use `new URL(item.url)` but it's not
// supported in IE.
const a = document.createElement('a');
a.href = item.url;
// If Algolia contains a external domain, we should navigate without relative URL
if (isRegexpStringMatch(externalUrlRegex, item.url)) {
return item;
}
// We transform the absolute URL into a relative URL.
const url = new URL(item.url);
return {
...item,
url: withBaseUrl(`${a.pathname}${a.hash}`),
url: withBaseUrl(`${url.pathname}${url.hash}`),
};
});
}).current;

View file

@ -19,6 +19,7 @@ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import {
useTitleFormatter,
usePluralForm,
isRegexpStringMatch,
useDynamicCallback,
} from '@docusaurus/theme-common';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
@ -121,7 +122,7 @@ function SearchPage() {
const {
siteConfig: {
themeConfig: {
algolia: {appId, apiKey, indexName},
algolia: {appId, apiKey, indexName, externalUrlRegex},
},
},
i18n: {currentLocale},
@ -205,14 +206,16 @@ function SearchPage() {
_highlightResult: {hierarchy},
_snippetResult: snippet = {},
}) => {
const {pathname, hash} = new URL(url);
const parsedURL = new URL(url);
const titles = Object.keys(hierarchy).map((key) => {
return sanitizeValue(hierarchy[key].value);
});
return {
title: titles.pop(),
url: pathname + hash,
url: isRegexpStringMatch(externalUrlRegex, parsedURL.href)
? parsedURL.href
: parsedURL.pathname + parsedURL.hash,
summary: snippet.content
? `${sanitizeValue(snippet.content.value)}...`
: '',

View file

@ -22,7 +22,7 @@ const Schema = Joi.object({
algolia: Joi.object({
// Docusaurus attributes
contextualSearch: Joi.boolean().default(DEFAULT_CONFIG.contextualSearch),
externalUrlRegex: Joi.string().optional(),
// Algolia attributes
appId: Joi.string().default(DEFAULT_CONFIG.appId),
apiKey: Joi.string().required(),