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

i18n no defaultLocale fallback handling for single-domain-deployment strategy #4723

Open
TomPeirs opened this issue May 4, 2021 · 17 comments
Labels
bug An error in the Docusaurus core causing instability or issues with its execution domain: i18n Related to the i18n system

Comments

@TomPeirs
Copy link

TomPeirs commented May 4, 2021

🐛 Bug Report

There seems to be no fallback handling to the defaultLocale.

When I change with the localeDropdown to French (fr), my baseURL is appended with the locale. And will look like below
https://docusaurus.io/fr/docs/i18n/tutorial
However when I replace the french locale with my default locale (in my case: en) it will return a page not found.
http://localhost:3000/en/docs/intro
How can I make the defaultLocale accessible from the URL as the current 'strategy' is to strip the defaultlocale from the URL.

I think this is an important Bug because when starting to use Docusaurus V2 early we shipped some 'stable' URLs to production, and these URLs need to remain stable, meaning we have the locale always appended after the BaseURL. (also for default english).

What would be the suggestion?
(to me it seems odd I would need to use the multi domain strategy and start configuring CDNs just to get this working)

To Reproduce

  1. Configure the sites locales
    i18n: { defaultLocale: 'en', locales: ['en', 'de'], },
  2. Write your translations (.. create i18n folder, with the locale folder, etc..)
  3. Build the application npm run build using the https://docusaurus.io/docs/i18n/tutorial#single-domain-deployment single domain deployment strategy

Expected behavior

I would expect that the application is accessible with the default locale prefix in the URL.
Even better would be if you do not define the locale it all, that the application falls back to the defaultLocale if the document is available.
e.g. https://docusaurus.io/it/docs/i18n/tutorial should fall back to https://docusaurus.io/docs/i18n/tutorial in case IT (Italian) is not defined as a locale.

Actual Behavior

Currently you see a Page Not Found forward.
image

Your Environment

  • Docusaurus version used: Alpha 75
  • Operating system and version (desktop or mobile): Windows , latest Chrome
@TomPeirs TomPeirs added bug An error in the Docusaurus core causing instability or issues with its execution status: needs triage This issue has not been triaged by maintainers labels May 4, 2021
@slorber
Copy link
Collaborator

slorber commented May 4, 2021

Hi @TomPeirs

This is something I actually plan to add, just wanted to see if someone come from a need for this and could help design the feature :)

In my opinion, it make sense for most users to have the default/en locale to not have a baseurl prefix by default, as most users already have an English Docusaurus sites with existing URLs (not using /en/ baseurl) and by default those URLs should continue working.

So my idea was to allow configuring the baseUrl for each locale independently, but use convenient default for most users.

For your use-case, as you don't want baseUrl: '/' for English, would the following API make sense?

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr'],
    localeConfigs: {
      en: {
        baseUrl: '/en/'
      },
    },
  },
};

Now, /en/ and /fr/ exist, but there's nothing anymore at the root /.
What do you expect Docusaurus to do if the user is browsing that root domain URL?
Showing a 404 does not look like a good idea.

Note Docusaurus can only build static assets, and so, only do client-side redirects using JavaScript.
And it's better to redirect using server-side redirects, but each host platform has a different way to configure this.

to me it seems odd I would need to use the multi domain strategy and start configuring CDNs just to get this working

Somehow, you could already solve your problem by running something like docusaurus build --locale en --out-dir build/en, this is basically what Docusaurus does behind the scene, nothing fancy. Building all locales at once is just "shortcut" to make this more convenient than running one cli command for each locale, but really it is the same in the end.

Even better would be if you do not define the locale it all, that the application falls back to the defaultLocale if the document is available.
e.g. https://docusaurus.io/it/docs/i18n/tutorial should fall back to https://docusaurus.io/docs/i18n/tutorial in case IT (Italian) is not defined as a locale.

Docusaurus can only build a folder of static files. It's not clear to me what exactly is a "fallback" for you and how we should built this technically (ie what should the /build folder look like exactly?). I suspect you mean "redirect", but this is a server-side feature, and is specific to the host solution you are using.

Note: some popular server-side solutions like Github Pages are quite limited: it's not possible to perform a server-side redirect here for example. And if we build something, we definitively want this to work in all Jamstack hosting solutions, including Github Pages, or this would be confusing for many users.

If you have a clear idea of what you want and think it is technically possible, I'd suggest creating a POC by hand-writing some html files and deploying those to Github Pages so that I understand better your suggestion

In my opinion, the role of Docusaurus is only to build a folder of static assets. It is your responsibility to handle the rest, including configuring your host correctly for fallbacks/redirects, adding performant caching headers, rewrite URLs etc... We can only help by documenting this, but it's hard to be exhaustive

@TomPeirs
Copy link
Author

TomPeirs commented May 4, 2021

Hey @slorber ,
Thank you for providing these insights.

Concerning

module.exports = {
 i18n: {
   defaultLocale: 'en',
   locales: ['en', 'fr'],
   localeConfigs: {
     en: {
       baseUrl: '/en/'
     },
   },
 },
};

For my particular use-case not having anything at the root would be fine
we already handle this on proxy-level by forwarding to the /en in case someone browses the root.
it would be great to be able to configure the localeConfigs as you porpose. But I guess your proposal is not available in Alpha-75 right? As I tried to compile localeConfigs as mentioned but this was not working.

This results in the following
Error: These field(s) ["i18n,localeConfigs,en,baseUrl",] are not recognized in docusaurus.config.js. If you still want these fields to be in your configuration, put them in the 'customFields' attribute.

Somehow, you could already solve your problem by running something like docusaurus build --locale en --out-dir build/en, this is basically what Docusaurus does behind the scene, nothing fancy. Building all locales at once is just "shortcut" to make this more convenient than running one cli command for each locale, but really it is the same in the end.

This is also a good idea.
I tried this out and did not get it working right away.
I assume I have to duplicate my docusaurus.config.js file in order to modify the baseUrl to :/en/ or /de/ by passing --config to the CLI because currently I get the following:
image

(I'll try it out this afternoon and update this ticket)

Docusaurus can only build a folder of static files. It's not clear to me what exactly is a "fallback" for you and how we should built this technically (ie what should the /build folder look like exactly?). I suspect you mean "redirect", but this is a server-side feature, and is specific to the host solution you are using.

I agree, you are right.

@slorber
Copy link
Collaborator

slorber commented May 4, 2021

it would be great to be able to configure the localeConfigs as you porpose. But I guess your proposal is not available in Alpha-75 right? As I tried to compile localeConfigs as mentioned but this was not working.

No it is not added yet, but will do that, as I planned to add it anyway

I assume I have to duplicate my docusaurus.config.js file in order to modify the baseUrl to :/en/ or /de/ by passing --config to the CLI because currently I get the following:

Temporarily you can pass a baseurl by using nodejs env variables in your config file:

baseUrl: process.env.BASE_URL

And run this:

BASE_URL='/en/' docusaurus build --locale en --out-dir build/en
BASE_URL='/it/' docusaurus build --locale it --out-dir build/it
BASE_URL='/de/' docusaurus build --locale de --out-dir build/de

When using the --locale option, by default we don't add the baseurl automatically, as it does not make sense for subdomain deployments to be en.myDomain.com/en or fr.myDomain.com/fr

@TomPeirs
Copy link
Author

TomPeirs commented May 4, 2021

Thank you, I had to slightly modify this to work with nodejs env variables.

First I installed cross-env.

  "devDependencies": {
    "cross-env": "^7.0.3"
  }

Then I modified the scripts:
"build_german": "cross-env BASE_URL='/de/' docusaurus build --locale de --out-dir build/de "

Without cross-env I couldn't get it to work. I realized setting nodejs environment variables is windows is different.

Just leaving this here

HOWEVER, the proposed solution actually does not work @slorber
yes I do have /en part of the URL now, but switching languages is broken
The reason I think is because somehow the language switcher appends the locale rather then switching it.
I show it in a video:

2021-05-04_13h20_25

@slorber
Copy link
Collaborator

slorber commented May 4, 2021 via email

@TomPeirs
Copy link
Author

TomPeirs commented May 4, 2021

oke thank you @slorber ,

In that case I will move away for this for a little bit.
Any chance to give me an estimation when you will merge and publish this and will it be in Alpha 76?

@TomPeirs
Copy link
Author

@slorber ,
I'm not so familiar with the core of docsuarus yet so I was affraid to open a PR (because my change would only work for this use case).I wasn't sure how I would properly read and configure parameters from the docusaurus.config.js.

Hence, for my use-case where I deploy to build/en/ and build/de/ and have nothing on root, I swizzled the LocaleDropDownNavbarItem.
I imported useAlternatePageUtils from a local copy.
In the useAlternatePageUtils I then slightly modified the baseUrlocalized constant as well as the getLocalizedBaseUrl method.

 const baseUrlUnlocalized =
    currentLocale === defaultLocale
      ? baseUrl
      : baseUrl.replace(`/${currentLocale}/`, `/${defaultLocale}/`);

  const pathnameSuffix = pathname.replace(baseUrl, '');

  function getLocalizedBaseUrl(locale: string) {
    return locale === defaultLocale
      ? `${baseUrlUnlocalized}`
      : `${baseUrlUnlocalized.replace(`/${defaultLocale}/`,`/${locale}/`)}`;

Like this the localeDropdown is working as expected for me.
I'm sure you have a better technical solution with your API proposal, so I will be happily to test it for you need someone to test it.

@slorber
Copy link
Collaborator

slorber commented May 13, 2021

Thanks

I'll tell you when I have a version to test with these features

Is your site open-source so that I can test on your site directly?

@TomPeirs
Copy link
Author

Thanks

I'll tell you when I have a version to test with these features

Is your site open-source so that I can test on your site directly?

It's not public,
But on Friday I will create a vercel deployment for you with a version where I block out sensitive data.

@TomPeirs
Copy link
Author

@slorber I think this ticket relates heavily to #3285
I think the problems described here will be fixed with the RFC.

Do you agree to close this?

@slorber
Copy link
Collaborator

slorber commented Jun 22, 2021

Not exactly the same, this issue is about i18n locale configuration, not docs version configuration (both should allow to configure the path)

Still in my todo list, which unfortunately is quite long 😅

@xiaosongxiaosong
Copy link

Hi, @slorber, i have create a pr #6731 for support this feature, I'm glad you could point it out for me if there's anything I've missed.

Hi @TomPeirs

This is something I actually plan to add, just wanted to see if someone come from a need for this and could help design the feature :)

In my opinion, it make sense for most users to have the default/en locale to not have a baseurl prefix by default, as most users already have an English Docusaurus sites with existing URLs (not using /en/ baseurl) and by default those URLs should continue working.

So my idea was to allow configuring the baseUrl for each locale independently, but use convenient default for most users.

For your use-case, as you don't want baseUrl: '/' for English, would the following API make sense?

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr'],
    localeConfigs: {
      en: {
        baseUrl: '/en/'
      },
    },
  },
};

