mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-02 03:37:48 +02:00
misc: replace all "Metadatas" with "Metadata" (#5871)
Co-authored-by: Josh-Cena <sidachen2003@gmail.com>
This commit is contained in:
parent
eab8c7c010
commit
c541e2d83c
36 changed files with 107 additions and 106 deletions
|
@ -26,7 +26,7 @@ A new document is now available at `http://localhost:3000/docs/hello`.
|
||||||
|
|
||||||
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
||||||
|
|
||||||
Add metadatas to customize the sidebar label and position:
|
Add metadata to customize the sidebar label and position:
|
||||||
|
|
||||||
```md title="docs/hello.md" {1-4}
|
```md title="docs/hello.md" {1-4}
|
||||||
---
|
---
|
||||||
|
|
|
@ -26,7 +26,7 @@ A new document is now available at `http://localhost:3000/docs/hello`.
|
||||||
|
|
||||||
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
||||||
|
|
||||||
Add metadatas to customize the sidebar label and position:
|
Add metadata to customize the sidebar label and position:
|
||||||
|
|
||||||
```md title="docs/hello.md" {1-4}
|
```md title="docs/hello.md" {1-4}
|
||||||
---
|
---
|
||||||
|
|
|
@ -26,7 +26,7 @@ A new document is now available at `http://localhost:3000/docs/hello`.
|
||||||
|
|
||||||
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
||||||
|
|
||||||
Add metadatas to customize the sidebar label and position:
|
Add metadata to customize the sidebar label and position:
|
||||||
|
|
||||||
```md title="docs/hello.md" {1-4}
|
```md title="docs/hello.md" {1-4}
|
||||||
---
|
---
|
||||||
|
|
|
@ -26,7 +26,7 @@ A new document is now available at `http://localhost:3000/docs/hello`.
|
||||||
|
|
||||||
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
||||||
|
|
||||||
Add metadatas to customize the sidebar label and position:
|
Add metadata to customize the sidebar label and position:
|
||||||
|
|
||||||
```md title="docs/hello.md" {1-4}
|
```md title="docs/hello.md" {1-4}
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`toRedirectFilesMetadata should create appropriate metadatas for empty baseUrl: fileContent baseUrl=empty 1`] = `
|
exports[`toRedirectFilesMetadata should create appropriate metadata for empty baseUrl: fileContent baseUrl=empty 1`] = `
|
||||||
Array [
|
Array [
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -16,7 +16,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toRedirectFilesMetadata should create appropriate metadatas for root baseUrl: fileContent baseUrl=/ 1`] = `
|
exports[`toRedirectFilesMetadata should create appropriate metadata for root baseUrl: fileContent baseUrl=/ 1`] = `
|
||||||
Array [
|
Array [
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -32,7 +32,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toRedirectFilesMetadata should create appropriate metadatas trailingSlash=false: fileContent 1`] = `
|
exports[`toRedirectFilesMetadata should create appropriate metadata trailingSlash=false: fileContent 1`] = `
|
||||||
Array [
|
Array [
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -70,7 +70,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toRedirectFilesMetadata should create appropriate metadatas trailingSlash=true: fileContent 1`] = `
|
exports[`toRedirectFilesMetadata should create appropriate metadata trailingSlash=true: fileContent 1`] = `
|
||||||
Array [
|
Array [
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -108,7 +108,7 @@ Array [
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toRedirectFilesMetadata should create appropriate metadatas trailingSlash=undefined: fileContent 1`] = `
|
exports[`toRedirectFilesMetadata should create appropriate metadata trailingSlash=undefined: fileContent 1`] = `
|
||||||
Array [
|
Array [
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
|
@ -42,7 +42,7 @@ describe('createToUrl', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('toRedirectFilesMetadata', () => {
|
describe('toRedirectFilesMetadata', () => {
|
||||||
test('should create appropriate metadatas trailingSlash=undefined', async () => {
|
test('should create appropriate metadata trailingSlash=undefined', async () => {
|
||||||
const pluginContext = {
|
const pluginContext = {
|
||||||
outDir: '/tmp/someFixedOutDir',
|
outDir: '/tmp/someFixedOutDir',
|
||||||
baseUrl: 'https://docusaurus.io',
|
baseUrl: 'https://docusaurus.io',
|
||||||
|
@ -69,7 +69,7 @@ describe('toRedirectFilesMetadata', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should create appropriate metadatas trailingSlash=true', async () => {
|
test('should create appropriate metadata trailingSlash=true', async () => {
|
||||||
const pluginContext = {
|
const pluginContext = {
|
||||||
outDir: '/tmp/someFixedOutDir',
|
outDir: '/tmp/someFixedOutDir',
|
||||||
baseUrl: 'https://docusaurus.io',
|
baseUrl: 'https://docusaurus.io',
|
||||||
|
@ -96,7 +96,7 @@ describe('toRedirectFilesMetadata', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should create appropriate metadatas trailingSlash=false', async () => {
|
test('should create appropriate metadata trailingSlash=false', async () => {
|
||||||
const pluginContext = {
|
const pluginContext = {
|
||||||
outDir: '/tmp/someFixedOutDir',
|
outDir: '/tmp/someFixedOutDir',
|
||||||
baseUrl: 'https://docusaurus.io',
|
baseUrl: 'https://docusaurus.io',
|
||||||
|
@ -124,7 +124,7 @@ describe('toRedirectFilesMetadata', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should create appropriate metadatas for root baseUrl', async () => {
|
test('should create appropriate metadata for root baseUrl', async () => {
|
||||||
const pluginContext = {
|
const pluginContext = {
|
||||||
outDir: '/tmp/someFixedOutDir',
|
outDir: '/tmp/someFixedOutDir',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
|
@ -139,7 +139,7 @@ describe('toRedirectFilesMetadata', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should create appropriate metadatas for empty baseUrl', async () => {
|
test('should create appropriate metadata for empty baseUrl', async () => {
|
||||||
const pluginContext = {
|
const pluginContext = {
|
||||||
outDir: '/tmp/someFixedOutDir',
|
outDir: '/tmp/someFixedOutDir',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ describe('site with full autogenerated sidebar', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('docs in fully generated sidebar have correct metadatas', async () => {
|
test('docs in fully generated sidebar have correct metadata', async () => {
|
||||||
const {content, siteDir} = await loadSite();
|
const {content, siteDir} = await loadSite();
|
||||||
const version = content.loadedVersions[0];
|
const version = content.loadedVersions[0];
|
||||||
|
|
||||||
|
@ -1518,11 +1518,11 @@ describe('site with partial autogenerated sidebars', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('docs in partially generated sidebar have correct metadatas', async () => {
|
test('docs in partially generated sidebar have correct metadata', async () => {
|
||||||
const {content, siteDir} = await loadSite();
|
const {content, siteDir} = await loadSite();
|
||||||
const version = content.loadedVersions[0];
|
const version = content.loadedVersions[0];
|
||||||
|
|
||||||
// Only looking at the docs of the autogen sidebar, others metadatas should not be affected
|
// Only looking at the docs of the autogen sidebar, others metadata should not be affected
|
||||||
|
|
||||||
expect(getDocById(version, 'API/api-end')).toEqual({
|
expect(getDocById(version, 'API/api-end')).toEqual({
|
||||||
...defaultDocMetadata,
|
...defaultDocMetadata,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
import {DocFrontMatter} from './types';
|
import {DocFrontMatter} from './types';
|
||||||
|
|
||||||
// NOTE: we don't add any default value on purpose here
|
// NOTE: we don't add any default value on purpose here
|
||||||
// We don't want default values to magically appear in doc metadatas and props
|
// We don't want default values to magically appear in doc metadata and props
|
||||||
// While the user did not provide those values explicitly
|
// While the user did not provide those values explicitly
|
||||||
// We use default values in code instead
|
// We use default values in code instead
|
||||||
const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
||||||
|
|
|
@ -284,7 +284,7 @@ export function processDocMetadata(args: {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error(
|
||||||
chalk.red(
|
chalk.red(
|
||||||
`Can't process doc metadatas for doc at path "${args.docFile.filePath}" in version "${args.versionMetadata.versionName}"`,
|
`Can't process doc metadata for doc at path "${args.docFile.filePath}" in version "${args.versionMetadata.versionName}"`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -5,10 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {CategoryMetadataFile, DefaultSidebarItemsGenerator} from '../generator';
|
||||||
CategoryMetadatasFile,
|
|
||||||
DefaultSidebarItemsGenerator,
|
|
||||||
} from '../generator';
|
|
||||||
import {Sidebar, SidebarItemsGenerator} from '../types';
|
import {Sidebar, SidebarItemsGenerator} from '../types';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
||||||
|
@ -37,7 +34,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockCategoryMetadataFiles(
|
function mockCategoryMetadataFiles(
|
||||||
categoryMetadataFiles: Record<string, Partial<CategoryMetadatasFile>>,
|
categoryMetadataFiles: Record<string, Partial<CategoryMetadataFile>>,
|
||||||
) {
|
) {
|
||||||
jest.spyOn(fs, 'pathExists').mockImplementation((metadataFilePath) => {
|
jest.spyOn(fs, 'pathExists').mockImplementation((metadataFilePath) => {
|
||||||
return typeof categoryMetadataFiles[metadataFilePath] !== 'undefined';
|
return typeof categoryMetadataFiles[metadataFilePath] !== 'undefined';
|
||||||
|
|
|
@ -27,7 +27,7 @@ const docIdPrefix = '$doc$/';
|
||||||
export const CategoryMetadataFilenameBase = '_category_';
|
export const CategoryMetadataFilenameBase = '_category_';
|
||||||
export const CategoryMetadataFilenamePattern = '_category_.{json,yml,yaml}';
|
export const CategoryMetadataFilenamePattern = '_category_.{json,yml,yaml}';
|
||||||
|
|
||||||
export type CategoryMetadatasFile = {
|
export type CategoryMetadataFile = {
|
||||||
label?: string;
|
label?: string;
|
||||||
position?: number;
|
position?: number;
|
||||||
collapsed?: boolean;
|
collapsed?: boolean;
|
||||||
|
@ -50,7 +50,7 @@ type Dir = {
|
||||||
[item: string]: Dir | null;
|
[item: string]: Dir | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CategoryMetadatasFileSchema = Joi.object<CategoryMetadatasFile>({
|
const CategoryMetadataFileSchema = Joi.object<CategoryMetadataFile>({
|
||||||
label: Joi.string(),
|
label: Joi.string(),
|
||||||
position: Joi.number(),
|
position: Joi.number(),
|
||||||
collapsed: Joi.boolean(),
|
collapsed: Joi.boolean(),
|
||||||
|
@ -62,14 +62,14 @@ const CategoryMetadatasFileSchema = Joi.object<CategoryMetadatasFile>({
|
||||||
// Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
|
// Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
|
||||||
// TODO later if there is `CategoryFolder/index.md`, we may want to read the metadata as yaml on it
|
// TODO later if there is `CategoryFolder/index.md`, we may want to read the metadata as yaml on it
|
||||||
// see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
// see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
||||||
async function readCategoryMetadatasFile(
|
async function readCategoryMetadataFile(
|
||||||
categoryDirPath: string,
|
categoryDirPath: string,
|
||||||
): Promise<CategoryMetadatasFile | null> {
|
): Promise<CategoryMetadataFile | null> {
|
||||||
async function tryReadFile(filePath: string): Promise<CategoryMetadatasFile> {
|
async function tryReadFile(filePath: string): Promise<CategoryMetadataFile> {
|
||||||
const contentString = await fs.readFile(filePath, {encoding: 'utf8'});
|
const contentString = await fs.readFile(filePath, {encoding: 'utf8'});
|
||||||
const unsafeContent = Yaml.load(contentString);
|
const unsafeContent = Yaml.load(contentString);
|
||||||
try {
|
try {
|
||||||
return Joi.attempt(unsafeContent, CategoryMetadatasFileSchema);
|
return Joi.attempt(unsafeContent, CategoryMetadataFileSchema);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error(
|
||||||
chalk.red(
|
chalk.red(
|
||||||
|
@ -81,7 +81,7 @@ async function readCategoryMetadatasFile(
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
for (const ext of ['.json', '.yml', '.yaml']) {
|
for (const ext of ['.json', '.yml', '.yaml']) {
|
||||||
// Simpler to use only posix paths for mocking file metadatas in tests
|
// Simpler to use only posix paths for mocking file metadata in tests
|
||||||
const filePath = posixPath(
|
const filePath = posixPath(
|
||||||
path.join(categoryDirPath, `${CategoryMetadataFilenameBase}${ext}`),
|
path.join(categoryDirPath, `${CategoryMetadataFilenameBase}${ext}`),
|
||||||
);
|
);
|
||||||
|
@ -184,16 +184,16 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
||||||
folderName: string,
|
folderName: string,
|
||||||
): Promise<WithPosition<SidebarItemCategory>> {
|
): Promise<WithPosition<SidebarItemCategory>> {
|
||||||
const categoryPath = path.join(version.contentPath, autogenDir, fullPath);
|
const categoryPath = path.join(version.contentPath, autogenDir, fullPath);
|
||||||
const categoryMetadatas = await readCategoryMetadatasFile(categoryPath);
|
const categoryMetadata = await readCategoryMetadataFile(categoryPath);
|
||||||
const className = categoryMetadatas?.className;
|
const className = categoryMetadata?.className;
|
||||||
const {filename, numberPrefix} = numberPrefixParser(folderName);
|
const {filename, numberPrefix} = numberPrefixParser(folderName);
|
||||||
return {
|
return {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: categoryMetadatas?.label ?? filename,
|
label: categoryMetadata?.label ?? filename,
|
||||||
collapsible:
|
collapsible:
|
||||||
categoryMetadatas?.collapsible ?? options.sidebarCollapsible,
|
categoryMetadata?.collapsible ?? options.sidebarCollapsible,
|
||||||
collapsed: categoryMetadatas?.collapsed ?? options.sidebarCollapsed,
|
collapsed: categoryMetadata?.collapsed ?? options.sidebarCollapsed,
|
||||||
position: categoryMetadatas?.position ?? numberPrefix,
|
position: categoryMetadata?.position ?? numberPrefix,
|
||||||
...(className !== undefined && {className}),
|
...(className !== undefined && {className}),
|
||||||
items: await Promise.all(
|
items: await Promise.all(
|
||||||
Object.entries(dir).map(([key, content]) =>
|
Object.entries(dir).map(([key, content]) =>
|
||||||
|
|
|
@ -124,8 +124,8 @@ export type PropSidebars = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reduce API surface for options.sidebarItemsGenerator
|
// Reduce API surface for options.sidebarItemsGenerator
|
||||||
// The user-provided generator fn should receive only a subset of metadatas
|
// The user-provided generator fn should receive only a subset of metadata
|
||||||
// A change to any of these metadatas can be considered as a breaking change
|
// A change to any of these metadata can be considered as a breaking change
|
||||||
export type SidebarItemsGeneratorDoc = Pick<
|
export type SidebarItemsGeneratorDoc = Pick<
|
||||||
DocMetadataBase,
|
DocMetadataBase,
|
||||||
'id' | 'frontMatter' | 'source' | 'sourceDirName' | 'sidebarPosition'
|
'id' | 'frontMatter' | 'source' | 'sourceDirName' | 'sidebarPosition'
|
||||||
|
|
|
@ -50,7 +50,7 @@ function getNormalizedSidebarName({
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Do we need to translate doc metadatas?
|
// Do we need to translate doc metadata?
|
||||||
// It seems translating frontmatter labels is good enough
|
// It seems translating frontmatter labels is good enough
|
||||||
function getDocTranslations(doc: DocMetadata): TranslationFileContent {
|
function getDocTranslations(doc: DocMetadata): TranslationFileContent {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -22,9 +22,9 @@ describe('docusaurus-plugin-content-pages', () => {
|
||||||
path: pluginPath,
|
path: pluginPath,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const pagesMetadatas = await plugin.loadContent?.();
|
const pagesMetadata = await plugin.loadContent?.();
|
||||||
|
|
||||||
expect(pagesMetadatas).toEqual([
|
expect(pagesMetadata).toEqual([
|
||||||
{
|
{
|
||||||
type: 'jsx',
|
type: 'jsx',
|
||||||
permalink: '/',
|
permalink: '/',
|
||||||
|
@ -89,7 +89,7 @@ describe('docusaurus-plugin-content-pages', () => {
|
||||||
path: pluginPath,
|
path: pluginPath,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const pagesMetadatas = await plugin.loadContent?.();
|
const pagesMetadata = await plugin.loadContent?.();
|
||||||
|
|
||||||
const frTranslationsPath = path.posix.join(
|
const frTranslationsPath = path.posix.join(
|
||||||
'@site',
|
'@site',
|
||||||
|
@ -98,7 +98,7 @@ describe('docusaurus-plugin-content-pages', () => {
|
||||||
'docusaurus-plugin-content-pages',
|
'docusaurus-plugin-content-pages',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(pagesMetadatas).toEqual([
|
expect(pagesMetadata).toEqual([
|
||||||
{
|
{
|
||||||
type: 'jsx',
|
type: 'jsx',
|
||||||
permalink: '/',
|
permalink: '/',
|
||||||
|
|
|
@ -29,7 +29,7 @@ function BlogListPage(props: Props): JSX.Element {
|
||||||
description={blogDescription}
|
description={blogDescription}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
||||||
pageClassName={ThemeClassNames.page.blogListPage}
|
pageClassName={ThemeClassNames.page.blogListPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
tag: 'blog_posts_list',
|
tag: 'blog_posts_list',
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -23,7 +23,7 @@ function BlogTagsListPage(props: Props): JSX.Element {
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
||||||
pageClassName={ThemeClassNames.page.blogTagsListPage}
|
pageClassName={ThemeClassNames.page.blogTagsListPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
tag: 'blog_tags_list',
|
tag: 'blog_tags_list',
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default function BlogTagsPostsPage(props: Props): JSX.Element {
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
||||||
pageClassName={ThemeClassNames.page.blogTagPostListPage}
|
pageClassName={ThemeClassNames.page.blogTagPostListPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
tag: 'blog_tags_posts',
|
tag: 'blog_tags_posts',
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -58,7 +58,7 @@ function DocPageContent({
|
||||||
<Layout
|
<Layout
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsDocPage}
|
pageClassName={ThemeClassNames.page.docsDocPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
version,
|
version,
|
||||||
tag: docVersionSearchTag(pluginId, version),
|
tag: docVersionSearchTag(pluginId, version),
|
||||||
}}>
|
}}>
|
||||||
|
|
|
@ -59,7 +59,7 @@ export default function DocTagDocListPage({tag}: Props): JSX.Element {
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsTagDocListPage}
|
pageClassName={ThemeClassNames.page.docsTagDocListPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
tag: 'doc_tag_doc_list',
|
tag: 'doc_tag_doc_list',
|
||||||
}}>
|
}}>
|
||||||
|
|
|
@ -22,7 +22,7 @@ function DocTagsListPage({tags}: Props): JSX.Element {
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsTagsListPage}
|
pageClassName={ThemeClassNames.page.docsTagsListPage}
|
||||||
searchMetadatas={{
|
searchMetadata={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
tag: 'doc_tags_list',
|
tag: 'doc_tags_list',
|
||||||
}}>
|
}}>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Head from '@docusaurus/Head';
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
import type {Props} from '@theme/Layout';
|
import type {Props} from '@theme/Layout';
|
||||||
import SearchMetadatas from '@theme/SearchMetadatas';
|
import SearchMetadata from '@theme/SearchMetadata';
|
||||||
import Seo from '@theme/Seo';
|
import Seo from '@theme/Seo';
|
||||||
import {
|
import {
|
||||||
DEFAULT_SEARCH_TAG,
|
DEFAULT_SEARCH_TAG,
|
||||||
|
@ -87,8 +87,8 @@ export default function LayoutHead(props: Props): JSX.Element {
|
||||||
siteConfig: {favicon},
|
siteConfig: {favicon},
|
||||||
i18n: {currentLocale, localeConfigs},
|
i18n: {currentLocale, localeConfigs},
|
||||||
} = useDocusaurusContext();
|
} = useDocusaurusContext();
|
||||||
const {metadatas, image: defaultImage} = useThemeConfig();
|
const {metadata, image: defaultImage} = useThemeConfig();
|
||||||
const {title, description, image, keywords, searchMetadatas} = props;
|
const {title, description, image, keywords, searchMetadata} = props;
|
||||||
const faviconUrl = useBaseUrl(favicon);
|
const faviconUrl = useBaseUrl(favicon);
|
||||||
const pageTitle = useTitleFormatter(title);
|
const pageTitle = useTitleFormatter(title);
|
||||||
|
|
||||||
|
@ -117,21 +117,22 @@ export default function LayoutHead(props: Props): JSX.Element {
|
||||||
|
|
||||||
<AlternateLangHeaders />
|
<AlternateLangHeaders />
|
||||||
|
|
||||||
<SearchMetadatas
|
<SearchMetadata
|
||||||
tag={DEFAULT_SEARCH_TAG}
|
tag={DEFAULT_SEARCH_TAG}
|
||||||
locale={currentLocale}
|
locale={currentLocale}
|
||||||
{...searchMetadatas}
|
{...searchMetadata}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Head
|
<Head
|
||||||
// it's important to have an additional <Head> element here,
|
// it's important to have an additional <Head> element here,
|
||||||
// as it allows react-helmet to override values set in previous <Head>
|
// as it allows react-helmet to override values set in previous <Head>
|
||||||
// ie we can override default metadatas such as "twitter:card"
|
// ie we can override default metadata such as "twitter:card"
|
||||||
// In same Head, the same meta would appear twice instead of overriding
|
// In same Head, the same meta would appear twice instead of overriding
|
||||||
// See react-helmet doc
|
// See react-helmet doc
|
||||||
>
|
>
|
||||||
{metadatas.map((metadata, i) => (
|
{/* Yes, "metadatum" is the grammatically correct term */}
|
||||||
<meta key={`metadata_${i}`} {...metadata} />
|
{metadata.map((metadatum, i) => (
|
||||||
|
<meta key={`metadata_${i}`} {...metadatum} />
|
||||||
))}
|
))}
|
||||||
</Head>
|
</Head>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Head from '@docusaurus/Head';
|
import Head from '@docusaurus/Head';
|
||||||
import type {Props} from '@theme/SearchMetadatas';
|
import type {Props} from '@theme/SearchMetadata';
|
||||||
|
|
||||||
// Note: we don't couple this to Algolia/DocSearch on purpose
|
// Note: we don't couple this to Algolia/DocSearch on purpose
|
||||||
// We may want to support other search engine plugins too
|
// We may want to support other search engine plugins too
|
||||||
// Search plugins should swizzle/override this comp to add their behavior
|
// Search plugins should swizzle/override this comp to add their behavior
|
||||||
export default function SearchMetadatas({
|
export default function SearchMetadata({
|
||||||
locale,
|
locale,
|
||||||
version,
|
version,
|
||||||
tag,
|
tag,
|
|
@ -301,7 +301,7 @@ declare module '@theme/Layout' {
|
||||||
readonly permalink?: string;
|
readonly permalink?: string;
|
||||||
readonly wrapperClassName?: string;
|
readonly wrapperClassName?: string;
|
||||||
readonly pageClassName?: string;
|
readonly pageClassName?: string;
|
||||||
readonly searchMetadatas?: {
|
readonly searchMetadata?: {
|
||||||
readonly version?: string;
|
readonly version?: string;
|
||||||
readonly tag?: string;
|
readonly tag?: string;
|
||||||
};
|
};
|
||||||
|
@ -320,15 +320,15 @@ declare module '@theme/LayoutHead' {
|
||||||
export default LayoutHead;
|
export default LayoutHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/SearchMetadatas' {
|
declare module '@theme/SearchMetadata' {
|
||||||
export interface Props {
|
export interface Props {
|
||||||
readonly locale?: string;
|
readonly locale?: string;
|
||||||
readonly version?: string;
|
readonly version?: string;
|
||||||
readonly tag?: string;
|
readonly tag?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SearchMetadatas: (props: Props) => JSX.Element;
|
const SearchMetadata: (props: Props) => JSX.Element;
|
||||||
export default SearchMetadatas;
|
export default SearchMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/LastUpdated' {
|
declare module '@theme/LastUpdated' {
|
||||||
|
|
|
@ -32,7 +32,7 @@ const DEFAULT_COLOR_MODE_CONFIG = {
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
colorMode: DEFAULT_COLOR_MODE_CONFIG,
|
colorMode: DEFAULT_COLOR_MODE_CONFIG,
|
||||||
docs: DEFAULT_DOCS_CONFIG,
|
docs: DEFAULT_DOCS_CONFIG,
|
||||||
metadatas: [],
|
metadata: [],
|
||||||
prism: {
|
prism: {
|
||||||
additionalLanguages: [],
|
additionalLanguages: [],
|
||||||
},
|
},
|
||||||
|
@ -46,7 +46,6 @@ const DEFAULT_CONFIG = {
|
||||||
maxHeadingLevel: 3,
|
maxHeadingLevel: 3,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
||||||
|
|
||||||
const NavbarItemPosition = Joi.string().equal('left', 'right').default('left');
|
const NavbarItemPosition = Joi.string().equal('left', 'right').default('left');
|
||||||
|
|
||||||
|
@ -264,9 +263,13 @@ const ThemeConfigSchema = Joi.object({
|
||||||
colorMode: ColorModeSchema,
|
colorMode: ColorModeSchema,
|
||||||
image: Joi.string(),
|
image: Joi.string(),
|
||||||
docs: DocsSchema,
|
docs: DocsSchema,
|
||||||
metadatas: Joi.array()
|
metadata: Joi.array()
|
||||||
.items(HtmlMetadataSchema)
|
.items(HtmlMetadataSchema)
|
||||||
.default(DEFAULT_CONFIG.metadatas),
|
.default(DEFAULT_CONFIG.metadata),
|
||||||
|
metadatas: Joi.any().forbidden().messages({
|
||||||
|
'any.unknown':
|
||||||
|
'themeConfig.metadatas has been renamed as themeConfig.metadata. See https://github.com/facebook/docusaurus/pull/5871',
|
||||||
|
}),
|
||||||
announcementBar: Joi.object({
|
announcementBar: Joi.object({
|
||||||
id: Joi.string().default('announcement-bar'),
|
id: Joi.string().default('announcement-bar'),
|
||||||
content: Joi.string().required(),
|
content: Joi.string().required(),
|
||||||
|
@ -358,7 +361,7 @@ const ThemeConfigSchema = Joi.object({
|
||||||
}).default(DEFAULT_CONFIG.tableOfContents),
|
}).default(DEFAULT_CONFIG.tableOfContents),
|
||||||
});
|
});
|
||||||
|
|
||||||
export {ThemeConfigSchema};
|
export {DEFAULT_CONFIG, ThemeConfigSchema};
|
||||||
|
|
||||||
export function validateThemeConfig({
|
export function validateThemeConfig({
|
||||||
validate,
|
validate,
|
||||||
|
|
|
@ -28,13 +28,13 @@ describe('parseCodeBlockTitle', () => {
|
||||||
expect(parseCodeBlockTitle(`{1,2-3}`)).toEqual(``);
|
expect(parseCodeBlockTitle(`{1,2-3}`)).toEqual(``);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should parse with multiple metadatas title first', () => {
|
test('should parse with multiple metadata title first', () => {
|
||||||
expect(parseCodeBlockTitle(`title="index.js" label="JavaScript"`)).toEqual(
|
expect(parseCodeBlockTitle(`title="index.js" label="JavaScript"`)).toEqual(
|
||||||
`index.js`,
|
`index.js`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should parse with multiple metadatas title last', () => {
|
test('should parse with multiple metadata title last', () => {
|
||||||
expect(parseCodeBlockTitle(`label="JavaScript" title="index.js"`)).toEqual(
|
expect(parseCodeBlockTitle(`label="JavaScript" title="index.js"`)).toEqual(
|
||||||
`index.js`,
|
`index.js`,
|
||||||
);
|
);
|
||||||
|
|
|
@ -113,7 +113,7 @@ export type ThemeConfig = {
|
||||||
footer?: Footer;
|
footer?: Footer;
|
||||||
hideableSidebar: boolean;
|
hideableSidebar: boolean;
|
||||||
image?: string;
|
image?: string;
|
||||||
metadatas: Array<Record<string, string>>;
|
metadata: Array<Record<string, string>>;
|
||||||
sidebarCollapsible: boolean;
|
sidebarCollapsible: boolean;
|
||||||
tableOfContents: TableOfContents;
|
tableOfContents: TableOfContents;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,8 @@ import React from 'react';
|
||||||
|
|
||||||
import Head from '@docusaurus/Head';
|
import Head from '@docusaurus/Head';
|
||||||
|
|
||||||
// Override default/agnostic SearchMetas to use Algolia-specific metadatas
|
// Override default/agnostic SearchMetas to use Algolia-specific metadata
|
||||||
export default function AlgoliaSearchMetadatas({locale, version, tag}) {
|
export default function AlgoliaSearchMetadata({locale, version, tag}) {
|
||||||
// Seems safe to consider here the locale is the language,
|
// Seems safe to consider here the locale is the language,
|
||||||
// as the existing docsearch:language filter is afaik a regular string-based filter
|
// as the existing docsearch:language filter is afaik a regular string-based filter
|
||||||
const language = locale;
|
const language = locale;
|
|
@ -11,7 +11,7 @@ import useContextualSearchFilters from '@theme/hooks/useContextualSearchFilters'
|
||||||
export default function useAlgoliaContextualFacetFilters() {
|
export default function useAlgoliaContextualFacetFilters() {
|
||||||
const {locale, tags} = useContextualSearchFilters();
|
const {locale, tags} = useContextualSearchFilters();
|
||||||
|
|
||||||
// seems safe to convert locale->language, see AlgoliaSearchMetadatas comment
|
// seems safe to convert locale->language, see AlgoliaSearchMetadata comment
|
||||||
const languageFilter = `language:${locale}`;
|
const languageFilter = `language:${locale}`;
|
||||||
|
|
||||||
const tagsFilter = tags.map((tag) => `docusaurus_tag:${tag}`);
|
const tagsFilter = tags.map((tag) => `docusaurus_tag:${tag}`);
|
||||||
|
|
|
@ -36,7 +36,7 @@ describe('createExcerpt', () => {
|
||||||
Nunc porttitor libero nec vulputate venenatis. Nam nec rhoncus mauris. Morbi tempus est et nibh maximus, tempus venenatis arcu lobortis.
|
Nunc porttitor libero nec vulputate venenatis. Nam nec rhoncus mauris. Morbi tempus est et nibh maximus, tempus venenatis arcu lobortis.
|
||||||
`),
|
`),
|
||||||
).toEqual(
|
).toEqual(
|
||||||
// h1 title is skipped on purpose, because we don't want the page to have SEO metadatas title === description
|
// h1 title is skipped on purpose, because we don't want the page to have SEO metadata title === description
|
||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ex urna, molestie et sagittis ut, varius ac justo.',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ex urna, molestie et sagittis ut, varius ac justo.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -53,7 +53,7 @@ describe('createExcerpt', () => {
|
||||||
Nunc porttitor libero nec vulputate venenatis. Nam nec rhoncus mauris. Morbi tempus est et nibh maximus, tempus venenatis arcu lobortis.
|
Nunc porttitor libero nec vulputate venenatis. Nam nec rhoncus mauris. Morbi tempus est et nibh maximus, tempus venenatis arcu lobortis.
|
||||||
`),
|
`),
|
||||||
).toEqual(
|
).toEqual(
|
||||||
// h1 title is skipped on purpose, because we don't want the page to have SEO metadatas title === description
|
// h1 title is skipped on purpose, because we don't want the page to have SEO metadata title === description
|
||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ex urna, molestie et sagittis ut, varius ac justo.',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ex urna, molestie et sagittis ut, varius ac justo.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -246,7 +246,7 @@ Accepted fields:
|
||||||
| `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. |
|
| `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. |
|
||||||
| `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. |
|
| `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. |
|
||||||
| `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. |
|
| `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. |
|
||||||
| `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadatas](/docs/sidebar#autogenerated-sidebar-metadatas). |
|
| `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadata](/docs/sidebar#autogenerated-sidebar-metadata). |
|
||||||
| `sidebar_class_name` | `string` | `undefined` | Gives the corresponding sidebar label a special class name when using autogenerated sidebars. |
|
| `sidebar_class_name` | `string` | `undefined` | Gives the corresponding sidebar label a special class name when using autogenerated sidebars. |
|
||||||
| `hide_title` | `boolean` | `false` | Whether to hide the title at the top of the doc. It only hides a title declared through the frontmatter, and have no effect on a Markdown title at the top of your document. |
|
| `hide_title` | `boolean` | `false` | Whether to hide the title at the top of the doc. It only hides a title declared through the frontmatter, and have no effect on a Markdown title at the top of your document. |
|
||||||
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
|
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
|
||||||
|
|
|
@ -93,9 +93,9 @@ module.exports = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Metadatas {#metadatas}
|
### Metadata {#metadata}
|
||||||
|
|
||||||
You can configure additional html metadatas (and override existing ones).
|
You can configure additional html metadata (and override existing ones).
|
||||||
|
|
||||||
Accepted fields:
|
Accepted fields:
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ Accepted fields:
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `metadatas` | `Metadata[]` | `[]` | Any field will be directly passed to the `<meta />` tag. Possible fields include `id`, `name`, `property`, `content`, `itemprop`, etc. |
|
| `metadata` | `Metadata[]` | `[]` | Any field will be directly passed to the `<meta />` tag. Possible fields include `id`, `name`, `property`, `content`, `itemprop`, etc. |
|
||||||
|
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ Example configuration:
|
||||||
module.exports = {
|
module.exports = {
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
// highlight-next-line
|
// highlight-next-line
|
||||||
metadatas: [{name: 'twitter:card', content: 'summary'}],
|
metadata: [{name: 'twitter:card', content: 'summary'}],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
|
@ -499,11 +499,11 @@ module.exports = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Autogenerated sidebar metadatas {#autogenerated-sidebar-metadatas}
|
#### Autogenerated sidebar metadata {#autogenerated-sidebar-metadata}
|
||||||
|
|
||||||
By default, the sidebar slice will be generated in **alphabetical order** (using files and folders names).
|
By default, the sidebar slice will be generated in **alphabetical order** (using files and folders names).
|
||||||
|
|
||||||
If the generated sidebar does not look good, you can assign additional metadatas to docs and categories.
|
If the generated sidebar does not look good, you can assign additional metadata to docs and categories.
|
||||||
|
|
||||||
**For docs**: use additional frontmatter:
|
**For docs**: use additional frontmatter:
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ By default, Docusaurus will **remove the number prefix** from the doc id, title,
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
|
|
||||||
**Prefer using [additional metadatas](#autogenerated-sidebar-metadatas)**.
|
**Prefer using [additional metadata](#autogenerated-sidebar-metadata)**.
|
||||||
|
|
||||||
Updating a number prefix can be annoying, as it can require **updating multiple existing markdown links**:
|
Updating a number prefix can be annoying, as it can require **updating multiple existing markdown links**:
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
---
|
---
|
||||||
id: head-metadatas
|
id: head-metadata
|
||||||
title: Head Metadatas
|
title: Head Metadata
|
||||||
description: Declaring page-specific head metadatas through MDX
|
description: Declaring page-specific head metadata through MDX
|
||||||
slug: /markdown-features/head-metadatas
|
slug: /markdown-features/head-metadata
|
||||||
---
|
---
|
||||||
|
|
||||||
# Head Metadatas
|
# Head Metadata
|
||||||
|
|
||||||
Docusaurus automatically sets useful page metadatas in `<html>`, `<head>` and `<body>` for you.
|
Docusaurus automatically sets useful page metadata in `<html>`, `<head>` and `<body>` for you.
|
||||||
|
|
||||||
It is possible to add extra metadatas (or override existing ones) by using the `<head>` tag in Markdown files:
|
It is possible to add extra metadata (or override existing ones) by using the `<head>` tag in Markdown files:
|
||||||
|
|
||||||
```md title="markdown-features-head-metadatas.mdx"
|
```md title="markdown-features-head-metadata.mdx"
|
||||||
---
|
---
|
||||||
id: head-metadatas
|
id: head-metadata
|
||||||
title: Head Metadatas
|
title: Head Metadata
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- highlight-start -->
|
<!-- highlight-start -->
|
||||||
<head>
|
<head>
|
||||||
<html className="some-extra-html-class" />
|
<html className="some-extra-html-class" />
|
||||||
<body className="other-extra-body-class" />
|
<body className="other-extra-body-class" />
|
||||||
<title>Head Metadatas customized title!</title>
|
<title>Head Metadata customized title!</title>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8" />
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary" />
|
||||||
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadatas" />
|
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadata" />
|
||||||
</head>
|
</head>
|
||||||
<!-- highlight-end -->
|
<!-- highlight-end -->
|
||||||
|
|
||||||
# Head Metadatas
|
# Head Metadata
|
||||||
|
|
||||||
My text
|
My text
|
||||||
```
|
```
|
||||||
|
@ -37,10 +37,10 @@ My text
|
||||||
<head>
|
<head>
|
||||||
<html className="some-extra-html-class" />
|
<html className="some-extra-html-class" />
|
||||||
<body className="other-extra-body-class" />
|
<body className="other-extra-body-class" />
|
||||||
<title>Head Metadatas customized title!</title>
|
<title>Head Metadata customized title!</title>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8" />
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary" />
|
||||||
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadatas" />
|
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadata" />
|
||||||
</head>
|
</head>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ My text
|
||||||
|
|
||||||
This `<head>` declaration has been added to the current Markdown doc, as a demo.
|
This `<head>` declaration has been added to the current Markdown doc, as a demo.
|
||||||
|
|
||||||
Open your browser DevTools and check how this page's metadatas have been affected.
|
Open your browser DevTools and check how this page's metadata have been affected.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
|
@ -11,12 +11,12 @@ Docusaurus supports search engine optimization in a variety of ways.
|
||||||
|
|
||||||
## Global metadata {#global-metadata}
|
## Global metadata {#global-metadata}
|
||||||
|
|
||||||
Provide global meta attributes for the entire site through the [site configuration](./configuration.md#site-metadata). The metadatas will all be rendered in the HTML `<head>` using the key-value pairs as the prop name and value.
|
Provide global meta attributes for the entire site through the [site configuration](./configuration.md#site-metadata). The metadata will all be rendered in the HTML `<head>` using the key-value pairs as the prop name and value.
|
||||||
|
|
||||||
```js title="docusaurus.config.js"
|
```js title="docusaurus.config.js"
|
||||||
module.exports = {
|
module.exports = {
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
metadatas: [{name: 'keywords', content: 'cooking, blog'}],
|
metadata: [{name: 'keywords', content: 'cooking, blog'}],
|
||||||
// This would become <meta name="keywords" content="cooking, blog"> in the generated HTML
|
// This would become <meta name="keywords" content="cooking, blog"> in the generated HTML
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ To read more about types of meta tags, visit [the MDN docs](https://developer.mo
|
||||||
|
|
||||||
## Single page metadata {#single-page-metadata}
|
## Single page metadata {#single-page-metadata}
|
||||||
|
|
||||||
Similar to [global metadata](#global-metadata), Docusaurus also allows for the addition of meta-information to individual pages. Follow [this guide](./guides/markdown-features/markdown-features-head-metadatas.mdx) for configuring the `<head>` tag. In short:
|
Similar to [global metadata](#global-metadata), Docusaurus also allows for the addition of meta-information to individual pages. Follow [this guide](./guides/markdown-features/markdown-features-head-metadata.mdx) for configuring the `<head>` tag. In short:
|
||||||
|
|
||||||
```md title="my-markdown-page.md"
|
```md title="my-markdown-page.md"
|
||||||
# A cooking guide
|
# A cooking guide
|
||||||
|
|
|
@ -327,7 +327,7 @@ const config = {
|
||||||
additionalLanguages: ['java'],
|
additionalLanguages: ['java'],
|
||||||
},
|
},
|
||||||
image: 'img/docusaurus-soc.png',
|
image: 'img/docusaurus-soc.png',
|
||||||
// metadatas: [{name: 'twitter:card', content: 'summary'}],
|
// metadata: [{name: 'twitter:card', content: 'summary'}],
|
||||||
gtag: !isDeployPreview
|
gtag: !isDeployPreview
|
||||||
? {
|
? {
|
||||||
trackingID: 'UA-141789564-1',
|
trackingID: 'UA-141789564-1',
|
||||||
|
|
|
@ -52,7 +52,7 @@ const sidebars = {
|
||||||
'guides/markdown-features/assets',
|
'guides/markdown-features/assets',
|
||||||
'guides/markdown-features/plugins',
|
'guides/markdown-features/plugins',
|
||||||
'guides/markdown-features/math-equations',
|
'guides/markdown-features/math-equations',
|
||||||
'guides/markdown-features/head-metadatas',
|
'guides/markdown-features/head-metadata',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'styling-layout',
|
'styling-layout',
|
||||||
|
|
Loading…
Add table
Reference in a new issue