Skip to content
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

Allow routes generated by addRoute to be listed in the plugin-content-docs sidebar #6067

Closed
2 tasks done
fsmaia opened this issue Dec 7, 2021 · 10 comments
Closed
2 tasks done
Labels
closed: wontfix A fix will bring significant overhead, or is out of scope (for feature requests) feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.

Comments

@fsmaia
Copy link
Contributor

fsmaia commented Dec 7, 2021

Have you read the Contributing Guidelines on issues?

Description

Currently, when a plugin/theme uses addRoute to register dynamic routes, these routes cannot be used in the sidebar. Besides, when accessing them directly, they have no wrapping layout (header/sidebar).

As we have an autogenerated sidebar item type, we could have a specific type to list all the sub-routes of a base route.

Has this been requested on Canny?

https://docusaurus.io/feature-requests/p/allow-routes-generated-by-addroute-to-be-listed-in-the-plugin-content-docs-sideb

Motivation

For plugin developers, using addRoute is way more powerful than performing an fs.createFileSync with a raw template, due to the following reasons:

  • A React component may be used instead of a raw component generator
  • This React component may be a part of the theme, and also be swizzled or overridden
  • There is no need to manage generated files/folders

This resource would be extremely useful for producing API Reference, such as documenting all the React components in a project, or all the TS typings, in a extensible scalable way.

API design

Add a new type to SidebarItemConfig to list all the sub-routes within a route:

export type SidebarItemRoutes = SidebarItemBase & {
  type: 'routes';
  label: string;
  baseRoute: string;
};

Real-life example:

A custom plugin generating dynamic routes (simplified version):

async contentLoaded({ content, actions }): Promise<void> {
  components.forEach(async component => {
    const componentData = await createData(`${component}.json`, JSON.stringify(component));

    addRoute({
      path: `/docs/react/${component.displayName}`,
      component: '@theme/ReactComponent',
       modules: {
         data: componentData,
       },
    });
  });
});

A Docusaurus configuration:

presets: [
  [
    '@docusaurus/preset-classic',
    /** @type {import('@docusaurus/preset-classic').Options} */
    {
      docs: {
        sidebarPath: require.resolve('./sidebars.js'),
      }
    }
  ]
],
plugins: [
  [
    'my-plugin',
      {
        src: ['../src/components/**'],
        tsconfig: '../tsconfig.json',
      },
  ],
],

And finally, a docusaurus sidebar configuration:

