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

Limiting number of versions visible in the version dropdown switch #10833

Open
2 tasks done
hrumhurum opened this issue Jan 12, 2025 · 5 comments · May be fixed by #10852
Open
2 tasks done

Limiting number of versions visible in the version dropdown switch #10833

hrumhurum opened this issue Jan 12, 2025 · 5 comments · May be fixed by #10852
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.

Comments

@hrumhurum
Copy link

hrumhurum commented Jan 12, 2025

Have you read the Contributing Guidelines on issues?

Description

The proposed feature allows to declutter the UI/UX by limiting the maximum number of versions that are shown in the version dropdown.

Has this been requested on Canny?

No response

Motivation

When documentation has multiple versions, Docusaurus shows a helpful dropdown switch populated with them. Unfortunately, the switch becomes visually overcrowded relatively quickly by trying to offer too many versions at the same time:

{354351EC-E1C0-432F-A796-B00CC5ACE351}

While it depends on a product the documentation is offered for, users tend to stick to more recent versions with a greater probability. We can utilize this observation to offer a better UX for the version selection.

For example, the product I work on has a quite a few versions, and visitors are going to have troubles selecting a version with the existing version switcher UX due to visual clutter. At the same time, we cannot really delete older versions because they serve a considerable minority of customers who prefer to stick to older product versions for X reasons. (Especially given the fact that the product offers online-only help as an installation option, it is important to preserve its online presence, mostly for service continuity reasons.)

By limiting the number of versions shown in the dropdown switcher, we declutter the UX. To cover even older versions, we (optionally) add "All versions" dropdown item that leads to a custom /versions page that offers the full list of versions in a categorized manner. The standalone /versions page is created and maintained manually, as well as an optional "All versions" dropdown item.

API design

To limit the maximum number of versions that are shown in the version switch UI control, a Docusaurus user defines optional dropdownMaxItemCount property for the docsVersionDropdown navigation bar item in the theme configuration section of docusaurus.config.ts file:

const config: Config = {
  // ...
  themeConfig: {
    // ...
    navbar: {
      items: [
        // ...
        {
          type: "docsVersionDropdown",
          position: "right",
          dropdownActiveClassDisabled: true,
+         dropdownMaxItemCount: 4,
          dropdownItemsAfter: [
            {
              to: "/versions",
              label: "All versions"
            },
          ]
        },
      ]
    }
  },
  // ...
};

Additionally, a Docusaurus user may add a custom mechanism for accessing older versions. For example, it can be a custom page "All versions" which is defined in dropdownItemsAfter property in the sample above.

The effect of the proposed options is that the maximum number of the displayed dropdown versions is now limited to the specified value (4):

{93CEC435-A603-4430-9042-98A4AD3AF7C7}

Have you tried building it?

As a proof of concept, I have implemented the proposed feature. It required changes to @docusaurus/theme-classic and @docusaurus/plugin-content-docs packages.

Live preview

  1. The website with the proposed feature on (no UX problems)
  2. The original website without the proposed feature (it has UX problems due to the constantly growing number of versions)

Implementation stages

Stage 1 of 2. Limiting the number of displayed versions in the dropdown

This is a simple change that required changes in @docusaurus/theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx component. The core algorithm perfrorms a slice of the version array according to the specified dropdownMaxItemCount value:

  const items = [
    ...dropdownItemsBefore,
-   ...versions.map(versionToLink),
+   ...versions.slice(0, dropdownMaxItemCount).map(versionToLink),
    ...dropdownItemsAfter,
  ];

The dropdownMaxItemCount option has formal constraints:

const DocsVersionDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  type: Joi.string().equal('docsVersionDropdown').required(),
  docsPluginId: Joi.string(),
  dropdownActiveClassDisabled: Joi.boolean(),
+ dropdownMaxItemCount: Joi.number().integer().min(0),
  dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]),
  dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]),
});

Notably, the dropdownMaxItemCount option explicitly allows 0 value, giving a space for further UI customizations.

Stage 2 of 2. Storage persistence of a selected version

The existing docsVersionDropdown component exhibits an interesting behavior of storing a selected version in a persistent storage (localStorage). This is required in order to ensure that an end-user always navigates in the scope of a selected version, even if he visits URIs that do not contain version information.

To support that scenario for custom version catalog pages, a new DocVersionLink React component was added to @docusaurus/theme-classic module. It can be then used in a custom versions.mdx page, for example:

import DocVersionLink from '@theme/DocVersionLink';

# Documentation Versions

## Current Version

| Version | Release Date | | |
|:-|:-|:-|:-|
| 2024.3 | December 31, 2024 | <DocVersionLink to="docs">Documentation</DocVersionLink> | [Release Notes](#) |

## Previous Versions

### 2024

| Version | Release Date | | |
|:-|:-|:-|:-|
| 2024.2 | September 17, 2024 | <DocVersionLink to="docs/2024.2">Documentation</DocVersionLink> | [Release Notes](#) |
| 2024.1 | March 29, 2024 | <DocVersionLink to="docs/2024.1">Documentation</DocVersionLink> | [Release Notes](#) |

### 2023

| Version | Release Date | | |
|:-|:-|:-|:-|
| 2023.4 | November 29, 2023 | <DocVersionLink to="docs/2023.4">Documentation</DocVersionLink> | [Release Notes](#) |
| 2023.3 | August 9, 2023 | <DocVersionLink to="docs/2023.3">Documentation</DocVersionLink> | [Release Notes](#) |
| 2023.2 | April 30, 2023 | <DocVersionLink to="docs/2023.2">Documentation</DocVersionLink> | [Release Notes](#) |
| 2023.1 | January 5, 2023 | <DocVersionLink to="docs/2023.1">Documentation</DocVersionLink> | [Release Notes](#) |

Internally, DocVersionLink component analyzes the target URI, and if it finds an associated versioned content, it injects a corresponding storage persistence logic. DocVersionLink works transparently to a user, so there is no need to specify plugin identifiers manually. Everything is handled automatically.

You can see the version persistence in action here.

Self-service

  • I'd be willing to contribute this feature to Docusaurus myself.
@hrumhurum hrumhurum 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 Jan 12, 2025
@slorber
Copy link
Collaborator

slorber commented Jan 16, 2025

Thanks for the detailed proposal

Honestly, is 7 versions in the dropdown really a big deal? Reducing it to 4 will not be a meaningful change IMHO.

I agree that some sites will likely have more than 7, but in this case the strategy is likely to "archive" older versions so that your site's build time remains reasonable over time.

That's what I do for our website and the RN one:

Image

https://reactnative.dev/versions

Image

Archived versions are external links hosted on another read-only subdomain.


Now if you really want this feature, I'm not a fan of dropdownMaxItemCount because it assumes that the versions to keep are the last ones, which is not necessarily the case depending on versioning patterns.

When versioning by year.Q like you do, maybe it makes sense.

But if you were using SemVer, maybe you'd have versions such as:

2.1.1
2.1.0
2.0.1
2.0.0
1.0.1
1.0.0

And maybe you'd want to have in the dropdown:

2.1
2.0
1.0

Or maybe just

1.x
2.x

I'd prefer an API that gives more flexibility to the user to decide what should be displayed, maybe also allowing them to override the labels for each version (and maybe more config in the future)

What about this instead?

{
          type: "docsVersionDropdown",
          position: "right",
          dropdownActiveClassDisabled: true,
+         versions: {
+           "1.0.1": {label: "1.x"},
+           "2.1.1": {label: "2.x"},
+         },
          dropdownItemsAfter: [
            {
              to: "/versions",
              label: "All versions"
            },
          ]
        },

Storage persistence of a selected version

I'm not 100% sure clicking a link should persist the underlying version in local storage.

Selecting it in the dropdown is a more "explicit" choice so it makes more sense to do it in the dropdown, IMHO. For example, our DocsVersionNavbarItem navbar item does not persist, despite linking to a version's root.

If we introduce such a link component, I'd prefer if the persistence is opt-in, and use plugin id + version name props:

<DocsVersionLink docsPluginId="ios" version="2023.4" persist>
  Documentation
</DocVersionLink>

@slorber slorber removed the status: needs triage This issue has not been triaged by maintainers label Jan 16, 2025
@hrumhurum
Copy link
Author

hrumhurum commented Jan 16, 2025

Honestly, is 7 versions in the dropdown really a big deal?

It is a big deal to some of us, but the exact number of actual versions is relative and depends on a particular product and versioning scheme.

The problem is that the year-based versioning produces an ever growing amount of versions, non stop. For example, our product has 50+ versions after being 15+ years in development. Our customers have a usual gap up to 5 years, meaning that at least 5 * 4 (avg. number of versions per year) = 20 last versions should remain easily accessible to them. In the past, we solved that by distributing the documentation file as a part of the product setup, but nowadays more and more people prefer to use the documentation online. This is what we try to achieve with Docusaurus. Yes, having 7 versions in the dropdown is bearable, but 20+ versions are out of the question.

Semver-based versioning is different, it operates by lineages and usually there are not too many of them. 1.x, 2.x, 3.x etc. Just 3 major versions in 5+ years, so after 10 years of development it is going to be about 6 major versions. A single dropdown can contain them all, not a big deal.

Those differences in the versioning schemes create discrepancies in perceptions.

Archived versions are external links hosted on another read-only subdomain.

We considered that approach, but given that we have "a non-stop production line with an ever growing amount of versions", it is too much of unscalable work that needs to be done/considered every time a new version is out. Once again, this is mostly caused by the year-based versioning scheme.

But if you were using SemVer... I'd prefer an API that gives more flexibility to the user to decide what should be displayed, maybe also allowing them to override the labels for each version

I 100% agree, your proposition looks good, and I am super happy to implement it as well. At the same time, year-based versioning needs dropdownMaxItemCount (or an equivalent) because that versioning scheme reflects an ever growing list of versions with a predictable usage distribution (top N latest versions). Both options are combinable and can happily coexist together.

I'm not 100% sure clicking a link should persist the underlying version in local storage. I'd prefer if the persistence is opt-in, and use plugin id + version name props

I trust your instinct. DocsVersionLink with explicit docsPluginId and version is even easier to implement than an automated version, and it makes the job done. The preference of the opt-in persistence is noted, it indeed depends on a use case.


Going beyond the implementation, I am also willing to document this feature in full with all the details of its usage.

@hrumhurum
Copy link
Author

hrumhurum commented Jan 16, 2025

I am starting to work on this feature. There will be two stages with two separate pull requests:

  1. Customization of displayed versions in the dropdown:
    1.1. implementation
    1.2. documentation
  2. DocsVersionLink:
    2.1. implementation
    2.2. documentation

If you have any ideas, comments, desires, guidance - feel free to discuss.

@slorber
Copy link
Collaborator

slorber commented Jan 17, 2025

Semver-based versioning is different, it operates by lineages and usually there are not too many of them. 1.x, 2.x, 3.x etc. Just 3 major versions in 5+ years, so after 10 years of development it is going to be about 6 major versions. A single dropdown can contain them all, not a big deal.

That's absolutely not true, there are many projects using semver and releasing many major versions per year

This is just one example among many others: React Native has 78 versions after 10 years. Versions older than 2 years ago are not maintained anymore and have been archived, because building a site with 78 docs versions would be much slower.

Image

We considered that approach, but given that we have "a non-stop production line with an ever growing amount of versions", it is too much of unscalable work that needs to be done/considered every time a new version is out. Once again, this is mostly caused by the year-based versioning scheme.

We all have an ever growing amount of versions.

What does "non-stop production line" means?

  • Are you still releasing things for the 2020.1 release?
  • Do these things require docs changes?

If the answer is no, then what's the problem with archiving that version?

If the answer is yes, then ok but I feel a bit sorry for you 😅 this is weird and unsustainable IMHO.

I 100% agree, your proposition looks good, and I am super happy to implement it as well. At the same time, year-based versioning needs dropdownMaxItemCount (or an equivalent) because that versioning scheme reflects an ever growing list of versions with a predictable usage distribution (top N latest versions). Both options are combinable and can happily coexist together.

If my proposition is implemented, I don't see the need to add dropdownMaxItemCount: the versions that are not provided are automatically filtered so you have a way to filter things with a per-version granularity instead of keeping only the first items of the version array. Introducing an extra API for that would create an API ambiguity.

I trust your instinct. DocsVersionLink with explicit docsPluginId and version is even easier to implement than an automated version, and it makes the job done. The preference of the opt-in persistence is noted, it indeed depends on a use case.

Going beyond the implementation, I am also willing to document this feature in full with all the details of its usage.

DocsVersionLink should probably be exposed in @docusaurus/plugin-content-docs/client. We haven't really documented these plugin client side APIs yet but we should start doing that.

I am starting to work on this feature. There will be two stages with two separate pull requests:

Yes, both things should be implemented in 2 separate PRs since they are different features. Let me know when there's something to review.

@hrumhurum
Copy link
Author

I created PR #10852 containing implementation and documentation for the customization of displayed versions in the docs version dropdown.

Here is a demo site that demonstrates the implemented functionality in action:

https://gp-temp-docusaurus-app1.netlify.app/eazfuscator.net

Please try it to get the actual look and feel, maybe you will have some feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants