-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
🚀 Feature
Update on how the API would like after some discussion:
The DocItem component right now is something like:
<div>
<DocVersionBanner />
<div>
<article>
<span>
Version: {versionMetadata.label}
</span>
<TOCCollapsible />
<div>
<MainHeading>{title}</MainHeading>
<DocContent />
</div>
<footer>
<div>
<EditThisPage />
</div>
<div>
<LastUpdated />
</div>
</footer>
</article>
<DocPaginator />
</div>
</div>We can have additional placeholder components at some "anchor points", meant to be swizzled:
<div>
<DocVersionBanner />
+ <AfterVersionBanner doc={DocContent} />
<div>
<article>
<span>
Version: {versionMetadata.label}
</span>
+ <AfterVersionBadge doc={DocContent} />
<TOCCollapsible />
<div>
<MainHeading>{title}</MainHeading>
+ <AfterHeading doc={DocContent} />
<DocContent />
+ <AfterMainContent doc={DocContent} />
</div>
<footer>
<div>
<EditThisPage />
+ <AfterEdit doc={DocContent} />
</div>
<div>
<LastUpdated />
+ <AfterLastUpdated doc={DocContent} />
</div>
</footer>
</article>
<DocPaginator />
+ <AfterPaginator doc={DocContent} />
</div>
</div>These anchor components are initially empty:
export default function AfterHeading({doc}) {
return null;
}But users can swizzle these elements and add custom logic. All the doc's data is provided through props, including front matter, metadata, title, content, etc., from which the user can pick and display.
export default function AfterHeading({doc}) {
const {frontMatter} = doc;
const {date, link} = frontMatter;
return (
<div className="alert alert--info margin-bottom--md" role="contentinfo">
First published on <b>{date.toLocaleDateString()}</b>.
<Link to={link}>Source link</Link>
</div>
);
}Some use-cases:
- A metadata list displaying author, source link, publication date, etc., after the heading;
- GitHub status badges after the heading;
- A custom feedback widget at the bottom, just like the discussion in [v2] Integrated Feedback Widget #4808;
- "Related links" at the bottom...
Benefits:
- Reduced code duplication: the same component doesn't have to be injected for every Markdown file, but is handled during doc loading;
- Reduced user burden: users don't have to swizzle the entire
DocItemjust to add one custom component, resulting in additional burden to keep it up-to-date in the future; - Easy extensibility: this conforms to Docusaurus's goal of making themes easily extended, since the user is only interacting with a very lightweight API;
- Not opinionated: all the logic is user-provided, and the Docusaurus doesn't provide any implementation details. This single generic API can satisfy a range of different needs.
Original proposal
Users may want a banner at the beginning of every documentation page containing some metadata like:
- Original source link, if this is an imported content;
- Author & Publish date (which may be different from the git info);
- Tags / thumbnail image.
Have you read the Contributing Guidelines on issues?
Yes
Has this been requested on Canny?
No
Motivation
Additional front matter should not be eaten up by the renderer but should find a way to be displayed. This frees the user from copy & pasting the same component (or importing them) to every page.
API Design
- We will provide a
metadataBanneroption inplugin-docs(default isfalse). When set totrue, a@theme/docMetadataBannercomponent will be injected at the beginning of every file—similar to the version banner. ThemetadataBanneroption will also accept a string path to a user-defined component, or the user can choose to swizzle@theme/docMetadataBannerinstead. - The
@theme/docMetadataBannercomponent will receivecontentas props (typing similar toDocItem.Props) from whichmetadata,frontMatter, etc., can be extracted. - The front matter that's already been picked up will be pruned, like:
const {title, sidebar_label, id, /* ..., */ ...customFrontMatter} = frontMatter;- The default rendering method can be an info box:
<div className="alert alert--info margin-bottom--md" role="contentinfo">
<div className="margin-top--md">
<ul>
{
Object.keys(customFrontMatter).map((key, i) => <li key={i}>{key}: {JSON.stringify(customFrontMatter[key])}</li>)
}
</ul>
</div>
</div>But users can easily customize it to show something they want, since they also know better of what custom front matter they have.
Have you tried building it?
Did some preliminary work to demonstrate what it would look like:
(Note: I used JSON.stringify() to force all front matter to strings. In practice, the date may be rendered with date.toLocaleDateString().)
