docusaurus icon indicating copy to clipboard operation
docusaurus copied to clipboard

RFC: Doc sidebar version dropdown

Open slorber opened this issue 4 years ago • 16 comments

🚀 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:

  • nest a version dropdown inside a sidebar category, so it can't be a sidebar item directly
  • display 2+ versions dropdowns inside the same sidebar

But it could make sense to:

  • display the dropdown at the bottom (sticky?) or the top (sticky?)
  • have different config per-sidebar?

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 avatar Oct 14 '21 17:10 slorber

Another site using this:

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

image

slorber avatar Nov 26 '21 12:11 slorber

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.

dsmmcken avatar Apr 21 '22 18:04 dsmmcken

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

slorber avatar Apr 22 '22 09:04 slorber

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.

dsmmcken avatar Apr 22 '22 13:04 dsmmcken

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

slorber avatar Apr 22 '22 15:04 slorber

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.

dsmmcken avatar Apr 22 '22 15:04 dsmmcken

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)

slorber avatar Apr 22 '22 15:04 slorber

@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?

Jersyfi avatar Mar 06 '23 11:03 Jersyfi

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.

slorber avatar Mar 08 '23 17:03 slorber

@slorber Perfect thank you 👍

Jersyfi avatar Mar 09 '23 12:03 Jersyfi

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?

RoiArthurB avatar Apr 27 '23 03:04 RoiArthurB

@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={[]} />

slorber avatar Apr 27 '23 10:04 slorber

@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

RoiArthurB avatar Apr 28 '23 04:04 RoiArthurB

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

glitch-txs avatar May 30 '24 14:05 glitch-txs

@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.

slorber avatar May 31 '24 07:05 slorber

I implemented something like this, but didn't like the dropdown in the sidebar because it was no longer reliably available/visible (since the sidebar is hidden away on narrow/mobile displays). Doing that experiment made me realize how duplicative/redundant the doc version badge is, since the dropdown and badge ended up being right next to each other.

So, I swizzled the doc version badge to instead produce the dropdown at the top of doc page bodies:

image

I personally think this is a win all around, so thought I'd share it as another non-navbar approach. (Next step will be to move the dropdown so that it's in a row with the first header in the doc being viewed so it's not wasting vertical space all on its own, but that's for another day :-))

cemerick avatar Sep 30 '24 20:09 cemerick