Now, /en/ and /fr/ exist, but there's nothing anymore at the root /. What do you expect Docusaurus to do if the user is browsing that root domain URL? Showing a 404 does not look like a good idea.

Note Docusaurus can only build static assets, and so, only do client-side redirects using JavaScript. And it's better to redirect using server-side redirects, but each host platform has a different way to configure this.

to me it seems odd I would need to use the multi domain strategy and start configuring CDNs just to get this working

Somehow, you could already solve your problem by running something like docusaurus build --locale en --out-dir build/en, this is basically what Docusaurus does behind the scene, nothing fancy. Building all locales at once is just "shortcut" to make this more convenient than running one cli command for each locale, but really it is the same in the end.

Even better would be if you do not define the locale it all, that the application falls back to the defaultLocale if the document is available.
e.g. docusaurus.io/it/docs/i18n/tutorial should fall back to docusaurus.io/docs/i18n/tutorial in case IT (Italian) is not defined as a locale.

Docusaurus can only build a folder of static files. It's not clear to me what exactly is a "fallback" for you and how we should built this technically (ie what should the /build folder look like exactly?). I suspect you mean "redirect", but this is a server-side feature, and is specific to the host solution you are using.

Note: some popular server-side solutions like Github Pages are quite limited: it's not possible to perform a server-side redirect here for example. And if we build something, we definitively want this to work in all Jamstack hosting solutions, including Github Pages, or this would be confusing for many users.

If you have a clear idea of what you want and think it is technically possible, I'd suggest creating a POC by hand-writing some html files and deploying those to Github Pages so that I understand better your suggestion

In my opinion, the role of Docusaurus is only to build a folder of static assets. It is your responsibility to handle the rest, including configuring your host correctly for fallbacks/redirects, adding performant caching headers, rewrite URLs etc... We can only help by documenting this, but it's hard to be exhaustive

@Josh-Cena Josh-Cena added the domain: i18n Related to the i18n system label Mar 29, 2022
@ahtremblay
Copy link

ahtremblay commented Jul 30, 2022

I think it is more intuitive to simply make defaultLocale optional. For instance:

module.exports = {
  i18n: {
    locales: ['en', 'fr'],
  },
};

would output en to /en/ and fr to /fr/ (leaving root empty), while:

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr'],
  },
};

would output en to / and fr to /fr/.

@arnaud4d
Copy link

I also have the issue to support external links to docusaurus v1 site: they all include '/en/', and no longer work in v2 :-(. Moreover, translators need to know that they have to add their languages in the urls because they don't see /en/ in them.
I would like to have a simple 'defaultLocaleInUrl' option.

@bclabs-kylian
Copy link

This is so needed imo. Will be waiting for the feature release

@Jwaegebaert
Copy link

Is there an update regarding this issue? I would love to have this feature within docusaurus, or the option to configure a custom baseUrl would also be nice.

@wiktorsikora
Copy link

I am also interested in this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An error in the Docusaurus core causing instability or issues with its execution domain: i18n Related to the i18n system
Projects
None yet
Development

No branches or pull requests

9 participants