-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: enable option to propagate arbitrary frontmatter data in globals #4492
Comments
Hi, I understand your motivation to create additional pages, but I don't think adding this data to the global site data is the best option here. As you noted it's going to increase the size of the whole site, including the homepage etc. What I would suggest instead is to look at extending the original docs plugin to create those additional pages. We don't have an official doc for this but you can take a look at: #4138 (comment) You could probably do what you want with something like: const docsPluginExports = require("@docusaurus/plugin-content-docs");
const docsPlugin = docsPluginExports.default;
function docsPluginEnhanced(...pluginArgs) {
const docsPluginInstance = docsPlugin(...pluginArgs);
return {
...docsPluginInstance,
async contentLoaded(...contentLoadedArgs) {
// Create default plugin pages
await docsPluginInstance.contentLoaded(...contentLoadedArgs);
// Create your additional pages
const { actions, content } = contentLoadedArgs[0];
const { addRoute } = actions;
const { loadedVersions } = content;
await Promise.all(
loadedVersions.map(async version => {
addRoute({
path: loadedVersion.versionPath + "/calendar",
exact: true,
component: "@theme/DocsCalendarPage", // Your component
modules: {
// ... The props DocsCalendarPage need to receive
calendar: await createCalendarProp(version)
}
});
})
);
}
};
}
module.exports = {
...docsPluginExports,
default: docsPluginEnhanced
}; Does it make sense to you? Normally you'll have all the data you need from the "version" item to create the prop your custom calendar page should receive. Only this custom calendar page would receive the data, and the homepage will not be burdened by useless frontmatter weight |
This does make sense, thanks! I built the most basic version as I could (using a super basic test component in my site at Here's the error:
the new plugin source:
package.json:
docusaurus.config.js:
Any help would be greatly appreciated, if I can figure this out it should be pretty easy to publish this plugin for others to fork to provide a similar enhancement. |
If you have a public github repo with a branch and your code I can see how to fix it. You can't pass any json to "modules" directly here, but you can pass a path to a son file containing the data you want (we have a Modules means something Webpack can require. It's a bit deep in our code but you'll find this link useful: async function contentLoaded({ content, actions }) {
const { createData, addRoute } = actions;
// Create friends.json
const friends = ["Yangshun", "Sebastien"];
const friendsJsonPath = await createData(
"friends.json",
JSON.stringify(friends)
);
// Add the '/friends' routes, and ensure it receives the friends props
addRoute({
path: "/friends",
component: "@site/src/components/Friends.js",
modules: {
// propName -> JSON file path
friends: friendsJsonPath
},
exact: true
});
} |
Thanks for your help on this, I got it to work - unfortunately the metadata available directly through the At the end of the day I think a prebuild script that programmatically extracts the frontmatter from chosen docs and creates a json/yaml for the calendar page to ingest will be the best approach to solving this problem. The minimum working example is at https://github.com/kaytwo/docusaurus-plugin-content-docs-index if it might be helpful or if there's an easier way to accomplish this. |
Do plugins get processed in the order of the plugin array? Would this type of preprocessing be possible using a plugin? e.g. pass it a glob of files you care about, and then generate the new mdx file, which then gets processed by the docs plugin itself to create the summary page. |
why don't you like this approach?
Yes but in any case if you are creating a page that is not handled directly by the classic theme you would have to style it anyway? You can reuse existing theme components to do so.
You mean write That would definitively work, and some sites do that already (Jest site fetch opencollective contributors to display them on the site) But why not using the Docusaurus infra instead? I admit the current API is not ideal, but it is definitively the pattern we want you to encourage to adopt, and we'll improve this API to make this easier.
Your example looks good to me (apart the data in events.json)
The plugins load content in parallel for efficiency, and you should avoid relying on the plugins ordering in any way. We don't want to implement a plugin execution ordering/dependency system but rather keep plugins isolated and let you extend them more easily. |
This may be my mistake - I couldn't find where custom frontmatter was persisted within the existing data structures (only all of the metadata generated by docusaurus), so the solution I could think of would be to:
Please let me know if there's a different way to access that metadata, that would be a great help.
This may be my own personal use case, but for a smaller docs site I see the hierarchical left nav as more of a global site nav than "read about the docs in this one specific component of a project", so the best case scenario would be for the schedule to coexist within that structure and be easily accessible from the sidebar, and for that same sidebar to show up on the schedule page itself. As I've been navigating the docusaurus docs, I've often found myself having to swap between the "Docs" sidebar and the "API" sidebar by using the top global nav, and it would be nice (and hopefully not overwhelming) for everything to show up in that same hierarchy. If there is an easy way for me to use the existing theme and the same sidebars (besides just dynamically generating a new
This is definitely the crux of it (I dove into this mostly because I didn't want to read the same files twice) - I am not seeing where I can read the arbitrary frontmatter content from the already-read-in files (and I can't figure out how to style the new page as a doc).
This makes sense - right now I'm considering an approach like https://github.com/acrobit/docusaurus-plugin-auto-sidebars/blob/45d6723fd3a0e04641b343cf1478827587c9fd5e/src/index.ts#L42 to generate the Thanks again for your help! |
FYI the debug plugin might be help to inspect the available content: https://docusaurus.io/__docusaurus/debug/content You are right, and we should make sure to provide you with this info. For now the only work-around is to re-read the file again 😅 would be happy to accept a PR that add
Only docs display the sidebar currently, and if you want to display the sidebars on a non-doc page it can be a bit tricky, as you'd need to duplicate some complicated code of the
An alternatives is implementing your own Another alternative is to override I think in this case the best option would be to reuse the For now in practice it may be simpler to generate your calendar data as a pre-build step, have a component import/render it, and then use MDX to render this calendar component in
This is likely the simplest option for now. I think we don't provide enough infra to help you do what you really want. Let's keep this open and see how we could make what you want easier in the future |
I have a similar use case where I want to generate docs from a GraphQL schema and have it integrated with the rest of the docs. Since the documentation would be automatically generated, I'd prefer not to write files to the disk. I first tried to hook into the docs plugin's In the end I created a plugin that writes files to the disk through Also, the sidebar can be tricky to deal with as you can't reference files that are not written to the disk. EDIT: I created a repository that illustrates the issue with the infinite reloading: https://github.com/Zhouzi/docusaurus-plugin I initialized a docusaurus project and added a pretty basic plugin that writes to the disk: https://github.com/Zhouzi/docusaurus-plugin/blob/main/plugin.js If I run |
@zhouzi some details:
Note @edno implemented something similar here: https://github.com/edno/docusaurus2-graphql-doc-generator, currently using a cli as a pre-build step, but I suggested to try extending the docs plugin to write md files to disk (graphql-markdown/graphql-markdown#144). |
Thanks for the insights 🙏 I think the solution to #4138 would actually solve most of my issues. For now I will follow the example of |
Related to discussion: #5856 (reply in thread) |
Related RFC: #6923 |
The global data API is not ideal and adding data there decrease the loading perf of all pages of your site, due to having to load all that data before hydrating React. I think in the future we'll use React Serve Components to access and solve a similar use case in a more flexible and performant way. Track #9089 |
🚀 Feature
Expose markdown frontmatter in page globals.
Have you read the Contributing Guidelines on issues?
Yes
Motivation
I'd like to programmatically generate docs/pages based on custom metadata stored in the frontmatter of my docs. In my use case, I'm building a course website, where the docs are the descriptions of homeworks, labs, exams, etc, and I'd like to create a "calendar" page that reads release and due date metadata from the frontmatter of each of those pages. As of right now, only
id
,path
, andsidebar
are set in the plugin globals.Pitch
While this is a very specific use case, I've typically seen frontmatter used in this way in other static site generators to create derivative pages that incorporate some or all of the important metadata from some subset of other pages.
I tried to implement something similar to this both using this approach as well as a standalone plugin that I wrote for this purpose (trying both
setGlobalData
andcreateData
), but the issue is that the functionality is too tightly tied to the docs plugin itself to be easily factored out (and I couldn't figure out how to swizzle this part of@docusaurus/plugin-content-docs
).Implementation
The frontmatter can be propagated with this commit: kaytwo@ff408e1. I understand that this will increase the size of the globals which should be avoided, however this option could probably be gated behind a config option by replacing this line in
docs.ts
with:The text was updated successfully, but these errors were encountered: