feat(core): make broken link checker detect broken anchors - add onBrokenAnchors config (#9528)

Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
ozaki 2024-01-04 12:56:20 +01:00 committed by GitHub
parent 332a466893
commit fd49301a45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 1220 additions and 519 deletions

View file

@ -265,26 +265,18 @@ export function PageRoute() {
Docusaurus builds a [single-page application](https://developer.mozilla.org/en-US/docs/Glossary/SPA), where route transitions are done through the `history.push()` method of React router. This operation is done on the client side. However, the prerequisite for a route transition to happen this way is that the target URL is known to our router. Otherwise, the router catches this path and displays a 404 page instead.
If you put some HTML pages under the `static` folder, they will be copied to the build output and therefore become accessible as part of your website, yet it's not part of the Docusaurus route system. We provide a `pathname://` protocol that allows you to redirect to another part of your domain in a non-SPA fashion, as if this route is an external link. Try the following two links:
If you put some HTML pages under the `static` folder, they will be copied to the build output and therefore become accessible as part of your website, yet it's not part of the Docusaurus route system. We provide a `pathname://` protocol that allows you to redirect to another part of your domain in a non-SPA fashion, as if this route is an external link.
```md
- [/pure-html](/pure-html)
- [pathname:///pure-html](pathname:///pure-html)
```
<BrowserWindow>
- [`/pure-html`](/pure-html)
- [`pathname:///pure-html`](pathname:///pure-html)
</BrowserWindow>
:::tip
The first link will **not** trigger a "broken links detected" check during the production build, because the respective file actually exists. Nevertheless, when you click on the link, a "page not found" will be displayed until you refresh.
:::
The `pathname://` protocol is useful for referencing any content in the static folder. For example, Docusaurus would convert [all Markdown static assets to require() calls](../guides/markdown-features/markdown-features-assets.mdx#static-assets). You can use `pathname://` to keep it a regular link instead of being hashed by Webpack.
```md title="my-doc.md"

View file

@ -188,7 +188,7 @@ export default {
The behavior of Docusaurus when it detects any broken link.
By default, it throws an error, to ensure you never ship any broken link, but you can lower this security if needed.
By default, it throws an error, to ensure you never ship any broken link.
:::note
@ -196,13 +196,21 @@ The broken links detection is only available for a production build (`docusaurus
:::
### `onBrokenAnchors` {#onBrokenAnchors}
- Type: `'ignore' | 'log' | 'warn' | 'throw'`
The behavior of Docusaurus when it detects any broken anchor declared with the `Heading` component of Docusaurus.
By default, it prints a warning, to let you know about your broken anchors.
### `onBrokenMarkdownLinks` {#onBrokenMarkdownLinks}
- Type: `'ignore' | 'log' | 'warn' | '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.
By default, it prints a warning, to let you know about your broken Markdown link.
### `onDuplicateRoutes` {#onDuplicateRoutes}

View file

@ -42,10 +42,10 @@ Accepted fields:
| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. |
| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. |
| `sidebarPath` | <code>false \| string</code> | `undefined` | Path to sidebar configuration. Use `false` to disable sidebars, or `undefined` to create a fully autogenerated sidebar. |
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. See also [Collapsible categories](/docs/sidebar#collapsible-categories) |
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. See also [Expanded categories by default](/docs/sidebar#expanded-categories-by-default) |
| `sidebarItemsGenerator` | <a href="#SidebarGenerator"><code>SidebarGenerator</code></a> | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar#customize-the-sidebar-items-generator) |
| `numberPrefixParser` | <code>boolean \|</code> <a href="#PrefixParser"><code>PrefixParser</code></a> | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar#using-number-prefixes) |
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. See also [Collapsible categories](/docs/sidebar/items#collapsible-categories) |
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. See also [Expanded categories by default](/docs/sidebar/items#expanded-categories-by-default) |
| `sidebarItemsGenerator` | <a href="#SidebarGenerator"><code>SidebarGenerator</code></a> | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar/autogenerated#customize-the-sidebar-items-generator) |
| `numberPrefixParser` | <code>boolean \|</code> <a href="#PrefixParser"><code>PrefixParser</code></a> | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes) |
| `docsRootComponent` | `string` | `'@theme/DocsRoot'` | Parent component of all the docs plugin pages (including all versions). Stays mounted when navigation between docs pages and versions. |
| `docVersionRootComponent` | `string` | `'@theme/DocVersionLayout'` | Parent component of all docs pages of an individual version (doc pages with sidebars, tags pages). Stays mounted when navigation between pages of that specific version. |
| `docRootComponent` | `string` | `'@theme/DocPage'` | Parent component of all doc pages with sidebars (regular docs pages, category generated index pages). Stays mounted when navigation between such pages. |
@ -275,7 +275,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. |
| `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_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_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#autogenerated-sidebar-metadata). |
| `sidebar_class_name` | `string` | `undefined` | Gives the corresponding sidebar label a special class name when using autogenerated sidebars. |
| `sidebar_custom_props` | `object` | `undefined` | Assign [custom props](../../guides/docs/sidebar/index.mdx#passing-custom-props) to the sidebar item referencing this doc |
| `displayed_sidebar` | `string` | `undefined` | Force the display of a given sidebar when browsing the current document. Read the [multiple sidebars guide](../../guides/docs/sidebar/multiple-sidebars.mdx) for details. |
@ -285,7 +285,7 @@ Accepted fields:
| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. |
| `pagination_next` | <code>string \| null</code> | Next doc in the sidebar | The ID of the documentation you want the "Next" pagination to link to. Use `null` to disable showing "Next" for this page. |
| `pagination_prev` | <code>string \| null</code> | Previous doc in the sidebar | The ID of the documentation you want the "Previous" pagination to link to. Use `null` to disable showing "Previous" for this page. |
| `parse_number_prefixes` | `boolean` | `numberPrefixParser` plugin option | Whether number prefix parsing is disabled on this doc. See also [Using number prefixes](/docs/sidebar#using-number-prefixes). |
| `parse_number_prefixes` | `boolean` | `numberPrefixParser` plugin option | Whether number prefix parsing is disabled on this doc. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes). |
| `custom_edit_url` | <code>string \| null</code> | Computed using the `editUrl` plugin option | The URL for editing this document. Use `null` to disable showing "Edit this page" for this page. |
| `keywords` | `string[]` | `undefined` | Keywords meta tag for the document page, for search engines. |
| `description` | `string` | The first line of Markdown content | The description of your document, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. |

View file

@ -180,7 +180,7 @@ By default, the files are written in `website/i18n/<defaultLocale>/...`.
### `docusaurus write-heading-ids [siteDir] [files]` {#docusaurus-write-heading-ids-sitedir}
Add [explicit heading IDs](./guides/markdown-features/markdown-features-toc.mdx#explicit-ids) to the Markdown documents of your site.
Add [explicit heading IDs](./guides/markdown-features/markdown-features-toc.mdx#heading-ids) to the Markdown documents of your site.
| Name | Default | Description |
| --- | --- | --- |

View file

@ -605,6 +605,49 @@ const MyComponent = () => {
};
```
### `useBrokenLinks` {#useBrokenLinks}
React hook to access the Docusaurus broken link checker APIs, exposing a way for a Docusaurus pages to report and collect their links and anchors.
:::warning
This is an **advanced** API that **most Docusaurus users don't need to use directly**.
It is already **built-in** in existing high-level components:
- the [`<Link>`](#link) component will collect links for you
- the `@theme/Heading` (used for Markdown headings) will collect anchors
Use `useBrokenLinks()` if you implement your own `<Heading>` or `<Link>` component.
:::
Usage example:
```js title="MyHeading.js"
import useBrokenLinks from '@docusaurus/useBrokenLinks';
export default function MyHeading({id, ...props}): JSX.Element {
const brokenLinks = useBrokenLinks();
brokenLinks.collectAnchor(id);
return <h2 id={id}>Heading</h2>;
}
```
```js title="MyLink.js"
import useBrokenLinks from '@docusaurus/useBrokenLinks';
export default function MyLink({targetLink, ...props}): JSX.Element {
const brokenLinks = useBrokenLinks();
brokenLinks.collectLink(targetLink);
return <a href={targetLink}>Link</a>;
}
```
## Functions {#functions}
### `interpolate` {#interpolate-1}

View file

@ -371,7 +371,7 @@ customProps:
:::info
If the `link` is explicitly specified, Docusaurus will not apply any [default conventions](items.mdx#category-index-convention).
If the `link` is explicitly specified, Docusaurus will not apply any [default conventions](#category-index-convention).
The doc links can be specified relatively, e.g. if the category is generated with the `guides` directory, `"link": {"type": "doc", "id": "intro"}` will be resolved to the ID `guides/intro`, only falling back to `intro` if a doc with the former ID doesn't exist.

View file

@ -106,7 +106,7 @@ npm run docusaurus docs:version 1.1.0
When tagging a new version, the document versioning mechanism will:
- Copy the full `docs/` folder contents into a new `versioned_docs/version-[versionName]/` folder.
- Create a versioned sidebars file based from your current [sidebar](docs-introduction.mdx#sidebar) configuration (if it exists) - saved as `versioned_sidebars/version-[versionName]-sidebars.json`.
- Create a versioned sidebars file based from your current [sidebar](./sidebar/index.mdx) configuration (if it exists) - saved as `versioned_sidebars/version-[versionName]-sidebars.json`.
- Append the new version number to `versions.json`.
### Creating new docs {#creating-new-docs}

View file

@ -445,7 +445,7 @@ Generated IDs are not always a good fit for localized sites, as it requires you
+ [link](#bonjour-le-monde)
```
For localized sites, it is recommended to use **[explicit heading IDs](../guides/markdown-features/markdown-features-toc.mdx#explicit-ids)**.
For localized sites, it is recommended to use **[explicit heading IDs](../guides/markdown-features/markdown-features-toc.mdx#heading-ids)**.
:::

View file

@ -211,7 +211,7 @@ For example, [`/examples/noIndex`](/examples/noIndex) is not included in the [Do
## Human readable links {#human-readable-links}
Docusaurus uses your file names as links, but you can always change that using slugs, see this [tutorial](./guides/docs/docs-introduction.mdx#document-id) for more details.
Docusaurus uses your file names as links, but you can always change that using slugs, see this [tutorial](./guides/docs/docs-create-doc.mdx#document-id) for more details.
## Structured content {#structured-content}

View file

@ -114,7 +114,7 @@ At most one plugin instance can be the "default plugin instance", by omitting th
## Using themes {#using-themes}
Themes are loaded in the exact same way as plugins. From the consumer perspective, the `themes` and `plugins` entries are interchangeable when installing and configuring a plugin. The only nuance is that themes are loaded after plugins, and it's possible for [a theme to override a plugin's default theme components](./swizzling.mdx#theme-aliases).
Themes are loaded in the exact same way as plugins. From the consumer perspective, the `themes` and `plugins` entries are interchangeable when installing and configuring a plugin. The only nuance is that themes are loaded after plugins, and it's possible for [a theme to override a plugin's default theme components](./advanced/client.mdx#theme-aliases).
:::tip