快速開始
Expo
本頁示範 Intor 在 Expo 專案中的最小整合流程。
安裝
本指南假設你已經建立好 Expo 專案。
專案建立方式請參考官方文件:Expo
為了啟用語系持久化功能,請安裝以下套件:
expo-localization@react-native-async-storage/async-storage
npx expo install expo-localization @react-native-async-storage/async-storage
安裝 Intor:
npm install intoryarn add intorpnpm add intorbun add intor
專案結構
index.jsonUindex.jsonU_layout.tsxMindex.tsxMintor-config.tsUintor-client-provider.tsxU
整合步驟
♯1 翻譯內容
在專案中建立 messages 資料夾,並依語系建立子資料夾,每個語系提供一個 index.json。
index.jsonUindex.jsonU
{ "hello": "Hello, {name}", "rich": "A <tag>text</tag>." }
{ "hello": "Bonjour, {name}", "rich": "Un <tag>texte</tag>." }
♯2 設定檔
在 src/ 下建立 i18n/ 資料夾,並於其中建立 intor-config.ts。
本範例採用最基本的翻譯內容載入方式,直接將 messages 定義於設定檔中。
詳見:載入翻譯內容
intor-config.tsU
import { defineIntorConfig } from "intor"; import EN from "../../messages/en/index.json"; import FR from "../../messages/fr/index.json"; export const intorConfig = defineIntorConfig({ defaultLocale: "en", supportedLocales: ["en", "fr"], messages: { en: EN, fr: FR, }, });
♯3 初始化
在 i18n/ 資料夾中建立 intor-client-provider.tsx。
intor-client-provider.tsxU
import AsyncStorage from "@react-native-async-storage/async-storage"; import { getLocales } from "expo-localization"; import { matchLocale } from "intor"; import { IntorProvider } from "intor/react"; import { useEffect, useState, type ReactNode } from "react"; import { intorConfig } from "./intor-config"; const STORAGE_KEY = "locale"; function resolveLocale(candidate?: string): string { const matched = matchLocale(candidate, intorConfig.supportedLocales); return matched ?? intorConfig.defaultLocale; } function getInitialLocale(): string { return resolveLocale(getLocales()[0]?.languageTag); } export function IntorClientProvider({ children }: { children: ReactNode }) { const [locale, setLocale] = useState(getInitialLocale); useEffect(() => { (async () => { const stored = await AsyncStorage.getItem(STORAGE_KEY); if (stored) setLocale(resolveLocale(stored)); })(); }, []); return ( <IntorProvider value={{ config: intorConfig, locale, onLocaleChange: async (locale) => { await AsyncStorage.setItem(STORAGE_KEY, locale); }, }} > {children} </IntorProvider> ); }
接著,在 _layout.tsx 中使用這個 provider 包裹整個應用程式。
_layout.tsxM
// ... import { IntorClientProvider } from "../i18n/intor-client-provider"; export default function TabLayout() { const colorScheme = useColorScheme(); return ( <IntorClientProvider> <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}> <AnimatedSplashOverlay /> <AppTabs /> </ThemeProvider> </IntorClientProvider> ); }
使用範例
透過 useTranslator 取得翻譯相關能力:
t:取得對應文字tRich:渲染包含語意 tag 的結構化翻譯內容
index.tsxM
import { useTranslator } from "intor/react"; import { Button, Text, View } from "react-native"; export default function HomeScreen() { const { t, tRich, setLocale } = useTranslator(); return ( <View style={{ margin: 80, gap: 20, backgroundColor: "white" }}> <Text>{t("hello", { name: "Intor" })}</Text> <Text> {tRich("rich", { tag: (children) => ( <Text style={{ fontWeight: "bold" }}>{children}</Text> ), })} </Text> <Button title="English" onPress={() => setLocale("en")} /> <Button title="French" onPress={() => setLocale("fr")} /> </View> ); }