module.exports = {
  sidebar: [
    {
      type: 'routes',
      label: 'React components',
      baseRoute: '/docs/react'
    },
];

Have you tried building it?

As this affects docusaurus-plugin-content-docs, I'm afraid it can't be customized outside it.

Also it seems that content-docs has its own way to determine if a route should be wrapped by the layout or not.

Self-service

  • I'd be willing to contribute this feature to Docusaurus myself.
@fsmaia fsmaia added feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future. status: needs triage This issue has not been triaged by maintainers labels Dec 7, 2021
@Josh-Cena
Copy link
Collaborator

As a general rule, plugins work in isolation: isolation of data, isolation of routes (they shouldn't shadow/overlap with each other). I believe you should enhance the docs plugin instead if you find that you need to reuse a lot of the layout and data.

@Josh-Cena Josh-Cena added status: needs more information There is not enough information to take action on the issue. and removed status: needs triage This issue has not been triaged by maintainers labels Dec 8, 2021
@fsmaia
Copy link
Contributor Author

fsmaia commented Dec 8, 2021

Do you mean that the docusaurus-plugin-content-docs should still unaware of the routes, just physical files?

And then the consumer plugin should find a way to register the sidebar entries, and also add sidebar: 'sidebar' to the routes manifest? Is it possible?

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Dec 8, 2021

Do you mean that the docusaurus-plugin-content-docs should still unaware of the routes, just physical files?

Yes, the docs plugin shouldn't know about anything outside the routes it generated by itself.

Typically, we assume that each plugin renders its data without touching other plugins' data. So if you find yourself needing to generate extra data for the docs page to consume, you should enhance the plugin instead: #4492 (comment)

@fsmaia
Copy link
Contributor Author

fsmaia commented Dec 8, 2021

Ok, big thanks for the clarification! I read the issue carefully and ran the project locally. But I still can't figure out how to inject the sidebar prop to the generated routes file. Could you help me?

Anyway, we can close the issue.

@Josh-Cena
Copy link
Collaborator

But I still can't figure out how to inject the sidebar prop to the generated routes file.

The sidebars data are loaded in the loadContent lifecycle, so if you managed to load all the data that you need, then you just need to add an extra addRoute call in the contentLoaded lifecycle. Have you checked the source code? The docs plugin is quite convoluted especially due to supporting versioning

@slorber
Copy link
Collaborator

slorber commented Dec 8, 2021

The sidebar is a concept of the docs plugin. Even though the blog plugin also displays a sidebar, it's a totally different implementation.

If you implement your own plugin with a sidebar, you have 2 choices:

  • Create your own sidebar: a JSON tree that you can pass as a prop/data to your own UI. Eventually, you could re-use some existing theme components but be aware we may refactor them a bit.
  • Use or extend the docs plugin so that you have exactly the same UX as regular docs

You can leverage the docs plugin in 2 ways:

We don't have a good public API for plugin extension so for now the best is to either implement your own UI or generate docs at build time.

Example: https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/docusaurus-plugin-typedoc

@fsmaia
Copy link
Contributor Author

fsmaia commented Dec 8, 2021

Thank you both for your kind explanations!

After deep-diving into the code, this issue, and plugins, I realized these two choices and chose to create my own sidebar.

Just for curiosity, my actual contribution/ambition is to render docs for all the React components within a project:
atomicpages/docusaurus-plugin-react-docgen-typescript#7

After all, it seems to me it's right to have a sidebar for each docgen tool (OpenAPI, Typedoc, react-docgen, etc), so I lost some interest in injecting routes into the docs sidebar (it would be a very extensive list, to say the least).

Last, but not least, I still think that the docs plugin should be route-based instead of file-based, but I'm sure there are several implications, such as it would break the complete isolation perspective.

@slorber
Copy link
Collaborator

slorber commented Dec 8, 2021

Last, but not least, I still think that the docs plugin should be route-based instead of file-based, but I'm sure there are several implications, such as it would break the complete isolation perspective.

Not sure what you mean here. For now routes are only generated using the files of the docs folder, but in the future we'd like to provide an API so that you could fetch docs and sync with a CMS, the files wouldn't necessarily need to exist on disc as long as the CMS is able to provide md string and eventually some frontmatter

@fsmaia
Copy link
Contributor Author

fsmaia commented Dec 8, 2021

Actually, all the routes registered by addRoute will be present in the routes.js file, not just the docs one.

As of a common web application, every route is a candidate to be listed in the sidebar (at least is up to the developer to list a route or not).

However, if we think that the docs plugin has a dedicated sidebar instance, then it doesn't make sense to list allow routes from other sources to be listed there.

@slorber
Copy link
Collaborator

slorber commented Dec 8, 2021

Only docs-related routes appear in the docs sidebar. That wouldn't make any sense to have a blog post appear in the blog sidebar, nor our showcase page.

As of a common web application, every route is a candidate to be listed in the sidebar (at least is up to the developer to list a route or not).

I don't believe it's true. If you look at CMS-built site there's generally some kind of item category so that pages are tagged and appear in a menu, but nothing is automatic and has to be implemented.

@Josh-Cena Josh-Cena added closed: wontfix A fix will bring significant overhead, or is out of scope (for feature requests) and removed status: needs more information There is not enough information to take action on the issue. labels Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed: wontfix A fix will bring significant overhead, or is out of scope (for feature requests) feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.
Projects
None yet
Development

No branches or pull requests

3 participants