kopia lustrzana https://github.com/elk-zone/elk
				
				
				
			fix: i18n SSR
							rodzic
							
								
									d09b4deb52
								
							
						
					
					
						commit
						970b6538e2
					
				
							
								
								
									
										5
									
								
								app.vue
								
								
								
								
							
							
						
						
									
										5
									
								
								app.vue
								
								
								
								
							|  | @ -1,13 +1,12 @@ | |||
| <script setup lang="ts"> | ||||
| setupI18n() | ||||
| setupPageHeader() | ||||
| setupEmojis() | ||||
| provideGlobalCommands() | ||||
| 
 | ||||
| await setupI18n() | ||||
| 
 | ||||
| // We want to trigger rerendering the page when account changes | ||||
| const key = computed(() => `${currentUser.value?.server ?? currentServer.value}:${currentUser.value?.account.id || ''}`) | ||||
| 
 | ||||
| const { params } = useRoute() | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { pwaInfo } from 'virtual:pwa-info' | ||||
| import type { Link } from '@unhead/schema' | ||||
| import type { Directions } from 'vue-i18n-routing' | ||||
| import { APP_NAME, STORAGE_KEY_LANG } from '~/constants' | ||||
| import { APP_NAME, COOKIE_MAX_AGE, STORAGE_KEY_LANG } from '~/constants' | ||||
| import type { LocaleObject } from '#i18n' | ||||
| 
 | ||||
| export function setupPageHeader() { | ||||
|  | @ -49,27 +49,26 @@ export function setupPageHeader() { | |||
| 
 | ||||
| export async function setupI18n() { | ||||
|   const { locale, setLocale, locales } = useI18n() | ||||
|   const nuxtApp = useNuxtApp() | ||||
|   nuxtApp.hook('app:suspense:resolve', async () => { | ||||
|     const isFirstVisit = process.server ? false : !window.localStorage.getItem(STORAGE_KEY_LANG) | ||||
|     const localeStorage = process.server ? ref('en-US') : useLocalStorage(STORAGE_KEY_LANG, locale.value) | ||||
|   const cookieLocale = useCookie(STORAGE_KEY_LANG, { maxAge: COOKIE_MAX_AGE }) | ||||
|   const isFirstVisit = cookieLocale.value == null | ||||
| 
 | ||||
|     if (isFirstVisit) { | ||||
|       const userLang = (navigator.language || 'en-US').toLowerCase() | ||||
|       // cause vue-i18n not explicit export LocaleObject type
 | ||||
|       const supportLocales = unref(locales) as { code: string }[] | ||||
|       const lang = supportLocales.find(locale => userLang.startsWith(locale.code.toLowerCase()))?.code | ||||
|   if (process.client && isFirstVisit) { | ||||
|     const userLang = (navigator.language || 'en-US').toLowerCase() | ||||
|     // cause vue-i18n not explicit export LocaleObject type
 | ||||
|     const supportLocales = unref(locales) as { code: string }[] | ||||
|     const lang = supportLocales.find(locale => userLang.startsWith(locale.code.toLowerCase()))?.code | ||||
|       || supportLocales.find(locale => userLang.startsWith(locale.code.split('-')[0]))?.code | ||||
|       localeStorage.value = lang || 'en-US' | ||||
|     } | ||||
|     cookieLocale.value = lang || 'en-US' | ||||
|   } | ||||
| 
 | ||||
|     if (localeStorage.value !== locale.value) | ||||
|       await setLocale(localeStorage.value) | ||||
|   if (cookieLocale.value && cookieLocale.value !== locale.value) | ||||
|     await setLocale(cookieLocale.value) | ||||
| 
 | ||||
|   if (process.client) { | ||||
|     watchEffect(() => { | ||||
|       localeStorage.value = locale.value | ||||
|       cookieLocale.value = locale.value | ||||
|     }) | ||||
|   }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export async function setupEmojis() { | ||||
|  |  | |||
|  | @ -19,7 +19,10 @@ export const STORAGE_KEY_HIDE_EXPLORE_TAGS_TIPS = 'elk-hide-explore-tags-tips' | |||
| export const STORAGE_KEY_NOTIFICATION = 'elk-notification' | ||||
| export const STORAGE_KEY_NOTIFICATION_POLICY = 'elk-notification-policy' | ||||
| 
 | ||||
| export const COOKIE_MAX_AGE = 10 * 365 * 24 * 60 * 60 * 1000 | ||||
| 
 | ||||
| export const COOKIE_KEY_FONT_SIZE = 'elk-font-size' | ||||
| export const COOKIE_KEY_COLOR_MODE = 'elk-color-mode' | ||||
| export const COOKIE_KEY_LOCALE = 'elk-locale' | ||||
| 
 | ||||
| export const HANDLED_MASTO_URLS = /^(https?:\/\/)?([\w\d-]+\.)+\w+\/(@[@\w\d-\.]+)(\/objects)?(\/\d+)?$/ | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import type { ColorMode } from '~/types' | ||||
| import { InjectionKeyColorMode } from '~/constants/symbols' | ||||
| import { COOKIE_KEY_COLOR_MODE } from '~/constants' | ||||
| import { COOKIE_KEY_COLOR_MODE, COOKIE_MAX_AGE } from '~/constants' | ||||
| 
 | ||||
| export default defineNuxtPlugin((nuxt) => { | ||||
|   const cookieColorMode = useCookie<ColorMode | null>(COOKIE_KEY_COLOR_MODE, { default: () => null }) | ||||
|   const cookieColorMode = useCookie<ColorMode | null>(COOKIE_KEY_COLOR_MODE, { maxAge: COOKIE_MAX_AGE }) | ||||
| 
 | ||||
|   const preferColorMode = process.server ? computed(() => 'light') : usePreferredColorScheme() | ||||
|   const colorMode = computed<ColorMode>({ | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| import type { FontSize } from '~/types' | ||||
| import { InjectionKeyFontSize } from '~/constants/symbols' | ||||
| import { COOKIE_KEY_FONT_SIZE } from '~/constants' | ||||
| import { COOKIE_KEY_FONT_SIZE, COOKIE_MAX_AGE } from '~/constants' | ||||
| import { fontSizeMap } from '~/constants/options' | ||||
| 
 | ||||
| export default defineNuxtPlugin((nuxt) => { | ||||
|   const DEFAULT = 'md' | ||||
|   const cookieFontSize = useCookie<FontSize>(COOKIE_KEY_FONT_SIZE, { default: () => DEFAULT }) | ||||
|   const cookieFontSize = useCookie<FontSize>(COOKIE_KEY_FONT_SIZE, { default: () => DEFAULT, maxAge: COOKIE_MAX_AGE }) | ||||
|   nuxt.vueApp.provide(InjectionKeyFontSize, cookieFontSize) | ||||
| 
 | ||||
|   if (!process.server) { | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Anthony Fu
						Anthony Fu