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
	
	 Alex Johansson
						Alex Johansson