mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-01 11:18:24 +02:00
feat(v2): onBrokenMarkdownLinks config (#3658)
* refactor(v2): move `reportMessage` from `core/src/server/utils` to `utils` package * feat(v2): handle broken markdown links by using onBrokenLinks prop from siteconfig * feat(v2): add a new site config prop called `onBrokenMarkdownLinks` works like onBrokenLinks, but only for markdown links * feat(v2): add `onBrokenMarkdownLinks` to API docs * some changes regarding test issues after adding `onBrokenMarkdownLink` * Update website/versioned_docs/version-2.0.0-alpha.66/api/docusaurus.config.js.md Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
parent
52e7511869
commit
8f2d898f22
18 changed files with 71 additions and 38 deletions
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
url: 'https://your-docusaurus-test-site.com',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.ico',
|
||||
organizationName: 'facebook', // Usually your GitHub org/user name.
|
||||
projectName: 'docusaurus', // Usually your repo name.
|
||||
|
|
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
url: 'https://your-docusaurus-test-site.com',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.ico',
|
||||
organizationName: 'facebook', // Usually your GitHub org/user name.
|
||||
projectName: 'docusaurus', // Usually your repo name.
|
||||
|
|
|
@ -13,6 +13,7 @@ module.exports = {
|
|||
url: 'https://your-docusaurus-test-site.com',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.ico',
|
||||
organizationName: 'facebook', // Usually your GitHub org/user name.
|
||||
projectName: 'docusaurus', // Usually your repo name.
|
||||
|
|
|
@ -31,6 +31,7 @@ module.exports = {
|
|||
facebookAppId: '199138890728411',
|
||||
},
|
||||
onBrokenLinks: 'log',
|
||||
onBrokenMarkdownLinks: 'log',
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
|
|
|
@ -302,6 +302,7 @@ export function createConfigFile({
|
|||
favicon: siteConfig.favicon ?? '',
|
||||
customFields: customConfigFields,
|
||||
onBrokenLinks: 'log',
|
||||
onBrokenMarkdownLinks: 'log',
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
|
|
|
@ -38,6 +38,7 @@ export interface VersionTwoConfig {
|
|||
noIndex?: boolean;
|
||||
githubHost?: string;
|
||||
onBrokenLinks: string;
|
||||
onBrokenMarkdownLinks: string;
|
||||
plugins: Array<[string, {[key: string]: any}]>;
|
||||
themes?: [];
|
||||
presets: [[string, ClassicPresetEntries]];
|
||||
|
|
|
@ -11,7 +11,12 @@ import {
|
|||
STATIC_DIR_NAME,
|
||||
DEFAULT_PLUGIN_ID,
|
||||
} from '@docusaurus/core/lib/constants';
|
||||
import {normalizeUrl, docuHash, aliasedSitePath} from '@docusaurus/utils';
|
||||
import {
|
||||
normalizeUrl,
|
||||
docuHash,
|
||||
aliasedSitePath,
|
||||
reportMessage,
|
||||
} from '@docusaurus/utils';
|
||||
import {LoadContext, Plugin, RouteConfig} from '@docusaurus/types';
|
||||
|
||||
import {loadSidebars, createSidebarsUtils} from './sidebars';
|
||||
|
@ -39,13 +44,12 @@ import {OptionsSchema} from './options';
|
|||
import {flatten, keyBy, compact} from 'lodash';
|
||||
import {toGlobalDataVersion} from './globalData';
|
||||
import {toVersionMetadataProp} from './props';
|
||||
import chalk from 'chalk';
|
||||
|
||||
export default function pluginContentDocs(
|
||||
context: LoadContext,
|
||||
options: PluginOptions,
|
||||
): Plugin<LoadedContent, typeof OptionsSchema> {
|
||||
const {siteDir, generatedFilesDir, baseUrl} = context;
|
||||
const {siteDir, generatedFilesDir, baseUrl, siteConfig} = context;
|
||||
|
||||
const versionsMetadata = readVersionsMetadata({context, options});
|
||||
|
||||
|
@ -311,11 +315,13 @@ export default function pluginContentDocs(
|
|||
sourceToPermalink,
|
||||
versionsMetadata,
|
||||
onBrokenMarkdownLink: (brokenMarkdownLink) => {
|
||||
// TODO make this warning configurable?
|
||||
console.warn(
|
||||
chalk.yellow(
|
||||
`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.version.versionName}`,
|
||||
),
|
||||
if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
|
||||
return;
|
||||
}
|
||||
|
||||
reportMessage(
|
||||
`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.version.versionName}`,
|
||||
siteConfig.onBrokenMarkdownLinks,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
1
packages/docusaurus-types/src/index.d.ts
vendored
1
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -21,6 +21,7 @@ export interface DocusaurusConfig {
|
|||
title: string;
|
||||
url: string;
|
||||
onBrokenLinks: ReportingSeverity;
|
||||
onBrokenMarkdownLinks: ReportingSeverity;
|
||||
onDuplicateRoutes: ReportingSeverity;
|
||||
noIndex: boolean;
|
||||
organizationName?: string;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@docusaurus/types": "^2.0.0-alpha.66",
|
||||
"chalk": "^3.0.0",
|
||||
"escape-string-regexp": "^2.0.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"gray-matter": "^4.0.2",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import chalk from 'chalk';
|
||||
import path from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import {createHash} from 'crypto';
|
||||
|
@ -13,6 +14,7 @@ import kebabCase from 'lodash.kebabcase';
|
|||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import fs from 'fs-extra';
|
||||
import {URL} from 'url';
|
||||
import {ReportingSeverity} from '@docusaurus/types';
|
||||
|
||||
// @ts-expect-error: no typedefs :s
|
||||
import resolvePathnameUnsafe from 'resolve-pathname';
|
||||
|
@ -436,3 +438,28 @@ export function getElementsAround<T extends unknown>(
|
|||
const next = aroundIndex === max ? undefined : array[aroundIndex + 1];
|
||||
return {previous, next};
|
||||
}
|
||||
|
||||
export function reportMessage(
|
||||
message: string,
|
||||
reportingSeverity: ReportingSeverity,
|
||||
): void {
|
||||
switch (reportingSeverity) {
|
||||
case 'ignore':
|
||||
break;
|
||||
case 'log':
|
||||
console.log(chalk.bold.blue('info ') + chalk.blue(message));
|
||||
break;
|
||||
case 'warn':
|
||||
console.warn(chalk.bold.yellow('warn ') + chalk.yellow(message));
|
||||
break;
|
||||
case 'error':
|
||||
console.error(chalk.bold.red('error ') + chalk.red(message));
|
||||
break;
|
||||
case 'throw':
|
||||
throw new Error(message);
|
||||
default:
|
||||
throw new Error(
|
||||
`unexpected reportingSeverity value: ${reportingSeverity}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ Object {
|
|||
"favicon": "img/docusaurus.ico",
|
||||
"noIndex": false,
|
||||
"onBrokenLinks": "throw",
|
||||
"onBrokenMarkdownLinks": "warn",
|
||||
"onDuplicateRoutes": "warn",
|
||||
"organizationName": "endiliey",
|
||||
"plugins": Array [
|
||||
|
|
|
@ -10,8 +10,8 @@ import resolvePathname from 'resolve-pathname';
|
|||
import fs from 'fs-extra';
|
||||
import {mapValues, pickBy, flatten, countBy} from 'lodash';
|
||||
import {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
||||
import {removePrefix, removeSuffix} from '@docusaurus/utils';
|
||||
import {getAllFinalRoutes, reportMessage} from './utils';
|
||||
import {removePrefix, removeSuffix, reportMessage} from '@docusaurus/utils';
|
||||
import {getAllFinalRoutes} from './utils';
|
||||
import path from 'path';
|
||||
|
||||
function toReactRouterRoutes(routes: RouteConfig[]): RRRouteConfig[] {
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
export const DEFAULT_CONFIG: Pick<
|
||||
DocusaurusConfig,
|
||||
| 'onBrokenLinks'
|
||||
| 'onBrokenMarkdownLinks'
|
||||
| 'onDuplicateRoutes'
|
||||
| 'plugins'
|
||||
| 'themes'
|
||||
|
@ -27,6 +28,7 @@ export const DEFAULT_CONFIG: Pick<
|
|||
| 'noIndex'
|
||||
> = {
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
onDuplicateRoutes: 'warn',
|
||||
plugins: [],
|
||||
themes: [],
|
||||
|
@ -64,6 +66,9 @@ const ConfigSchema = Joi.object({
|
|||
onBrokenLinks: Joi.string()
|
||||
.equal('ignore', 'log', 'warn', 'error', 'throw')
|
||||
.default(DEFAULT_CONFIG.onBrokenLinks),
|
||||
onBrokenMarkdownLinks: Joi.string()
|
||||
.equal('ignore', 'log', 'warn', 'error', 'throw')
|
||||
.default(DEFAULT_CONFIG.onBrokenMarkdownLinks),
|
||||
onDuplicateRoutes: Joi.string()
|
||||
.equal('ignore', 'log', 'warn', 'error', 'throw')
|
||||
.default(DEFAULT_CONFIG.onDuplicateRoutes),
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
||||
import {getAllFinalRoutes, reportMessage} from './utils';
|
||||
import {reportMessage} from '@docusaurus/utils';
|
||||
import {getAllFinalRoutes} from './utils';
|
||||
|
||||
export function getAllDuplicateRoutes(
|
||||
pluginsRouteConfigs: RouteConfig[],
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import chalk from 'chalk';
|
||||
import flatMap from 'lodash.flatmap';
|
||||
import {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
||||
import {RouteConfig} from '@docusaurus/types';
|
||||
|
||||
// Recursively get the final routes (routes with no subroutes)
|
||||
export function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[] {
|
||||
|
@ -15,28 +14,3 @@ export function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[] {
|
|||
}
|
||||
return flatMap(routeConfig, getFinalRoutes);
|
||||
}
|
||||
|
||||
export function reportMessage(
|
||||
message: string,
|
||||
reportingSeverity: ReportingSeverity,
|
||||
): void {
|
||||
switch (reportingSeverity) {
|
||||
case 'ignore':
|
||||
break;
|
||||
case 'log':
|
||||
console.log(chalk.bold.blue('info ') + chalk.blue(message));
|
||||
break;
|
||||
case 'warn':
|
||||
console.warn(chalk.bold.yellow('warn ') + chalk.yellow(message));
|
||||
break;
|
||||
case 'error':
|
||||
console.error(chalk.bold.red('error ') + chalk.red(message));
|
||||
break;
|
||||
case 'throw':
|
||||
throw new Error(message);
|
||||
default:
|
||||
throw new Error(
|
||||
`unexpected reportingSeverity value: ${reportingSeverity}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,14 @@ The broken links detection is only available for a production build (`docusaurus
|
|||
|
||||
:::
|
||||
|
||||
### `onBrokenMarkdownLinks`
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'error' | 'throw'`
|
||||
|
||||
The behavior of Docusaurus, when it detects any broken markdown link.
|
||||
|
||||
By default, it prints a warning, to let you know about your broken markdown link, but you can change this security if needed.
|
||||
|
||||
### `onDuplicateRoutes`
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'error' | 'throw'`
|
||||
|
|
|
@ -13,6 +13,7 @@ module.exports = {
|
|||
baseUrl: '/blog-only/',
|
||||
url: 'https://v2.docusaurus.io',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/docusaurus.ico',
|
||||
themes: ['@docusaurus/theme-live-codeblock'],
|
||||
plugins: [],
|
||||
|
|
|
@ -49,6 +49,7 @@ module.exports = {
|
|||
baseUrl,
|
||||
url: 'https://v2.docusaurus.io',
|
||||
onBrokenLinks: isVersioningDisabled ? 'warn' : 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/docusaurus.ico',
|
||||
customFields: {
|
||||
description:
|
||||
|
|
Loading…
Add table
Reference in a new issue