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>
This commit is contained in:
parent
b74dbdca9f
commit
2ce2bb1ca8
2 changed files with 25 additions and 4 deletions
|
@ -1,17 +1,26 @@
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
import { trpc } from "@lib/trpc";
|
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
|
* Auto-switches locale client-side to the logged in user's preference
|
||||||
*/
|
*/
|
||||||
const I18nLanguageHandler = (): null => {
|
const I18nLanguageHandler = (): null => {
|
||||||
const { i18n } = useTranslation("common");
|
const { i18n } = useTranslation("common");
|
||||||
const locale = trpc.useQuery(["viewer.i18n"]).data?.locale;
|
const locale = useViewerI18n().data?.locale;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
if (locale && i18n.language && i18n.language !== locale) {
|
if (locale && i18n.language && i18n.language !== locale) {
|
||||||
if (typeof i18n.changeLanguage === "function") i18n.changeLanguage(locale);
|
if (typeof i18n.changeLanguage === "function") i18n.changeLanguage(locale);
|
||||||
}
|
}
|
||||||
|
}, [locale, i18n]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { useLocale } from "@lib/hooks/useLocale";
|
||||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
|
||||||
import { trpc } from "@lib/trpc";
|
import { trpc } from "@lib/trpc";
|
||||||
|
|
||||||
|
import Loader from "@components/Loader";
|
||||||
import { HeadSeo } from "@components/seo/head-seo";
|
import { HeadSeo } from "@components/seo/head-seo";
|
||||||
import Avatar from "@components/ui/Avatar";
|
import Avatar from "@components/ui/Avatar";
|
||||||
import Dropdown, {
|
import Dropdown, {
|
||||||
|
@ -32,6 +33,7 @@ import Dropdown, {
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@components/ui/Dropdown";
|
} from "@components/ui/Dropdown";
|
||||||
|
|
||||||
|
import { useViewerI18n } from "./I18nLanguageHandler";
|
||||||
import Logo from "./Logo";
|
import Logo from "./Logo";
|
||||||
|
|
||||||
function useMeQuery() {
|
function useMeQuery() {
|
||||||
|
@ -160,6 +162,16 @@ export default function Shell(props: {
|
||||||
|
|
||||||
const pageTitle = typeof props.heading === "string" ? props.heading : props.title;
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeadSeo
|
<HeadSeo
|
||||||
|
|
Loading…
Reference in a new issue