Show loading spinner on `<Shell />` until i18n is loaded (#946)

* show loading spinner if i18n isn't loaded

* loading spinner tweaks

Co-authored-by: Alex van Andel <me@alexvanandel.com>
pull/957/head^2
Alex Johansson 2021-10-14 21:10:44 +02:00 committed by GitHub
parent b74dbdca9f
commit 2ce2bb1ca8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 4 deletions

View File

@ -1,17 +1,26 @@
import { useTranslation } from "next-i18next";
import { useEffect } from "react";
import { trpc } from "@lib/trpc";
export function useViewerI18n() {
return trpc.useQuery(["viewer.i18n"], {
staleTime: Infinity,
});
}
/**
* Auto-switches locale client-side to the logged in user's preference
*/
const I18nLanguageHandler = (): null => {
const { i18n } = useTranslation("common");
const locale = trpc.useQuery(["viewer.i18n"]).data?.locale;
const locale = useViewerI18n().data?.locale;
if (locale && i18n.language && i18n.language !== locale) {
if (typeof i18n.changeLanguage === "function") i18n.changeLanguage(locale);
}
useEffect(() => {
if (locale && i18n.language && i18n.language !== locale) {
if (typeof i18n.changeLanguage === "function") i18n.changeLanguage(locale);
}
}, [locale, i18n]);
return null;
};

View File

@ -23,6 +23,7 @@ import { useLocale } from "@lib/hooks/useLocale";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
import { trpc } from "@lib/trpc";
import Loader from "@components/Loader";
import { HeadSeo } from "@components/seo/head-seo";
import Avatar from "@components/ui/Avatar";
import Dropdown, {
@ -32,6 +33,7 @@ import Dropdown, {
DropdownMenuTrigger,
} from "@components/ui/Dropdown";
import { useViewerI18n } from "./I18nLanguageHandler";
import Logo from "./Logo";
function useMeQuery() {
@ -160,6 +162,16 @@ export default function Shell(props: {
const pageTitle = typeof props.heading === "string" ? props.heading : props.title;
const i18n = useViewerI18n();
if (i18n.status === "loading") {
// show spinner whilst i18n is loading to avoid language flicker
return (
<div className="z-50 absolute w-full h-screen bg-gray-50 flex items-center">
<Loader />
</div>
);
}
return (
<>
<HeadSeo