I'm using NextJS 13.4 with app directory (server components) and date-fns. I also use next-intl as internationalisation library.
I want to set correct locale before the app starts rendering on server side and the user's timezone so that whatever is rendered on the server matches the browser rendered content.
// arc/app/[locale]/layout.tsx
export default async function RootLayout({ children, params }: Props) {
const locale = useLocale();
// Show a 404 error if the user requests an unknown locale
if (params.locale !== locale) {
notFound();
}
// set locale for date-fns
try {
const dateFnsLocale = (
(await import(`date-fns/locale`)) as Record<string, Locale>
)[locale];
setDefaultOptions({
locale: dateFnsLocale,
});
} catch (error) {
throw new Error("invalid locale for date-fns", { cause: error });
}
...
return (
<html lang={locale}>
<head />
<body className={classNames(aeonicFontClassName, "text-tixy-1000")}>
{children}
<DateFnsLocaleLoader locale={locale} />
</body>
</html>
);
// DateFnsLocaleLoader
"use client";
import { FC, useEffect } from "react";
import { setDefaultOptions } from "date-fns";
type Props = {
locale: string;
};
export const DateFnsLocaleLoader: FC<Props> = ({ locale }) => {
useEffect(() => {
const load = async () => {
try {
const dateFnsLocale = (
(await import(`date-fns/locale`)) as Record<string, Locale>
)[locale];
setDefaultOptions({
locale: dateFnsLocale,
});
} catch (error) {
throw new Error("invalid locale for date-fns", { cause: error });
}
};
load();
}, [locale]);
return null;
};
The problem is that there is still mismatch between what is rendered on server vs client.