facebook / docusaurus

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

Allow linking to versioned docs from footer and page #7402

Open lorenzolewis opened 2 years ago

lorenzolewis commented 2 years ago

Have you read the Contributing Guidelines on issues?

Prerequisites

Description

I'm expecting to be able to use links in pages (such as index.js) and in the footer config to docs.

We would like to have all files under the docs directory to be served at the root of the site. We would also like to have the URLs for all docs versioned, so we're following the setup for the second use case described here: https://docusaurus.io/docs/versioning#configuring-versioning-behavior.

When doing this, the links on the included reproduction site on index.js as well as the footer are broken.

Reproducible demo

https://stackblitz.com/edit/github-pryivb?file=docusaurus.config.js

Steps to reproduce

  1. In docusaurus.config.js, in the docs preset object, set routeBasePath to "/" and add the following object under `versions':
    current: {
    label: 'v1',
    path: 'v1'
    }
  2. See how the footer link and the tutorial link on the index page are now broken

Expected behavior

Docusaurus should be able to build the urls similar to how it is in the navBar (by introducing an item option to the footer to be able to specify type: 'doc' and docId: 'your-doc-id-here. If there is not currently a way to reference a page like this from a non-doc page (such as index.js), I would expect some sort of API from Docusaurus to allow it to build out this link dynamically (similar to how the navbar links are)

Actual behavior

The links to docs are broken (see Docs -> Tutorial in the footer and the "Docusaurus Tutorial - 5min" button link on index.js)

Your environment

Self-service

Josh-Cena commented 2 years ago

Happy to accept a PR adding type: "doc" kind of link to the footer.

As for page links, there's an undocumented hook but it's quite stable anyways:

import Link from "@docusaurus/Link";
import { useLatestVersion } from "@docusaurus/plugin-content-docs/client";

function MyPage() {
  const latestVersion = useLatestVersion();
  return <Link to={`${latestVersion.path}somePage`}>Link</Link>;
}
lorenzolewis commented 2 years ago

Makes sense. I can look into implementing a PR for the footer. Can you point me in the direction of where the logic for doing this is in the navbar? Not very familiar with the codebase yet.

Would you be open to having something like a docId attribute to the Link component so this can be done automatically? Could also look at implementing that possibly.

Josh-Cena commented 2 years ago

Would you be open to having something like a docId attribute to the Link component so this can be done automatically?

No. Link is a core component and it should not be aware of the docs plugin's data structure, so that's a hard no😟

Can you point me in the direction of where the logic for doing this is in the navbar?

I assume you mean the footer? The link item is here: https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/Footer/LinkItem/index.tsx

It will receive one single link item as defined in the footer config. Right now, everything will be a simple link; but we would add a bit more polymorphism here by introducing the type: "default|doc" tag. You can get some inspiration from the navbar item entry point: https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/NavbarItem/ComponentTypes.tsx I don't know if it has to be as complicated as that. Considering we only have two item types, my suggestion would be a simple

export default function FooterLinkItem({item}: Props): JSX.Element {
  // ...
  if (item.type === "doc") {
    return <Link /* transforming doc ID to the right link props ... */ />;
  }

  return <Link ...></Link>;
}

Also remember to add it to the validation schema: https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/validateThemeConfig.ts

And I think we'll be good.

lorenzolewis commented 2 years ago

Would you be open to having something like a docId attribute to the Link component so this can be done automatically?

No. Link is a core component and it should not be aware of the docs plugin's data structure, so that's a hard no😟

Would a component like <DocLink> be feasible that's part of the doc plugin and not core? Essentially just a wrapper around <Link>

Josh-Cena commented 2 years ago

That could work, yeah. If you want to make a POC, feel free to!

slorber commented 2 years ago

👍 for DocLink as a public API and usable in footer.It can use useLayoutDoc(docId, docsPluginId) similarly to DocNavbarItem

It would be fine to replace the setup we have for NavbarItems because users may also want custom footer items later and we could also introduce other item types