shuding / nextra

Simple, powerful and flexible site generation framework with everything you love from Next.js.
https://nextra.site
MIT License
11.21k stars 1.23k forks source link

Versioned docs #20

Open jaredpalmer opened 3 years ago

jaredpalmer commented 3 years ago

Kind of like next.js docs load the route manifest file from github version tags, would be rad to use same technique somehow.

helloworld commented 3 years ago

+1 it would be very useful to see versioning implemented. Our team had to spend a lot of time building a custom documentation site that supported versioning since we couldn't find any other existing solutions.

dimaMachina commented 2 years ago

We missing this feature for our websites and I can work on this next week! Cc @shuding

shuding commented 2 years ago

@B2o5T I have some thoughts regarding this, let's find some time to discuss next week 👍. In general it should be similar to remote MDX but more

dimaMachina commented 1 year ago

will break the silence đŸ€

@shuding I think we can support different kinds of versioning docs

1. a simple way, via regular folders like below

image

2. via some advanced technique like remote downloading from some specific commit history hash

The WIP for the first one was implemented today and we'll test it soon on GraphQL Yoga v3

Let's start by small and improve it!

https://user-images.githubusercontent.com/7361780/189004955-15ece872-b416-4e00-8604-0c3635063be1.mov

I'll prepare soon my initial implementation PR

shuding commented 1 year ago

I think 2 is the way to go, but curious about your solution for the meta information. 👀 @B2o5T

In the long term I believe that “remote MDX” should be solved by React Server Components, but that would require a big refactoring of the framework (looking forward to that future).

dimaMachina commented 1 year ago

@shuding

but curious about your solution for the meta information

source code is here ;)

In the long term I believe that “remote MDX” should be solved by React Server Components, but that would require a big refactoring of the framework (looking forward to that future).

What yours through about future problems with remote versioning:

shuding commented 1 year ago

@B2o5T Please don’t mind that I’m dumping all my thoughts over the years!

I think ideally, versioned docs (including the default version) can be placed in anywhere. The user just need to configure a method to retrieve it. By default it’s the FS (pages/) but user can specify a different root path (for example v1/) or a function to fetch the content.

That way, you can put your docs in Notion, git, or CMS.

A solution is, since Nextra integrates into the compiler level, it can download these MDX files and put them in pages/, before building the website. Or, we use a match all route [[
slug]] and getStaticPaths to download these MDX files and compile them (using Nextra’s compiler) inside getStaticProps. I think that’s the most viable way for now if we want to make this general enough.

The only downside of above is, the build time will explode over time. After all you don’t want to rebuild legacy docs every time. A perfect solution for this kind of problem is to use lazy SSG (Next’s fallback: 'blocking' mode), that skips these legacy docs paths at build time, and behave like SSR when someone actually visits it. After SSR it’s cached and static again.

But with MDX, it has another bigger problem. If we fetch and compile the content during the runtime, we need to execute MDX there. MDX itself is actually JavaScript and you can do anything with it, which is remote code execution and very dangerous, hard to optimize. Both next-mdx-remote and mdx-bundler use something like eval. Importing components is one of the problems in that scope too. Markdoc avoids this problem because it’s template, not JS. I don’t know how to solve this problem yet, maybe we can have a stricter MDX syntax that doesn’t allow you to define components inline, but I hope it’s OK to use eval.


Edit on GitHub link will not work if legacy docs are stored in main branch

static images should be disabled for remote docs? or content from /public directory of legacy docs should be copied

I think it’s fine to disable these for legacy version :P

ixahmedxi commented 1 year ago

We at tRPC would love to migrate away from docusuarus to nextra but the versioning feature is our only blocking feature as that we need to maintain both v9 and v10 docs simultaneously, would love to help out in any way as well! great work on nextra btw we love it.

vpavicic commented 1 year ago

+1 for this feature :) it would be really useful for our project as well

timmyjose commented 11 months ago

Hmm. I thought I was missing something in the docs, but versioning support is not really present right now from the looks of it. That's too bad - option 1 leads to a lot of duplicated code.

zachtil commented 6 months ago

Hey, lots of appreciation for this project. Seeing this unpinned, wondering if this will make it into Nextra 3 or has this plan changed?

vordgi commented 4 months ago

I became interested in this idea and want to tell what came out of it:

  1. This cannot be done using getStaticProps. Yes, as @shuding wrote above - mdx files in nextra are too complex. And they consist not only of md, but also of components. And you can't assemble and pass components inside by returning them through props - they need to be fully assembled by webpack.
  2. There is another problem with components - they also need to have versioning. That is, it is not enough to clone pages - you need to clone components. And in fact, you need to clone all the files from the previous version, otherwise you cannot do without artifacts (and asking users not to change files is nonsense).
  3. The next resulting problem - in the page files, you need to reconfigure the imports so that they take exactly the versioned files (it was @src/assets/intro.png, now @src/versions/v2/assets/intro.png). This also applies to various dynamic imports.
  4. There are absolute links to other pages inside the files. If now the version lies, for example, under /v2/docs/, then all links need to be changed to a versioned one - both inside files and in nextra navigation (but this can be solved with the context around each page).
  5. It will not be possible to do versioning for _app and _document files, since they can be only one in the directory (in the future this problem will be with the root layout).

What I would suggest:

Just add a component for navigating versions. Let users build the application themselves and deploy it as they see fit. Add to the config versions: { href: string; title: string }[], where href is either origin (https://v1.mydoc.com/), or base (/v1)

All of the above is generally feasible, but I highly doubt it's worth it. You can see a primitive implementation with a solution to some of the problems here - nimpl-versioner (and try it). This is a separate package, which can be run before the build and it will clone the files and configure them (of course with a probability of bugs, this is not a full-fledged utility, just example).

mackinleysmith commented 1 month ago

I am also highly interested in this functionality and will likely have to build it custom for my organization. My thought is to upload my mdx documents directory to S3 each time our package is deployed, under a directory named by the current version. Then, something like https://github.com/hashicorp/next-mdx-remote might allow me to pull the docs of the corresponding version.

Mike-Logit commented 1 month ago

I just found this issue after mentioning a similar idea here: https://github.com/shuding/nextra/pull/2940

I want to control the visibility of pages in the menus (the sidebar and nav bar) based on a versioning dependency specified in the URL (either a query parameter or path, it doesn't matter).

Most of my doc pages should be shared between all versions, but maybe a small number of pages have a dependency on different versions.

Where my requirements diff is that I want a dropdown component to control what version of documentation they're viewing and to let the user know there's more up to date documentation for a newer version (inspired by the ASP.Net Core documentation).

I'm not sure if the solutions mentioned here would also solve my requirements? It definitely sounds interesting, though!

IMB11 commented 1 month ago

I ended up moving to vitepress, which has a versioning plugin.