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

Setting the locale in the server context (SSR) does not work in production build #44

Open
PatrickBauer opened this issue Jul 31, 2024 · 15 comments

Comments

@PatrickBauer
Copy link

PatrickBauer commented Jul 31, 2024

We have a very simple code that works perfectly on client side, but fails on the server side on a production build.
This does not happen when using the dev server though.

Code

export default defineNuxtRouteMiddleware(() => {
  const { locale } = useNuxtApp().$i18n;
  const dayjs = useDayjs();

  if (locale.value !== dayjs.locale()) {
    console.log("Setting dayjs locale to", locale.value);
    dayjs.locale(locale.value);
    console.log("Dayjs locale is now set to", dayjs.locale());
  }
});

Output

Setting dayjs locale to de
Dayjs locale is now set to en

Here I'd expect the server to put out "de" twice, but setting the locale simply does nothing.

Config

  locales: i18nConfig.locales,
  plugins: ["localeData", "localizedFormat", "utc", "customParseFormat"],
  defaultLocale: 'en',
@tcampbPPU
Copy link
Member

does the console say anything about hydration miss match issues? also i wouldn't full trust the dev server without giving it a build first 😅

@PatrickBauer
Copy link
Author

PatrickBauer commented Jul 31, 2024

Like I said it's not happening in the dev server but only in the production build. I can see the backend content being rendered in the page source in the English locale, but being overridden on the client once hydration happens.

But client side and hydration are not important here, I can't get the server to render any non-en locale dates when using the built prod server version. I can't even get it so switch to a different locale, as reading after setting the locale immediately returns the default locale again. In the dev server and client side, this works without any issues 🙏

@The73756
Copy link

The73756 commented Aug 6, 2024

Same issue

@batjeciftci
Copy link

batjeciftci commented Aug 18, 2024

Same issue, different locales between SSR and Client, hydration issue.

@bell-101
Copy link

Same issue

@cfab
Copy link

cfab commented Oct 14, 2024

Any news on this ? Thank you.

@ReindDooyeweerd
Copy link

Seems to be an issue i'm having also on a side project i'm building, https://huishistorie.nl/amersfoort/3822cg/bombardonstraat/132

As soon as i change stuff like this:

{{ $dayjs(homeDataStore.homeData.energy.expiry_date).format("D MMMM YYYY") }}

To:

{{ homeDataStore.homeData.energy.expiry_date }}

From the template my hydration error on the frontend disappears. Haven't seen it in dev builds as mentioned above by @PatrickBauer

@Trash0101
Copy link

Same issue, but in dev mode too. In ssr dayjs defaults to "en" locale even when explicitly set to another.

@simonmaass
Copy link

I can confirm this issue... very annoying and resulting in "Hydration completed but contains mismatches." errors in console in production builds!

@kofeinstyle
Copy link

kofeinstyle commented Nov 23, 2024

Same issue with defaultTimezone. SSR does not use it (maybe and client ). In ssr dayjs using server timezone and after that I see hydration error because I have another timezone

@gokhantaskan
Copy link

gokhantaskan commented Nov 29, 2024

(Updated) I created a plugin.

export default defineNuxtPlugin({
  name: "locale",
  hooks: {
    "app:created": () => {
      const nuxtApp = useNuxtApp();
      const dayjs = nuxtApp.$dayjs;
      const i18n = nuxtApp.$i18n;
      dayjs.locale(i18n.locale.value);
    },
    "i18n:beforeLocaleSwitch": ({ newLocale }) => {
      const nuxtApp = useNuxtApp();
      const dayjs = nuxtApp.$dayjs;
      dayjs.locale(newLocale);
    },
  },
});

Both the server and the client are configured correctly. However, it didn't work with the "i18n:localeSwitched" hook, which might be an issue with the dayjs plugin.

"@nuxtjs/i18n": "^9.1.0",
"dayjs": "^1.11.13",
"dayjs-nuxt": "^2.1.11"

@dpetrouk
Copy link

dpetrouk commented Dec 5, 2024

Got here because I have the same issue.

"dayjs-nuxt": "^2.1.11",

@Trash0101
Copy link

Trash0101 commented Dec 5, 2024

The core issue is that all locales except "en" do not exist when called during SSR, despite being set in the configuration files. My temporary solution involves extracting locale configurations directly from the Day.js source, storing them in separate files within my application, and passing them as arguments to dayjs.locale(). Once the page finishes loading, I swap these temporary locales with the actual ones.

This approach does have potential discrepancies if locales are updated or dayjs configurations change significantly. However, as long as you stick to the same Day.js version, this method works reliably. To avoid conflicts with standard locales, name the temporary locales distinctly, such as frSSR instead of just fr.

@dpetrouk
Copy link

dpetrouk commented Dec 5, 2024

To make locale config available dayjs requires import with side-effects (like import 'dayjs/locale/ru.js'). After that dayjs.Ls.ru with locale config becomes available.

It seems that imports without binding to a variable are lost on nuxt build.

Current workaround for my case:
./composables/dayjs.ts:

import dayjs from 'dayjs'
import locale from 'dayjs/locale/ru'
import relativeTime from 'dayjs/plugin/relativeTime'

dayjs.extend(relativeTime)
dayjs.locale('ru', locale)

export function useDayjs()
{   
    return dayjs
}

To use:

const dayjs = useDayjs()

@Szlavicsek
Copy link

Thank you @Trash0101 and @dpetrouk for sharing your solutions.

For anyone having an internationalized site, I'd suggest creating an i18n plugin and adding the workaround like this:

import locale_hu from 'dayjs/locale/hu';
import locale_en from 'dayjs/locale/en';

export default defineNuxtPlugin((nuxtApp) => {
    const localeFiles = {
        hu: locale_hu,
        en: locale_en,
    };

    nuxtApp.hook('app:created', () => {
        nuxtApp.$dayjs.locale(nuxtApp.$i18n.locale.value, localeFiles[nuxtApp.$i18n.locale.value]);
    });

    nuxtApp.hook('i18n:beforeLocaleSwitch', ({ oldLocale, newLocale, initialSetup, context }) => {});

    nuxtApp.hook('i18n:localeSwitched', ({ oldLocale, newLocale }) => {
        nuxtApp.$dayjs.locale(newLocale);
        // change locale of other dependencies
    });
});

"dayjs-nuxt": "^2.1.11",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests