facebook / docusaurus

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

Improve explanation of what SSR is #7213

Closed priyatam closed 2 years ago

priyatam commented 2 years ago

Have you read the Contributing Guidelines on issues?

Description

In the Architecture page and SSG/SSR documentation , it's mentioned that Docusaurus generates Server bundle and Client bundle. However, when I run docusaurus build, the following is generated in build folder (which looks like CSR):

The two main js files in assets/js are references in all the index files under docs and nested folders under docs.

  1. /assets/js/runtime~main.cf87a1ef.js
  2. /assets/js/main.f83ca060.js

The point of SSR is to avoid Js files altogether for content generation, but it looks like docusaurus is using a hybrid model with content in index.html + js file + chunked-js file. If that's so, what exactly is in the chunked-js file–that's not in index.html? How can I generate a pure static site where all content is generated in html without a reference to a js file?

Self-service

Josh-Cena commented 2 years ago

Hi, "server bundle" means the HTML files, and "client bundle" means the React SPA files (those JS assets). JS is critical because our site is ultimately hydrated into an SPA with client routing. NOT using JS will work, but will result in far degraded user experience (see #3030). This is the point of us being a React SPA, instead of something like Jekyll.

The point of SSR is to avoid Js files altogether for content generation,

That's not true. SSR is a progressive enhancement technique. It's job is to send pre-rendered HTML so users can see something before the JavaScript bundle starts loading and adds interactiveness. It doesn't mean there's absolutely no client-side script.

How can I generate a pure static site where all content is generated in html without a reference to a js file?

Why would you want that? That would mean no color mode, no smooth transition, no pre-fetching... You'd be better off with Jekyll.

Happy to accept a PR if the doc is confusing for readers without knowledge of modern SSR approaches. Maybe we can link to some blog posts / other documentation? I don't know many great resources though...

slorber commented 2 years ago

There are 2 kind of static sites:

Both usually ship at least some JavaScript, because some features would be very complex to build without any JS (search for example)

But the 2nd category also "hydrates" the React/Vue/... framework on the existing markup, enabling you to use a modern framework to handle interactions instead of Vanilla JS. Also route transitions when you click on a link are using history.push() instead of regular HTML navigation, which gives a better navigation UX.

The point of SSR is to avoid Js files altogether for content generation, but it looks like docusaurus is using a hybrid model with content in index.html + js file + chunked-js file. If that's so, what exactly is in the chunked-js file–that's not in index.html? How can I generate a pure static site where all content is generated in html without a reference to a js file?

The JS contains React and code to render the page on the client, without having to ask the HTML content for the server.

This hybrid model does not satisfy everyone (you'll find strong opponents to it) but it's what we decided to use a,d this hybrid model is likely to improve over time and becomes more lightweight.

FYI there's an old experimental PR exploring a Docusaurus build without any JS at all, but for now we don't officially support such a feature => https://github.com/facebook/docusaurus/pull/3237


Note @Josh-Cena we do have a JS "server bundle" used during the SSR/server phase, but it's removed during the build process:

  // Remove server.bundle.js because it is not needed.
  if (typeof serverConfig.output?.filename === 'string') {
    const serverBundle = path.join(outDir, serverConfig.output.filename);
    if (await fs.pathExists(serverBundle)) {
      await fs.unlink(serverBundle);
    }
  }

It took me a while to notice it 🤪 Removing it doesn't help for debugging but I guess it was removed for upload size reasons 🤷‍♂️ Maybe we could keep it and output it in .docusaurus instead.

Josh-Cena commented 2 years ago

Yes, I know server.bundle.js but that's more of a build artifact (webpack is a JS bundler, so it has to emit JS after all), not user-facing, so I decided to not mention it and complicate things😅