facebook / docusaurus

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

Support swapping out routers (IPFS react router, HashRouter...) #6645

Closed OxMarco closed 2 years ago

OxMarco commented 2 years ago

Have you read the Contributing Guidelines on issues?

Description

I suggest that we explore ways to make Docusaurus deployment to IPFS possible. At the moment, the main blocker is the baseUrl that cannot be precomputed before the website is deployed.

I tried using Piñata to deploy the build folder to IPFS and got an error

We suggest trying baseUrl = /ipfs/QmUsHzX.....BdPd/

Has this been requested on Canny?

No response

Motivation

IPFS is a decentralised and very price competitive storage system

API design

No response

Have you tried building it?

No response

Self-service

Josh-Cena commented 2 years ago

Hi, Docusaurus uses the base URL to build your site and pre-generate certain static HTML, so it would be non-trivial to support this use-case. Could you tell me:

Note that as stated multiple times in the issue template, we expect the issue to be very detailed and well-thought, not a random feature request. Please use the Canny board for that.

OxMarco commented 2 years ago

Upon uploading content (in this case the build folder) to an IPFS node, the resulting URL is the hash of the uploaded files. Being an immutable filesystem, the hash works both as a pointer to the document and as an anti-tampering system. Deployment of the same exact file(s) will yield the same URL, as hashes are deterministic.

We could try to use ipfs-react-router module to take care of the base URL. Injecting the URL ex-post would not be doable as content on IPFS cannot be edited.

Josh-Cena commented 2 years ago

I see. So your use-case is that you want to deploy the build output to IPFS, and IPFS will calculate an immutable base URL based on the HTML/JS bundle hash; when you re-deploy, the base URL would change?

The solution seems to be swapping out the router? We have a similar use-case where someone's trying to deploy to AWS and they want to use the hash router: https://docusaurus.canny.io/feature-requests/p/support-for-different-routers

Maybe we should make the router swizzleable?

Josh-Cena commented 2 years ago

Note that we aren't using the React router basename feature yet and base URL is handled a bit hackily now, which has caused problems like #6462, #6315, and #6294. If we are to support an alternative router, we have to make sure basename is supported first. And that would probably be after we've migrated to React router v6.

OxMarco commented 2 years ago

Supporting swappable routers is probably a good way to support IPFS without introducing destructive changes to the codebase. I used the aforementioned react ipfs router in the past and it worked pretty well as a solution to deploying an app without knowing the URL beforehand.

slorber commented 2 years ago

Please assume I have 0 knowledge of IPFS / Piñata (which is not totally untrue 😅)

Why do you want that? How would it work? Do you have examples of other open-source SSG SPAs being deployed to IPFS (Gatsby, Next, Jekyll, Eleventy, whatever...?) that we could inspect?

OxMarco commented 2 years ago

IPFS - the interplanetary file system - is a distributed network of independent nodes that offer data storage and replication for immutable data, it can be multimedia, PDFs or websites too. For static website generators like the ones you mention, the build folder containing compiled artefacts is uploaded to an IPFS node and then served to the open public using its hash, called CID, as URL (in the form of ipfs://CID, or accessible using a public HTTP gateway like https://gateway.ipfs.io/ipfs/CID).

An example of apps deployed to IPFS is the Uniswap frontend

slorber commented 2 years ago

Sorry but I still don't understand why do you want this, apart for the beauty of publishing it in a distributed way?

Please don't give me technical reasons, I'm looking for concrete business outcomes.

Why deploying on IPFS is superior to any other Jamstack host? Why should we care?

An example of apps deployed to IPFS is the Uniswap frontend

I see a GitHub app, linking to https://app.uniswap.org/

This site seems to be hosted (or at least proxied) through Cloudflare, which looks to me already possible with Docusaurus. I don't understand how to interpret your example.

Please provide a very simple and easy-to-understand example on how you deploy a static site on IPFS.

I suggest using the following structure:

- index.html
- blog.html
- assets/xyz-hash56sy756b7.js
- assets/css-hash67a823gh5.js

I'd like to understand how you access each of these URLs from your browser.

Actually, I'd suggest to create by yourself a very simple example SPA and deploy it to IPFS, giving us the instructions to browse/inspect this deployment on both Github + IPFS. This way we can understand better what you are talking about.


Regarding the routing based on a hash (not to be mistaken with the hash fingerprinting of emitted assets), please note that we are a static site generator, pre-rendering HTML files on the disc.

A URL hash will not be sent to the client request, and you can't get it on the server to decide which HTML file to serve. For these reasons it's not a good fit for any SSG because it means that the server can at best only server index.html which contains the homepage, and only later render the page you are really aiming to visit.

If you want to build anything hash-based, I suggest to not use a SSG in the first place 🤷‍♂️

slorber commented 2 years ago

Note, you can see by yourself if you disable JS that the Uniswap app is not a static app. It is entirely generated on the client side

image
OxMarco commented 2 years ago

Business value of IPFS hosting is cheaper hosting price, redundancy and data immutability. Some people then use Cloudflare to connect a custom DNS to the IPFS route for better UX.

Uniswap frontend is a ReactJS app, it is dynamically generated as it interacts with the blockchain.

Considering your point it seems Docusaurus isn't fit for a content distribution system like IPFS

mrkvn commented 2 years ago

From what I researched, build for create-react-app does not work with IPFS too. But putting "homepage": "./", in package.json works. Thus, I think it's just about pathing.

So I did the same thing for build files for docusaurus. For example, I changed all the hrefs such as "/assets/..." to "./assets/..." and it worked. I'm not sure why putting "homepage": "./", in package.json does not make the build files to relative path though. So I had to do it manually.

Josh-Cena commented 2 years ago

@mrkvn There's a plugin to do this. See https://github.com/facebook/docusaurus/issues/3825#issuecomment-911593835

mrkvn commented 2 years ago

@Josh-Cena Thanks. That'd be a big help. I'll check it.

mrkvn commented 2 years ago

@Josh-Cena Looks like it's not there anymore. Page not found. :(

mrkvn commented 2 years ago

This helped. #448 (comment)

ColinLondon commented 9 months ago

This helped. #448 (comment)

Yup, that takes care of the relative links. But some features are lost when running offline (mode switching, hideable sidebar, tabs, etc.).

slorber commented 9 months ago

As part of the offline-mode support (https://github.com/facebook/docusaurus/issues/3825), we are likely to add support for a client-only rendered app using the hash router.

See

As far as I understand, this could allow to support deploying to IPFS?