mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
feat(core): siteConfig.headTags API to render extra tags in document head (#8151)
Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
parent
3558a091c6
commit
1ca4fb50fe
7 changed files with 124 additions and 2 deletions
9
packages/docusaurus-types/src/config.d.ts
vendored
9
packages/docusaurus-types/src/config.d.ts
vendored
|
@ -8,7 +8,7 @@
|
|||
import type {RuleSetRule} from 'webpack';
|
||||
import type {Required as RequireKeys, DeepPartial} from 'utility-types';
|
||||
import type {I18nConfig} from './i18n';
|
||||
import type {PluginConfig, PresetConfig} from './plugin';
|
||||
import type {PluginConfig, PresetConfig, HtmlTagObject} from './plugin';
|
||||
|
||||
export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'throw';
|
||||
|
||||
|
@ -192,6 +192,13 @@ export type DocusaurusConfig = {
|
|||
* @default ["static"]
|
||||
*/
|
||||
staticDirectories: string[];
|
||||
/**
|
||||
* An array of tags that will be inserted in the HTML `<head>`.
|
||||
*
|
||||
* @see https://docusaurus.io/docs/api/docusaurus-config#head
|
||||
* @default []
|
||||
*/
|
||||
headTags: HtmlTagObject[];
|
||||
/**
|
||||
* An array of scripts to load. The values can be either strings or plain
|
||||
* objects of attribute-value maps. The `<script>` tags will be inserted in
|
||||
|
|
|
@ -7,6 +7,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
|
|||
"baseUrlIssueBanner": true,
|
||||
"clientModules": [],
|
||||
"customFields": {},
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {},
|
||||
|
@ -44,6 +45,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
|
|||
"baseUrlIssueBanner": true,
|
||||
"clientModules": [],
|
||||
"customFields": {},
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {},
|
||||
|
@ -83,6 +85,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
|
|||
"baseUrlIssueBanner": true,
|
||||
"clientModules": [],
|
||||
"customFields": {},
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {},
|
||||
|
@ -122,6 +125,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
|
|||
"baseUrlIssueBanner": true,
|
||||
"clientModules": [],
|
||||
"customFields": {},
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {},
|
||||
|
@ -164,6 +168,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
|
|||
],
|
||||
"customFields": {},
|
||||
"favicon": "img/docusaurus.ico",
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {},
|
||||
|
|
|
@ -71,6 +71,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
|
|||
"baseUrlIssueBanner": true,
|
||||
"clientModules": [],
|
||||
"customFields": {},
|
||||
"headTags": [],
|
||||
"i18n": {
|
||||
"defaultLocale": "en",
|
||||
"localeConfigs": {
|
||||
|
|
|
@ -351,6 +351,74 @@ describe('normalizeConfig', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('accepts headTags with tagName and attributes', () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'link',
|
||||
attributes: {
|
||||
rel: 'icon',
|
||||
href: 'img/docusaurus.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("throws error if headTags doesn't have tagName", () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
headTags: [
|
||||
{
|
||||
attributes: {
|
||||
rel: 'icon',
|
||||
href: 'img/docusaurus.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}).toThrowErrorMatchingInlineSnapshot(`
|
||||
""headTags[0].tagName" is required
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it("throws error if headTags doesn't have attributes", () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'link',
|
||||
},
|
||||
],
|
||||
});
|
||||
}).toThrowErrorMatchingInlineSnapshot(`
|
||||
""headTags[0].attributes" is required
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it("throws error if headTags doesn't have string attributes", () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'link',
|
||||
attributes: {
|
||||
rel: false,
|
||||
href: 'img/docusaurus.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}).toThrowErrorMatchingInlineSnapshot(`
|
||||
""headTags[0].attributes.rel" must be a string
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it("throws error if css doesn't have href", () => {
|
||||
expect(() => {
|
||||
normalizeConfig({
|
||||
|
|
|
@ -33,6 +33,7 @@ export const DEFAULT_CONFIG: Pick<
|
|||
| 'plugins'
|
||||
| 'themes'
|
||||
| 'presets'
|
||||
| 'headTags'
|
||||
| 'stylesheets'
|
||||
| 'scripts'
|
||||
| 'clientModules'
|
||||
|
@ -51,6 +52,7 @@ export const DEFAULT_CONFIG: Pick<
|
|||
plugins: [],
|
||||
themes: [],
|
||||
presets: [],
|
||||
headTags: [],
|
||||
stylesheets: [],
|
||||
scripts: [],
|
||||
clientModules: [],
|
||||
|
@ -222,6 +224,20 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
|
|||
})
|
||||
.default(DEFAULT_CONFIG.scripts),
|
||||
ssrTemplate: Joi.string(),
|
||||
headTags: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
tagName: Joi.string().required(),
|
||||
attributes: Joi.object()
|
||||
.pattern(/[\w-]+/, Joi.string())
|
||||
.required(),
|
||||
}).unknown(),
|
||||
)
|
||||
.messages({
|
||||
'array.includes':
|
||||
'{#label} is invalid. A headTag must be an object with at least a "tagName" and an "attributes" property.',
|
||||
})
|
||||
.default(DEFAULT_CONFIG.headTags),
|
||||
stylesheets: Joi.array()
|
||||
.items(
|
||||
Joi.string(),
|
||||
|
|
|
@ -21,6 +21,7 @@ export function createBootstrapPlugin({
|
|||
const {
|
||||
stylesheets,
|
||||
scripts,
|
||||
headTags,
|
||||
clientModules: siteConfigClientModules,
|
||||
} = siteConfig;
|
||||
return {
|
||||
|
@ -58,7 +59,7 @@ export function createBootstrapPlugin({
|
|||
},
|
||||
);
|
||||
return {
|
||||
headTags: [...stylesheetsTags, ...scriptsTags],
|
||||
headTags: [...headTags, ...stylesheetsTags, ...scriptsTags],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -429,6 +429,30 @@ module.exports = {
|
|||
};
|
||||
```
|
||||
|
||||
### `headTags` {#headTags}
|
||||
|
||||
An array of tags that will be inserted in the HTML `<head>`. The values must be objects that contain two properties; `tagName` and `attributes`. `tagName` must be a string that determines the tag being created; eg `"link"`. `attributes` must be an attribute-value map.
|
||||
|
||||
- Type: `{ tagName: string; attributes: Object; }[]`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'link',
|
||||
attributes: {
|
||||
rel: 'icon',
|
||||
href: '/img/docusaurus.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
This would become `<link rel="icon" href="img/docusaurus.png" />` in the generated HTML.
|
||||
|
||||
### `scripts` {#scripts}
|
||||
|
||||
An array of scripts to load. The values can be either strings or plain objects of attribute-value maps. The `<script>` tags will be inserted in the HTML `<head>`. If you use a plain object, the only required attribute is `src`, and any other attributes are permitted (each one should have boolean/string values).
|
||||
|
|
Loading…
Add table
Reference in a new issue