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

Allow configuration of cleanUrls option for serve command #7991

Open
2 tasks done
SlicedSilver opened this issue Aug 23, 2022 · 14 comments
Open
2 tasks done

Allow configuration of cleanUrls option for serve command #7991

SlicedSilver opened this issue Aug 23, 2022 · 14 comments
Labels
apprentice Issues that are good candidates to be handled by a Docusaurus apprentice / trainee feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future. good first issue If you are just getting started with Docusaurus, this issue should be a good place to begin.

Comments

@SlicedSilver
Copy link

Have you read the Contributing Guidelines on issues?

Description

Allow configuration of the cleanUrls option passed to serve-handler package when running docusaurus serve.

Currently, Docusaurus sets the cleanUrls option for the serve-hander package to true and it isn't configurable by the user.

serveHandler(req, res, {
cleanUrls: true,
public: dir,
trailingSlash,
directoryListing: false,
});
});

Proposing that this should be a user-configurable option.

Has this been requested on Canny?

No response

Motivation

By default, at least a few major hosting providers (GH Pages, Netlify, Vercel) don't enable this 'feature'. Having this as an option would allow for more accurate testing of the documentation website before deploying.

A Use Case:
It is possible to embed an iframe into a documentation page which serves as a self-contained example. The example file can be loaded using the file-loader web pack loader.

<iframe
     src={require('!!file-loader!./assets/example.html').default}
 ></iframe>
 <a href={require('!!file-loader!./assets/example.html').default} target="\_blank">
     View example in a new window
 </a>

This works correctly when using docusaurus start and when deploying the build onto a hosting provider. However, when running docusaurus serve, any url ending with .html is rewritten without the extension and a 404 error occurs.

API design

ServeCLIOptions could include cleanUrls?: boolean; which defaults to true.

export type ServeCLIOptions = HostPortOptions &
Pick<LoadContextOptions, 'config'> & {
dir?: string;
build?: boolean;
open?: boolean;
};

When the user wishes to disable cleanUrls then they would call the serve command as follows:
docusaurus serve --no-clean-urls

