# I18N for Mobile app
TODO list for i18n:
- detect language from user
- handle display for static messages
- handle display for dynamic messages
- handle for external packages
- axios request with locale in header
- dayjs display
 
# Supported locales
Define supported locales for your app
export enum SupportedLocale {
  vi = 'vi',
  en = 'en',
}
export const DEFAULT_CONTENT_LOCALE = SupportedLocale.vi
export const FALLBACK_DETECTED_LOCALE = SupportedLocale.en
helpers
export function isLocaleSupported(locale: string): boolean {
  return Object.values(SupportedLocale).includes(locale as SupportedLocale)
}
export function getSupportedLocale(locale: string): SupportedLocale | undefined {
  return isLocaleSupported(locale) ? locale as SupportedLocale : undefined
}
# Language detection
# Static messages
Use lingui (opens new window) library
# External packages
# Dynamic messages
When the backend doesn't provide a translated content for content-language in header. It's nice to have feature => The app will request to an endpoint to translate text then display for UI
# Foundation
service.ts
import instance from '@/services/axios'
export type TranslationPayload = {
  content: string
  sourceLanguage?: string
  targetLanguage: string
}
export async function translateText(payload: TranslationPayload) {
  const res = await instance.post<TranslationResponse>('/translations/text', payload)
  return res.data
}
useGetTranslatedTextQuery.tsx
type Options = {
  originalLocale?: string
}
export function useGetTranslatedTextQuery(content: string, options?: Options) {
  const { 
    isKeepOriginal, 
    originalLocale, 
    targetLocale 
  } = useDetectTranslatable(options)
  const hash = hashTo32Chars(content || '')
  const result = useQuery({
    queryKey: ['translatedText', hash, targetLocale],
    enabled: !!content,
    queryFn: async () => {
      if (isKeepOriginal) {
        return content
      }
      const res = await translateText({
        content,
        targetLanguage: targetLocale,
        sourceLanguage: originalLocale,
      })
      return res.translatedContent
    },
  })
  return {
    ...result,
    isKeepOriginal,
  }
}
export function useDetectTranslatable(options?: Options) {
  const { i18n } = useLingui()
  const targetLocale = i18n.locale as SupportedLocale
  const originalLocale = options?.originalLocale || DEFAULT_CONTENT_LOCALE
  const isKeepOriginal = targetLocale === originalLocale
  return {
    translatable: !isKeepOriginal,
    isKeepOriginal,
    originalLocale,
    targetLocale,
  }
}