facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
54.14k stars 8.11k forks source link

RFC: Doc sidebar version dropdown #5706

Open slorber opened 2 years ago

slorber commented 2 years ago

🚀 Feature

The navbar can get a bit crowded over time and it's a common doc pattern to use a sidebar version dropdown

The APISIX website already built this:

https://apisix.apache.org/docs/apisix/architecture-design/apisix

image

image

We could add some extra sidebar config to handle a version dropdown.

I don't have a strong opinion on the public API yet. Maybe it could be a theme config like themeConfig.docSidebarVersionDropdown: true ?

To me it does not make sense to:

But it could make sense to:

The current sidebars.js file is hard to modify to add some sidebar top-level sidebarr configs like booleans: we'd have to ensure backward compatibility but this is a possibility:

const sidebars = {
  mySidebar: {
    versionDropdown: "top-sticky",
    items: [...]
  }
}

We could also add a type and allow it only as top-level item (simpler for retrocompatibility)?

const sidebars = {
  mySidebar: [{type: "versionDropdown"},...]
}

Note we want to enable custom navbar items and custom blog sidebar items, so maybe we also need to think about custom doc sidebar items too? I don't really have a use-case for this yet.

Just wanted to open the discussion around this feature's design.

slorber commented 2 years ago

Another site using this:

https://docs.dyte.io/react/quickstart

image

dsmmcken commented 2 years ago

An alternative might be allowing components to accept children for rendering, either before or after? Then I could wrap the component, and allow more generic customization.

Although, my specific use case is also to move the switcher here.

slorber commented 2 years ago

An alternative might be allowing components to accept children for rendering, either before or after? Then I could wrap the component, and allow more generic customization.

Not sure what you mean here 😅 which component? and how do you provide that children yourself?


Note: you can already wrap the desktop sidebar to add top/bottom elements.

We even have a demo on our own website here, you can see a top/bottom ad container in the test sidebar:

CleanShot 2022-04-22 at 11 34 49@2x

page: https://docusaurus.io/tests/docs

code: https://github.com/facebook/docusaurus/blob/main/website/src/theme/DocSidebar/Desktop/Content/index.js

Now, these 2 blocks are "static" and not part of the sidebar scrollable area.

I don't think we provide a way to easily add top/bottom sidebar components to the scrollable area atm, but we could work on that if someone has a use-case for this

dsmmcken commented 2 years ago

these 2 blocks are "static" and not part of the sidebar scrollable area.

Hmm, I was thinking I wanted my version switcher to be part of the scroll area, without really thinking it through, but it could equally be static, and that actually might make more sense. I wrapped DocSidebarItems and displayed before the items, only if level == 1, to get it part of the scroll area.

I was thinking kinda like how dropdown has dropdownItemsBefore and dropdownItemsAfter, you could pass items for before or after the docsidebar to get it into the scroll area.

slorber commented 2 years ago

I wrapped DocSidebarItems and displayed before the items, only if level == 1, to get it part of the scroll area.

hmmm yes that can work but maybe not in a very straightforward way. We could as well extract the scrollable area in a separate container

I was thinking kinda like how dropdown has dropdownItemsBefore and dropdownItemsAfter, you could pass items for before or after the docsidebar to get it into the scroll area.

configs such as dropdownItemsAfter only allow passing navbar items. It only works if what you provide is a navbar item, and does not work to add arbitrary React components at the top/bottom of the sidebar scroll container

dsmmcken commented 2 years ago

configs such as dropdownItemsAfter only allow passing navbar items. It only works if what you provide is a navbar item, and does not work to add arbitrary React components at the top/bottom of the sidebar scroll container

I understand that, I just meant doing a similar concept of accepting elements to insert before and after, for the docsiderbar it would be any react component.

All good, I have a solution that works for me.

slorber commented 2 years ago

I understand that, I just meant doing a similar concept of accepting elements to insert before and after, for the docsiderbar it would be any react component.

Instead we'll provide a way to register your own doc sidebar item types, so instead of using "doc" or "category" you could use a type "myCustomVersionSelect" (or use the pre-built one that we'll likely provide) that you can use at the beginning/end but also anywhere in the middle of your sidebar

Slightly related to https://github.com/facebook/docusaurus/issues/7227

Note you can already insert arbitrary HTML content in the sidebar scrollable container: https://docusaurus.io/docs/sidebar/items#sidebar-item-html (but it's not using React so making this content interactive may be complicated and require vanilla js)

Jersyfi commented 1 year ago

@slorber for my multi framework documentation like in the example dyte docs https://github.com/facebook/docusaurus/issues/5706#issuecomment-979933443 i need this feature too. You are right that it is possible to add custom html using vanilla js at the top or bottom of the sidebar, but it is not a great solution. Do you have any new information on this feature?

slorber commented 1 year ago

We don't have a workaround currently but we could add a similar one to https://github.com/facebook/docusaurus/issues/7227: allowing you to register custom sidebar items with swizzle, and do not reject items with a custom- prefix in the type name.

That's not perfect but it's a good short-term workaround.

Jersyfi commented 1 year ago

@slorber Perfect thank you 👍

RoiArthurB commented 1 year ago

Hi @slorber , any update on this feature? I guess it could be very interesting for most people to be able to have the version number only in the documentation part (and not the blog, index page, etc; where it's not relevant)!

Also, I did try to inspire myself from the examples above and tried to add the DocsVersionDropdownNavbarItem in the wrapped swizzled DocSidebar as this:

// website/src/theme/DocSidebar/index.js
import React from 'react';
import DocSidebar from '@theme-original/DocSidebar';
import DocsVersionDropdownNavbarItem from '@theme-original/NavbarItem/DocsVersionDropdownNavbarItem';

export default function DocSidebarWrapper(props) {
  return (
    <>
      <div className="custom-sidebarVersion">
        <p><u><b>Version:</b></u> <DocsVersionDropdownNavbarItem /></p>
      </div>
      <hr />
      <DocSidebar {...props} />
    </>
  );
}

It worked very well in dev mode (yarn docusaurus start), but failed every time while compiling the project (yarn build) (built log here)... Any clue?

slorber commented 1 year ago

@RoiArthurB no update but still agree this could be useful.

The build error is because DocsVersionDropdownNavbarItem is not programmed defensively and is only designed to be used with default values set in our config validation schema.

Passing default values yourself should work, try this: <DocsVersionDropdownNavbarItem dropdownItemsBefore={[]} dropdownItemsAfter={[]} />

RoiArthurB commented 1 year ago

@slorber Thanks your solution did work. I'm looking forward to have a proper way to integrate it, but right now, this simple trick gives a good enough result :)

image

glitch-txs commented 1 month ago

hi @slorber I'm looking to implement something like this but for different frameworks supports as shown in this picture from your comment. Do you know if this is possible atm in Docusaurus v3?

So basically I have an SDK that can be implemented in different frameworks, the documentation for its implementation changins slightly for each framework, so something like this would be very useful

slorber commented 1 month ago

@glitch-txs the Dyte docs is using Docusaurus v3.1.1 (can be seen in HTML head meta tags): https://docs.dyte.io/react-ui-kit

So yes this is definitively possible, similar to how it was in v2. The Dyte website is open source so you can just copy their solution.