A similar options could be added to the configuration file (https://github.com/facebook/docusaurus/blob/bd9f29a4698963d3b139f7419877a300640b09ff/packages/docusaurus-types/src/config.d.ts).

Have you tried building it?

I've tried the changes locally and passing cleanUrls: false to serve-handler works as expected.

Self-service

  • I'd be willing to contribute this feature to Docusaurus myself.
@SlicedSilver SlicedSilver 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 Aug 23, 2022
@Josh-Cena Josh-Cena removed the status: needs triage This issue has not been triaged by maintainers label Aug 23, 2022
@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Aug 23, 2022

Maybe we could let you pass a JSON string through a single command line option, which we directly merge into the default options? I don't have good API designs so far.

@SlicedSilver
Copy link
Author

If the goal is to make the entire serve-handler options object customisable from the command line then it may be a bit cumbersome to achieve that with a JSON string.

For example:
docusaurus serve --serve-options='{"cleanUrls":false, "renderSingle": false, "directoryListing": ["/assets/**", "/!assets/private"]}'

Especially if trying to customise the headers option (https://github.com/vercel/serve-handler#headers-array) which can be rather lengthy.

Alternatives

  • Might be better to allow the loading of a JSON file from disk, much like the config cli option for the other commands:
    docusaurus serve --serve-config ./serve-config.json

  • or include these options within the main docusaurus.config.js file.

I'm happy to work on a PR if there is a decision on the preferred approach for the API.

@Josh-Cena
Copy link
Collaborator

Yeah, I think a serveOptions in the config file makes more sense, just like we have several options for deploy as well. I'm not totally decided yet.

@slorber
Copy link
Collaborator

slorber commented Aug 24, 2022

To me this CLI command is just a convenience for non-technical users to easily test their Docusaurus site. If you don't like it or need something more advanced you can provide your own server.

What prevents you from running npx serve and have a serve.json config file for example? Docusaurus doesn't do much more than that.

Not against adding a --no-clean-urls options or something, but anything more advanced feels out of the scope of our CLI. I don't really want to provide a json string as a CLI arg respecting a third-party lib schema 🤷‍♂️

@SlicedSilver
Copy link
Author

Agreed, that makes sense. It would be out of scope to add all those options from a third-party lib.

I can use npx serve or create my own script to achieve what I'm looking for.

Would it make sense to change the default from true to false which will match the behaviour of the start command and the majority of hosting providers which I've checked?

Alternatively, could the script check for an environmental variable CLEAN_URLS=false ? No need to change the API then.

Happy that this issue can be closed if deemed out of scope.👍

@slorber
Copy link
Collaborator

slorber commented Aug 24, 2022

Would it make sense to change the default from true to false which will match the behaviour of the start command and the majority of hosting providers which I've checked?

As far as I know, Netlify has pretty URLs by default, although it tells you it doesn't (asset optimization disabled by default, but still pretty URLs enabled)

I've documented this here:

This is confusing but it's what I see in practice. Also Netlify pretty URLs is not exactly the same as Vercel cleanUrls. All hosting providers have differences. Netlify pretty URLs will remove a trailing slash but won't redirect if you use HTML file extensions for example.

Here's a Netlify deployment with std settings: https://630608910ce7dd006e877866--docusaurus-with-netlify-defaults.netlify.app

Also, have you tried deploying a Docusaurus site without pretty URLs? Would our frontend SPA router work with URLs ending with xyz/index.html or xyz.html for example?

If you want to change this setting, I'd rather ask you to do the homework and show me a Docusaurus site hosted on multiple platforms with cleanUrls: false and trailingSlash true/false combinations.


Alternatively, could the script check for an environmental variable CLEAN_URLS=false ? No need to change the API then.

That's not particularly better to me. If this is a useful option we should expose it properly. But is it a useful option in the first place?


I'm still not sure to understand your iframe use-case. What is the easy actionable step-by-step guide for reproducing this problem?


Happy that this issue can be closed if deemed out of scope.👍

Feel free to close if you don't care much about getting this solved.

@Josh-Cena
Copy link
Collaborator

I don't think it's quite out of scope. If some hosting providers have this behavior and others don't, we ought to provide an option to make the local testing env mirror the deployment env.

@slorber
Copy link
Collaborator

slorber commented Aug 24, 2022

I don't think it's quite out of scope. If some hosting providers have this behavior and others don't, we ought to provide an option to make the local testing env mirror the deployment env.

I'm ok to add an option for this

But if some hosting provider decides to do weird fancy things, I wouldn't make it part of docusaurus serve scope. For example GitHub Pages without a .nojekyll file would have a quite surprising static serving behavior, and we definitively don't want to add support for that

@Josh-Cena
Copy link
Collaborator

Aye, yes, that makes sense

@slorber slorber added the good first issue If you are just getting started with Docusaurus, this issue should be a good place to begin. label Aug 24, 2022
@SlicedSilver
Copy link
Author

I've created a stackbiltz example where the site functions correctly on npm run start, but not when running npm run serve.

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

It appears that this behaviour only occurs when baseUrl is changed from the default of '/'.


The example:

  • Click 'View Example' on the landing page of the documentation site.
  • When run with start then you will see a light blue iframe
  • When run with serve then you will see the landing page within the iframe.

@rashidmya
Copy link
Contributor

can I try doing this?

@slorber
Copy link
Collaborator

slorber commented Aug 26, 2022

@SlicedSilver is it possible that it's related to our serve.ts code having some "extras"?

CleanShot 2022-08-26 at 17 46 16@2x


@rashidmya yes I'm ok to add a --no-clean-urls option.
But let's wait first to be sure that it's needed, cf my comment above. You can help investigate the problem

@SlicedSilver
Copy link
Author

Within serve.ts, if I set cleanUrls: false then it works as expected.

However, if I remove the http 302 'found' redirect logic then it works as well (without changing the cleanUrls):

    // if (!req.url?.startsWith(baseUrl)) {
    //   res.writeHead(302, {
    //    Location: baseUrl,
    //  });
    //  res.end();
    //  return;
    // }

Changing the Location value within the redirect also works (without changing the cleanUrls):

Location: baseUrl + req.url.slice(1),

If changing the location value is the best option then obviously it might make sense to check if baseUrl ends with / and url starts with / if that is quietly allowed within the configuration.

const slicePoint = (baseUrl.endsWith('/') && req.url.startsWith('/')) ? 1 : 0;
// ...
Location: baseUrl + req.url.slice(slicePoint),

@slorber Hope this helps, and thanks for your assistance.

@slorber slorber added the apprentice Issues that are good candidates to be handled by a Docusaurus apprentice / trainee label Sep 25, 2023
@MattiasBuelens
Copy link

MattiasBuelens commented Feb 19, 2024

This tripped us up too.

We have some .html files inside /static/examples/, and we put them in an <iframe> inside our docs:

<iframe src={useBaseUrl("/examples/demo.html")}></iframe>

This works fine with docusaurus start, but breaks with docusaurus build && docusaurus serve. We found that changing baseUrl from /docs/ to / fixes the issue, but unfortunately we can't do that for this website.

Reproduction case: https://github.com/MattiasBuelens/docusaurus-serve-html-asset-issue

What prevents you from running npx serve and have a serve.json config file for example? Docusaurus doesn't do much more than that.

That seems like a reasonable workaround for us. I'd prefer if docusaurus serve would have better support for baseUrl, but for now we'll use a custom serve script instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apprentice Issues that are good candidates to be handled by a Docusaurus apprentice / trainee feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future. good first issue If you are just getting started with Docusaurus, this issue should be a good place to begin.
Projects
None yet
Development

No branches or pull requests

5 participants