mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-25 12:38:57 +02:00
refactor useTitleFormatter() hook
This commit is contained in:
parent
fffb5a7213
commit
f414ebf442
5 changed files with 35 additions and 31 deletions
|
@ -43,7 +43,7 @@ export {
|
||||||
|
|
||||||
export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';
|
export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';
|
||||||
|
|
||||||
export {useTitleFormatter} from './utils/generalUtils';
|
export {useTitleFormatter} from './utils/titleFormatterUtils';
|
||||||
|
|
||||||
export {useLocationChange} from './utils/useLocationChange';
|
export {useLocationChange} from './utils/useLocationChange';
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {DefaultTitleFormatter} from '../generalUtils';
|
import {DefaultTitleFormatter} from '../titleFormatterUtils';
|
||||||
|
|
||||||
describe('DefaultTitleFormatter', () => {
|
describe('DefaultTitleFormatter', () => {
|
||||||
it('works', () => {
|
it('works', () => {
|
|
@ -10,7 +10,7 @@ import clsx from 'clsx';
|
||||||
import Head from '@docusaurus/Head';
|
import Head from '@docusaurus/Head';
|
||||||
import useRouteContext from '@docusaurus/useRouteContext';
|
import useRouteContext from '@docusaurus/useRouteContext';
|
||||||
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
||||||
import {useTitleFormatter} from './generalUtils';
|
import {useTitleFormatter} from './titleFormatterUtils';
|
||||||
|
|
||||||
type PageMetadataProps = {
|
type PageMetadataProps = {
|
||||||
readonly title?: string;
|
readonly title?: string;
|
||||||
|
@ -25,20 +25,21 @@ type PageMetadataProps = {
|
||||||
* Works in the same way as Helmet.
|
* Works in the same way as Helmet.
|
||||||
*/
|
*/
|
||||||
export function PageMetadata({
|
export function PageMetadata({
|
||||||
title,
|
title: pageTitle,
|
||||||
description,
|
description,
|
||||||
keywords,
|
keywords,
|
||||||
image,
|
image,
|
||||||
children,
|
children,
|
||||||
}: PageMetadataProps): ReactNode {
|
}: PageMetadataProps): ReactNode {
|
||||||
const pageTitle = useTitleFormatter(title);
|
const titleFormatter = useTitleFormatter();
|
||||||
const {withBaseUrl} = useBaseUrlUtils();
|
const {withBaseUrl} = useBaseUrlUtils();
|
||||||
const pageImage = image ? withBaseUrl(image, {absolute: true}) : undefined;
|
const pageImage = image ? withBaseUrl(image, {absolute: true}) : undefined;
|
||||||
|
|
||||||
|
const title = pageTitle ? titleFormatter.format(pageTitle) : undefined;
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
{title && <title>{pageTitle}</title>}
|
{title && <title>{title}</title>}
|
||||||
{title && <meta property="og:title" content={pageTitle} />}
|
{title && <meta property="og:title" content={title} />}
|
||||||
|
|
||||||
{description && <meta name="description" content={description} />}
|
{description && <meta name="description" content={description} />}
|
||||||
{description && <meta property="og:description" content={description} />}
|
{description && <meta property="og:description" content={description} />}
|
||||||
|
|
|
@ -27,12 +27,12 @@ export const DefaultTitleFormatter: TitleFormatterFn = ({
|
||||||
return `${trimmedTitle} ${titleDelimiter} ${siteTitle}`;
|
return `${trimmedTitle} ${titleDelimiter} ${siteTitle}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TitleFormatter = {format: (title?: string) => string};
|
type TitleFormatterUtils = {format: (title?: string) => string};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a function to format the page title
|
* Returns a function to format the page title
|
||||||
*/
|
*/
|
||||||
export function useTitleFormatter(): TitleFormatter {
|
export function useTitleFormatter(): TitleFormatterUtils {
|
||||||
const {siteConfig} = useDocusaurusContext();
|
const {siteConfig} = useDocusaurusContext();
|
||||||
const formatter = DefaultTitleFormatter;
|
const formatter = DefaultTitleFormatter;
|
||||||
const {title: siteTitle, titleDelimiter} = siteConfig;
|
const {title: siteTitle, titleDelimiter} = siteConfig;
|
|
@ -25,11 +25,11 @@ import Link from '@docusaurus/Link';
|
||||||
import {useAllDocsData} from '@docusaurus/plugin-content-docs/client';
|
import {useAllDocsData} from '@docusaurus/plugin-content-docs/client';
|
||||||
import {
|
import {
|
||||||
HtmlClassNameProvider,
|
HtmlClassNameProvider,
|
||||||
|
PageMetadata,
|
||||||
useEvent,
|
useEvent,
|
||||||
usePluralForm,
|
usePluralForm,
|
||||||
useSearchQueryString,
|
useSearchQueryString,
|
||||||
} from '@docusaurus/theme-common';
|
} from '@docusaurus/theme-common';
|
||||||
import {useTitleFormatter} from '@docusaurus/theme-common/internal';
|
|
||||||
import Translate, {translate} from '@docusaurus/Translate';
|
import Translate, {translate} from '@docusaurus/Translate';
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import {
|
import {
|
||||||
|
@ -160,6 +160,25 @@ type ResultDispatcher =
|
||||||
| {type: 'update'; value: ResultDispatcherState}
|
| {type: 'update'; value: ResultDispatcherState}
|
||||||
| {type: 'advance'; value?: undefined};
|
| {type: 'advance'; value?: undefined};
|
||||||
|
|
||||||
|
function getSearchPageTitle(searchQuery: string | undefined): string {
|
||||||
|
return searchQuery
|
||||||
|
? translate(
|
||||||
|
{
|
||||||
|
id: 'theme.SearchPage.existingResultsTitle',
|
||||||
|
message: 'Search results for "{query}"',
|
||||||
|
description: 'The search page title for non-empty query',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: searchQuery,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: translate({
|
||||||
|
id: 'theme.SearchPage.emptyResultsTitle',
|
||||||
|
message: 'Search the documentation',
|
||||||
|
description: 'The search page title for empty query',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function SearchPageContent(): ReactNode {
|
function SearchPageContent(): ReactNode {
|
||||||
const {
|
const {
|
||||||
i18n: {currentLocale},
|
i18n: {currentLocale},
|
||||||
|
@ -167,12 +186,13 @@ function SearchPageContent(): ReactNode {
|
||||||
const {
|
const {
|
||||||
algolia: {appId, apiKey, indexName, contextualSearch},
|
algolia: {appId, apiKey, indexName, contextualSearch},
|
||||||
} = useAlgoliaThemeConfig();
|
} = useAlgoliaThemeConfig();
|
||||||
|
|
||||||
const processSearchResultUrl = useSearchResultUrlProcessor();
|
const processSearchResultUrl = useSearchResultUrlProcessor();
|
||||||
const documentsFoundPlural = useDocumentsFoundPlural();
|
const documentsFoundPlural = useDocumentsFoundPlural();
|
||||||
|
|
||||||
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
|
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
|
||||||
const [searchQuery, setSearchQuery] = useSearchQueryString();
|
const [searchQuery, setSearchQuery] = useSearchQueryString();
|
||||||
|
const pageTitle = getSearchPageTitle(searchQuery);
|
||||||
|
|
||||||
const initialSearchResultState: ResultDispatcherState = {
|
const initialSearchResultState: ResultDispatcherState = {
|
||||||
items: [],
|
items: [],
|
||||||
query: null,
|
query: null,
|
||||||
|
@ -310,24 +330,6 @@ function SearchPageContent(): ReactNode {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const getTitle = () =>
|
|
||||||
searchQuery
|
|
||||||
? translate(
|
|
||||||
{
|
|
||||||
id: 'theme.SearchPage.existingResultsTitle',
|
|
||||||
message: 'Search results for "{query}"',
|
|
||||||
description: 'The search page title for non-empty query',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
query: searchQuery,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: translate({
|
|
||||||
id: 'theme.SearchPage.emptyResultsTitle',
|
|
||||||
message: 'Search the documentation',
|
|
||||||
description: 'The search page title for empty query',
|
|
||||||
});
|
|
||||||
|
|
||||||
const makeSearch = useEvent((page: number = 0) => {
|
const makeSearch = useEvent((page: number = 0) => {
|
||||||
if (contextualSearch) {
|
if (contextualSearch) {
|
||||||
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
|
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
|
||||||
|
@ -380,8 +382,9 @@ function SearchPageContent(): ReactNode {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
|
<PageMetadata title={pageTitle} />
|
||||||
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>{useTitleFormatter(getTitle())}</title>
|
|
||||||
{/*
|
{/*
|
||||||
We should not index search pages
|
We should not index search pages
|
||||||
See https://github.com/facebook/docusaurus/pull/3233
|
See https://github.com/facebook/docusaurus/pull/3233
|
||||||
|
@ -390,7 +393,7 @@ function SearchPageContent(): ReactNode {
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<div className="container margin-vert--lg">
|
<div className="container margin-vert--lg">
|
||||||
<Heading as="h1">{getTitle()}</Heading>
|
<Heading as="h1">{pageTitle}</Heading>
|
||||||
|
|
||||||
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue