์ด ํ์ด์ง์๋ ์ ํ๋ฆฌ์ผ์ด์ ํ ํ๋ฆฟ์ด ์ ๊ณต๋ฉ๋๋ค.
์ด ํ์ด์ง๋ ํ ํ๋ฆฟ์ ๋ผ์ด๋ธ ๋ฐ๋ชจ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.
์ด ํ์ด์ง์ ์ํ๋ AI ์ด์์คํดํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์๋ฅผ ์์ฝํฉ๋๋ค
๋ฒ์ ๊ธฐ๋ก
- "Solid useIntlayer API ์ฌ์ฉ๋ฒ์ ์ง์ ์์ฑ ์ก์ธ์ค๋ก ์
๋ฐ์ดํธ"v8.9.02026. 5. 4.
- "init ๋ช
๋ น์ด ์ถ๊ฐ"v7.5.92025. 12. 30.
- "๋ ์ด์์ ์
๋ฐ์ดํธ ๋ฐ 404 ์ฒ๋ฆฌ"v7.5.62025. 12. 27.
- "๋ฌธ์ ์
๋ฐ์ดํธ"v6.1.52025. 10. 3.
- "React Router v7 ์ง์ ์ถ๊ฐ"v5.8.22025. 9. 4.
์ด ํ์ด์ง์ ์ฝํ ์ธ ๋ AI๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญ๋์์ต๋๋ค.
์์ด ์๋ณธ ๋ด์ฉ์ ์ต์ ๋ฒ์ ์ ๋ณด๊ธฐ์ด ๋ฌธ์๋ฅผ ๊ฐ์ ํ ์์ด๋์ด๊ฐ ์์ผ์๋ฉด GitHub์ ํ ๋ฆฌํ์คํธ๋ฅผ ์ ์ถํ์ฌ ์์ ๋กญ๊ฒ ๊ธฐ์ฌํด ์ฃผ์ธ์.
๋ฌธ์์ ๋ํ GitHub ๋งํฌ๋ฌธ์์ Markdown์ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
Intlayer๋ก React Router v7 ๋ฒ์ญํ๊ธฐ | ๊ตญ์ ํ(i18n)
์ด ๊ฐ์ด๋๋ React Router v7 ํ๋ก์ ํธ์์ ๋ก์ผ์ผ ์ธ์ ๋ผ์ฐํ , TypeScript ์ง์ ๋ฐ ์ต์ ๊ฐ๋ฐ ๋ฐฉ์์ ํ์ฉํ์ฌ Intlayer๋ฅผ ํตํฉํด ์ํํ ๊ตญ์ ํ(i18n)๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์ด ๊ฐ์ด๋๋ ํ๋ก ํธ์๋ ๋ผ์ฐํ ์ ์ค์ ์ ๋ก๋๋ค. fs-routes ๋ผ์ฐํ ์ ๊ฒฝ์ฐ Intlayer with React Router v7 File-System Routes ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ชฉ์ฐจ
๋์๋ณด๋ค Intlayer๋ฅผ ์ ํํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
'react-i18next' ๋๋ 'i18next'์ ๊ฐ์ ์ฃผ์ ์๋ฃจ์ ๊ณผ ๋น๊ตํ ๋ Intlayer๋ ๋ค์๊ณผ ๊ฐ์ ํตํฉ ์ต์ ํ๊ฐ ์ ๊ณต๋๋ ์๋ฃจ์ ์ ๋๋ค.
Intlayer๋ ๋ก์ผ์ผ ์ธ์ ๋ผ์ฐํ , ๋ก์ผ์ผ ๊ฐ์ง๋ฅผ ์ํ ๋ฏธ๋ค์จ์ด ๋ฐ ๊ตญ์ ํ ํ์ฅ(i18n)์ ํ์ํ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ React Router์ ์๋ฒฝํ๊ฒ ์๋ํ๋๋ก ์ต์ ํ๋์์ต๋๋ค.
๋์ฉ๋ JSON ํ์ผ์ ํ์ด์ง์ ๋ก๋ํ๋ ๋์ ํ์ํ ์ฝํ ์ธ ๋ง ๋ก๋ํ์ธ์. Intlayer๋ ๋ฒ๋ค ๋ฐ ํ์ด์ง ํฌ๊ธฐ๋ฅผ ์ต๋ 50% ์ค์ด๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ฝํ ์ธ ์ ๋ฒ์๋ฅผ ์ง์ ํ๋ฉด ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ฉ์ดํด์ง๋๋ค. ์ ์ฒด ์ฝํ ์ธ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๊ฒํ ํด์ผ ํ๋ ์ ์ ์ ๋ถ๋ด ์์ด ๋จ์ผ ๊ธฐ๋ฅ ํด๋๋ฅผ ๋ณต์ ํ๊ฑฐ๋ ์ญ์ ํ ์ ์์ต๋๋ค. ๋ํ Intlayer๋ ์์ ํ ์ ํ๋์ด ์ฝํ ์ธ ์ ์ ํ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
์ฝํ ์ธ ๋ฅผ ๊ฐ์ ์์น์ ๋ฐฐ์นํ๋ฉด LLM(๋ํ ์ธ์ด ๋ชจ๋ธ)์ ํ์ํ ์ปจํ ์คํธ๊ฐ ์ค์ด๋ญ๋๋ค. Intlayer์๋ ๋๋ฝ๋ ๋ฒ์ญ์ ํ ์คํธํ๊ธฐ ์ํ CLI, LSP, MCP ๋ฐ agent skills, AI ์์ด์ ํธ๋ฅผ ์ํ ๊ฐ๋ฐ์ ๊ฒฝํ(DX)์ ๋์ฑ ์ํํ๊ฒ ๋ง๋ญ๋๋ค.
AI ๊ณต๊ธ์์ ๋น์ฉ์ผ๋ก ์ ํํ LLM์ ์ฌ์ฉํ์ฌ CI/CD ํ์ดํ๋ผ์ธ์ ๋ฒ์ญํ๋ ค๋ฉด ์๋ํ๋ฅผ ์ฌ์ฉํ์ธ์. Intlayer๋ ๋ํ ์ฝํ ์ธ ์ถ์ถ์ ์๋ํํ๋ ์ปดํ์ผ๋ฌ์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฒ์ญ์ ๋๋ ์น ํ๋ซํผ์ ์ ๊ณตํฉ๋๋ค.
๋๊ท๋ชจ JSON ํ์ผ์ ๊ตฌ์ฑ ์์์ ์ฐ๊ฒฐํ๋ฉด ์ฑ๋ฅ ๋ฐ ๋ฐ์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. Intlayer๋ ๋น๋ ์ ์ฝํ ์ธ ๋ก๋ฉ์ ์ต์ ํํฉ๋๋ค.
Intlayer๋ ๋จ์ํ i18n ์๋ฃจ์ ๊ทธ ์ด์์ผ๋ก ๊ด๋ฆฌ์ ๋์์ด ๋๋ ์์ฒด ํธ์คํ ๋น์ฃผ์ผ ํธ์ง๊ธฐ ๋ฐ ์ ์ฒด CMS๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ค๊ตญ์ด ์ฝํ ์ธ ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ ๊ณตํ์ฌ ๋ฒ์ญ๊ฐ, ์นดํผ๋ผ์ดํฐ, ๊ธฐํ ํ์๊ณผ ์ํํ๊ฒ ํ์ ํ ์ ์์ต๋๋ค. ์ฝํ ์ธ ๋ ๋ก์ปฌ ๋ฐ/๋๋ ์๊ฒฉ์ผ๋ก ์ ์ฅ๋ ์ ์์ต๋๋ค.
React Router v7 ์ ํ๋ฆฌ์ผ์ด์ ์์ Intlayer ์ค์ ๋จ๊ณ๋ณ ๊ฐ์ด๋
See the Config-Based Routing Template or File-System Routes Template on GitHub.
์์กด์ฑ ์ค์น
์ ํธํ๋ ํจํค์ง ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํ์ธ์:
bash์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
--interactiveํ๋๊ทธ๋ ์ ํ ์ฌํญ์ ๋๋ค. AI ์์ด์ ํธ์ธ ๊ฒฝ์ฐintlayer-cli init๋ฅผ ์ฌ์ฉํ์ธ์.์ด ๋ช ๋ น์ ํ๊ฒฝ์ ๊ฐ์งํ๊ณ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค. ์๋ฅผ ๋ค์ด:
bash์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
intlayer
intlayer
๊ตฌ์ฑ ๊ด๋ฆฌ, ๋ฒ์ญ, ์ฝํ ์ธ ์ ์ธ, ํธ๋์คํ์ผ๋ง ๋ฐ CLI ๋ช ๋ น์ด๋ฅผ ์ํ ๊ตญ์ ํ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ ํต์ฌ ํจํค์ง์ ๋๋ค.react-intlayer
Intlayer๋ฅผ React ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ํตํฉํ๋ ํจํค์ง๋ก, React ๊ตญ์ ํ๋ฅผ ์ํ ์ปจํ ์คํธ ์ ๊ณต์์ ํ ์ ์ ๊ณตํฉ๋๋ค.vite-intlayer
Intlayer๋ฅผ Vite ๋ฒ๋ค๋ฌ์ ํตํฉํ๊ธฐ ์ํ Vite ํ๋ฌ๊ทธ์ธ๊ณผ, ์ฌ์ฉ์์ ์ ํธ ๋ก์ผ์ผ ๊ฐ์ง, ์ฟ ํค ๊ด๋ฆฌ, URL ๋ฆฌ๋๋ ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฏธ๋ค์จ์ด๋ฅผ ํฌํจํฉ๋๋ค.
ํ๋ก์ ํธ ๊ตฌ์ฑ
์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ์ด๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ํ ์ค์ ํ์ผ์ ๋ง๋์ธ์:
intlayer.config.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
import { type IntlayerConfig, Locales } from "intlayer"; const config: IntlayerConfig = { internationalization: { defaultLocale: Locales.ENGLISH, // ๊ธฐ๋ณธ ๋ก์ผ์ผ ์ค์ locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], // ์ง์ํ๋ ๋ก์ผ์ผ ๋ชฉ๋ก }, }; export default config;์ด ๊ตฌ์ฑ ํ์ผ์ ํตํด ์ง์ญํ๋ URL, ๋ฏธ๋ค์จ์ด ๋ฆฌ๋๋ ์ , ์ฟ ํค ์ด๋ฆ, ์ฝํ ์ธ ์ ์ธ์ ์์น ๋ฐ ํ์ฅ์ ์ค์ , ์ฝ์์์ Intlayer ๋ก๊ทธ ๋นํ์ฑํ ๋ฑ ๋ค์ํ ์ค์ ์ ํ ์ ์์ต๋๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ๊ตฌ์ฑ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
Vite ๊ตฌ์ฑ์ Intlayer ํตํฉํ๊ธฐ
๊ตฌ์ฑ์ intlayer ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํ์ธ์:
vite.config.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
intlayer()Vite ํ๋ฌ๊ทธ์ธ์ Intlayer๋ฅผ Vite์ ํตํฉํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด ํ๋ฌ๊ทธ์ธ์ ์ฝํ ์ธ ์ ์ธ ํ์ผ์ ๋น๋๋ฅผ ๋ณด์ฅํ๊ณ ๊ฐ๋ฐ ๋ชจ๋์์ ์ด๋ฅผ ๋ชจ๋ํฐ๋งํฉ๋๋ค. ๋ํ Vite ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ Intlayer ํ๊ฒฝ ๋ณ์๋ฅผ ์ ์ํ๋ฉฐ, ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ๋ณ์นญ(alias)๋ ์ ๊ณตํฉ๋๋ค.React Router v7 ๋ผ์ฐํธ ๊ตฌ์ฑ
๋ก์ผ์ผ ์ธ์ ๋ผ์ฐํธ๋ก ๋ผ์ฐํ ๊ตฌ์ฑ์ ์ค์ ํ์ธ์:
app/routes.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
Set up your routing configuration to use file-system based routes with
flatRoutes:app/routes.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
The
flatRoutesfunction from@react-router/fs-routesenables file-system based routing, where the file structure in theroutes/directory determines your application's routes. TheignoredRouteFilesoption ensures that Intlayer content declaration files (.content.ts, etc.) are not treated as route files.๋ ์ด์์ ์ปดํฌ๋ํธ ์์ฑ
๋ฃจํธ ๋ ์ด์์๊ณผ ๋ก์ผ์ผ๋ณ ๋ ์ด์์์ ์ค์ ํ์ธ์:
๋ฃจํธ ๋ ์ด์์
app/root.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
์ฝํ ์ธ ์ ์ธํ๊ธฐ
๋ฒ์ญ์ ์ ์ฅํ๊ธฐ ์ํด ์ฝํ ์ธ ์ ์ธ์ ์์ฑํ๊ณ ๊ด๋ฆฌํ์ธ์:
app/routes/[lang]/page.content.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
์ฝํ ์ธ ์ ์ธ์ ์ ํ๋ฆฌ์ผ์ด์ ๋ด ์ด๋์๋ ์ ์ํ ์ ์์ผ๋ฉฐ,
contentDir๋๋ ํ ๋ฆฌ(๊ธฐ๋ณธ๊ฐ:./app)์ ํฌํจ๋๋ฉด ์๋์ผ๋ก ์ธ์๋ฉ๋๋ค. ๋ํ ์ฝํ ์ธ ์ ์ธ ํ์ผ ํ์ฅ์(๊ธฐ๋ณธ๊ฐ:.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml})์ ์ผ์นํด์ผ ํฉ๋๋ค.ํ์ผ ์์คํ ๊ธฐ๋ฐ ๋ผ์ฐํ ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
app/routes/($locale)._index.content.ts์ ๋ฐฐ์นํ ์ ์์ต๋๋ค.์์ธํ ๋ด์ฉ์ ์ฝํ ์ธ ์ ์ธ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ก์ผ์ผ ์ธ์ ์ปดํฌ๋ํธ ์์ฑ
๋ก์ผ์ผ ์ธ์ ๋ด๋น๊ฒ์ด์ ์ ์ํ
LocalizedLink์ปดํฌ๋ํธ๋ฅผ ์์ฑํฉ๋๋ค:app/components/localized-link.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
๋ก์ปฌ๋ผ์ด์ฆ๋ ๊ฒฝ๋ก๋ก ์ด๋ํ๋ ค๋ ๊ฒฝ์ฐ,
useLocalizedNavigateํ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:app/hooks/useLocalizedNavigate.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
ํ์ด์ง์์ Intlayer ํ์ฉํ๊ธฐ
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์์ ์ฝํ ์ธ ์ฌ์ ์ ์ก์ธ์คํ์ธ์:
ํ์งํ๋ ํ ํ์ด์ง
app/routes/page.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
app/routes/($locale)._index.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
useIntlayerํ ์ ๋ํด ๋ ์์๋ณด๋ ค๋ฉด ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.๊ธฐ์กด ์ฑ์ด ์๋ค๋ฉด, Intlayer Compiler์ extract ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒ ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๋ช ์ด ์์ ๋ณํํ ์ ์์ต๋๋ค.
๋ก์ผ์ผ ์ค์์ฒ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
์ฌ์ฉ์๊ฐ ์ธ์ด๋ฅผ ๋ณ๊ฒฝํ ์ ์๋๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ง๋์ธ์:
app/components/locale-switcher.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
app/components/locale-switcher.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
useLocaleํ ์ ๋ํด ๋ ์์๋ณด๋ ค๋ฉด ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.HTML ์์ฑ ๊ด๋ฆฌ ์ถ๊ฐ (์ ํ ์ฌํญ)
์ ํ์ฌํญHTML์ lang ๋ฐ dir ์์ฑ์ ๊ด๋ฆฌํ๋ ํ ์ ๋ง๋ญ๋๋ค:
app/hooks/useI18nHTMLAttributes.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
๊ทธ๋ฐ ๋ค์ ๋ฃจํธ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ์ธ์:
app/routes/layout.tsx์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
๋ฏธ๋ค์จ์ด ์ถ๊ฐ
intlayerProxy๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ฒ ์ธก ๋ผ์ฐํ ์ ์ถ๊ฐํ ์๋ ์์ต๋๋ค. ์ด ํ๋ฌ๊ทธ์ธ์ URL์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฌ ๋ก์ผ์ผ์ ์๋์ผ๋ก ๊ฐ์งํ๊ณ ์ ์ ํ ๋ก์ผ์ผ ์ฟ ํค๋ฅผ ์ค์ ํฉ๋๋ค. ๋ก์ผ์ผ์ด ์ง์ ๋์ง ์์ผ๋ฉด ํ๋ฌ๊ทธ์ธ์ด ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์ธ์ด ๊ธฐ๋ณธ ์ค์ ์ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ฅ ์ ์ ํ ๋ก์ผ์ผ์ ๊ฒฐ์ ํฉ๋๋ค. ๋ก์ผ์ผ์ด ๊ฐ์ง๋์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ๋ก์ผ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ๋ฉ๋๋ค.intlayerProxy๋ฅผ ํ๋ก๋์ ์์ ์ฌ์ฉํ๋ ค๋ฉดvite-intlayerํจํค์ง๋ฅผdevDependencies์์dependencies๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.Intlayer v9๋ถํฐ
intlayerProxy()๋intlayer()ํ๋ฌ๊ทธ์ธ์ ์ง์ ๋ฒ๋ค๋ก ํฌํจ๋์ด ์์ผ๋ฉฐrouting.enableProxy์ต์ (true๊ฐ ๊ธฐ๋ณธ๊ฐ)์ ํตํด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋ฉ๋๋ค. ์๋์ ๊ฐ์ด ๋ฐ๋ก ๋ฑ๋กํ๋ ๊ฒ์ ์ด์ ์ ํ ์ฌํญ์ ๋๋ค. ์ด๋ ํ์ ํธํ์ฑ์ ์ ์งํ๊ณ ํ๋ฌ๊ทธ์ธ ์์๋ฅผ ์ ์ดํด์ผ ํ๋ ์ค์ ์ ์ํด ์ ์ง๋ฉ๋๋ค.routing.enableProxy: false๋ก ์ค์ ํ์ฌ ๊ฑฐ์ ํ ์ ์์ต๋๋ค. v9 ๋ฆด๋ฆฌ์ค ๋ ธํธ๋ฅผ ์ฐธ์กฐํ์ธ์.vite.config.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
์ปดํฌ๋ํธ์์ ์ฝํ ์ธ ์ถ์ถ
์ ํ์ฌํญ๊ธฐ์กด codebase๊ฐ ์๋ ๊ฒฝ์ฐ, ์์ฒ ๊ฐ์ ํ์ผ์ ๋ณํํ๋ ๊ฒ์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
์ด ๊ณผ์ ์ ์ฝ๊ฒ ํ๊ธฐ ์ํด Intlayer๋ ์ปดํฌ๋ํธ๋ฅผ ๋ณํํ๊ณ ์ฝํ ์ธ ๋ฅผ ์ถ์ถํ๋ compiler / extractor๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด๋ฅผ ์ค์ ํ๋ ค๋ฉด
intlayer.config.tsํ์ผ์compiler์น์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค:intlayer.config.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
import { type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { // ... ๋๋จธ์ง ์ค์ compiler: { /** * ์ปดํ์ผ๋ฌ ํ์ฑํ ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค. */ enabled: true, /** * ์ถ๋ ฅ ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ ์ํฉ๋๋ค. */ output: ({ fileName, extension }) => `./${fileName}${extension}`, /** * ๋ณํ ํ ์ปดํฌ๋ํธ๋ฅผ ์ ์ฅํ ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค. * * - `true`์ธ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ ๋์คํฌ์ ์ปดํฌ๋ํธ ํ์ผ์ ์ฌ์์ฑํฉ๋๋ค. ๋ฐ๋ผ์ ๋ณํ์ ์๊ตฌ์ ์ด๋ฉฐ, ์ปดํ์ผ๋ฌ๋ ๋ค์ ํ๋ก์ธ์ค์์ ๋ณํ์ ๊ฑด๋๋๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ปดํ์ผ๋ฌ๋ ์ฑ์ ๋ณํํ ๋ค์ ์ ๊ฑฐํ ์ ์์ต๋๋ค. * * - `false`์ธ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ ๋น๋ ์ถ๋ ฅ์๋ง `useIntlayer()` ํจ์ ํธ์ถ์ ์ฃผ์ ํ๊ณ ๊ธฐ๋ณธ codebase๋ฅผ ์ ์งํฉ๋๋ค. ๋ณํ์ ๋ฉ๋ชจ๋ฆฌ์์๋ง ์ํ๋ฉ๋๋ค. */ saveComponents: false, /** * ๋์ ๋๋ฆฌ ํค ์ ๋์ฌ */ dictionaryKeyPrefix: "", }, }; export default config;extractor๋ฅผ ์คํํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ๋ณํํ๊ณ ์ฝํ ์ธ ๋ฅผ ์ถ์ถํฉ๋๋ค
bash์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
v9๋ถํฐ
intlayerCompiler๋intlayerํ๋ฌ๊ทธ์ธ์ ํฌํจ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ์๋์ผ๋ก ์ถ๊ฐํ ํ์๊ฐ ์์ต๋๋ค.vite.config.ts๋ฅผ ์ ๋ฐ์ดํธํ์ฌintlayerCompilerํ๋ฌ๊ทธ์ธ์ ํฌํจํ์ธ์:vite.config.ts์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
bash์ฝ๋ ๋ณต์ฌ์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
Configure TypeScript
Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
Ensure your TypeScript configuration includes the autogenerated types:
์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
Git Configuration
It is recommended to ignore the files generated by Intlayer. This allows you to avoid committing them to your Git repository.
To do this, you can add the following instructions to your .gitignore file:
์ฝ๋๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ
VS Code Extension
To improve your development experience with Intlayer, you can install the official Intlayer VS Code Extension.
Install from the VS Code Marketplace
This extension provides:
- Autocompletion for translation keys.
- Real-time error detection for missing translations.
- Inline previews of translated content.
- Quick actions to easily create and update translations.
For more details on how to use the extension, refer to the Intlayer VS Code Extension documentation.
Go Further
To go further, you can implement the visual editor or externalize your content using the CMS.
๋ฌธ์ ์ฐธ์กฐ
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ Intlayer๋ฅผ React Router v7๊ณผ ํตํฉํ์ฌ ๋ก์ผ์ผ ์ธ์ ๋ผ์ฐํ ๊ณผ TypeScript ์ง์์ด ํฌํจ๋ ์์ ํ ๊ตญ์ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ ์ ๊ณตํฉ๋๋ค.
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
React Router v7์ ์์ฒด ๋ฉ์์ง ๋ ์ด์ด๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก i18n ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์กฐํฉํด์ผ ํฉ๋๋ค:
react-i18next/i18next: ๋ฐํ์์ JSON ๋ค์์คํ์ด์ค๋ฅผ ๋ก๋ํ๋ฉฐ, ๋ผ์ฐํฐ์ ์ฐ๊ฒฐํ๊ธฐ ์ํ ๋ณ๋์ ๋ก์ผ์ผ ๊ฐ์ง๊ธฐ๊ฐ ํ์ํฉ๋๋ค.react-intl๋ฐLingui: ์ถ์ถ ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ ICU ๋ฉ์์ง ํฌ๋งท ๊ธฐ๋ฐ์ ๋๋ค.Intlayer: ๊ฐ์ฅ ์ง๋ณด๋ ์๋ฃจ์ ์ ๋๋ค. ์ฝ๋๋ฒ ์ด์ค ์ด๋์๋ ์ฝํ ์ธ ๋ฅผ ์ ์ธํ ์ ์์ผ๋ฉฐ(๊ฐ ์ปดํฌ๋ํธ ์ ๋๋ ์ค์ ์ง์ค์), ๋น๋ ํ์์ ์ปดํ์ผ๋๊ณ ์ข ๋จ ๊ฐ ํ์ ์์ ์ฑ์ ์ ๊ณตํ๋ฉฐ, ๋ก์ผ์ผ ์ธ์ ๋ผ์ฐํ ํฌํผ, AI ๋ฒ์ญ, ๋น์ฃผ์ผ ์๋ํฐ ๋ฐ CMS๋ฅผ ํฌํจํฉ๋๋ค.
์ Intlayer์ธ๊ฐ์ ๋ฒค์น๋งํฌ๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ค์์คํ์ด์ค ๊ธฐ๋ฐ ์ค์ ๋ณด๋ค ํจ์ฌ ์ ์ต๋๋ค. ํ์ด์ง๋ ๋ ๋๋งํ์ง ์๋ ์ธ์ด์ ์นดํ๋ก๊ทธ๋ฅผ ์ ๋ ๋ค์ด๋ก๋ํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์๋ฒ ๋ ๋๋ง๋ ๋งํฌ์
์ ์๋ฒ์์ ์ง์ ์ฝํ
์ธ ๋ฅผ ํ์ธํ๋ฉฐ, ๋น๋ ํ์ ์ปดํ์ผ๋ฌ๋ useIntlayer ํธ์ถ์ ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉํ๋ ์ ํํ ์ฌ์ ํญ๋ชฉ์ผ๋ก ๋์ฒดํ๋ฏ๋ก ์ฌ์ฉ๋์ง ์๋ ํค์ ์ธ์ด๋ ์ ๊ฑฐ๋๊ณ , ๋์ ์ฌ์ ์ ํตํด ๋ก์ผ์ผ๋ณ๋ก ๋ถํ ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ธ ๋์๋ค๊ณผ ๋น๊ตํ์ ๋ Intlayer๋ ๋ฒ๋ค ๋ฐ ํ์ด์ง ํฌ๊ธฐ๋ฅผ ์ต๋ 50%๊น์ง ์ค์ฌ์ค๋๋ค. ๋ฒ๋ค ์ต์ ํ์ ๋ฒค์น๋งํฌ๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ค, ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. react-i18next ๋ง์ด๊ทธ๋ ์ด์
๊ฐ์ด๋ ๋๋ i18next ๋ง์ด๊ทธ๋ ์ด์
๊ฐ์ด๋๋ฅผ ํตํด ์ฝํ
์ธ ๋ฅผ ์ ์ง์ ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ ์ ์์ต๋๋ค. ๋๋ ํ์ฌ API๋ฅผ ์์ ํ ์ ์งํ ์๋ ์์ต๋๋ค. ํธํ ์ด๋ํฐ(compat adapters)๋ react-i18next, react-intl, i18next์ ์์ ํ ๋์ผํ API๋ฅผ ๋
ธ์ถํ๋ฉด์ Intlayer ์ฌ์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ฏ๋ก, import ๊ตฌ๋ฌธ๋ง ๋ณ๊ฒฝํ๊ณ ์ปดํฌ๋ํธ ์ฝ๋๋ ๊ทธ๋๋ก ์ ์งํ ์ ์์ต๋๋ค.
๋ค. sync JSON ํ๋ฌ๊ทธ์ธ์ /messages/{locale}/{namespace}.json ํ์ผ์ ๋จ์ผ ์ง์ค ๊ณต๊ธ์(source of truth)์ผ๋ก ์ ์งํ๋ฉด์ ์๋ฐฉํฅ์ผ๋ก Intlayer ์ฌ์ ์ ์์ฑํฉ๋๋ค. sync PO ํ๋ฌ๊ทธ์ธ์ gettext ์นดํ๋ก๊ทธ์ ๋ํด ๋์ผํ ์์
์ ์ํํ๋ฉฐ, ๋ก์ผ์ผ๋ณ ํ์ผ์ ํตํด ๋ก์ผ์ผ์ ํ ํ์ผ์ ๋ชจ์ผ๋ ๋์ ์ธ์ด๋ณ๋ก ์ฝํ
์ธ ๋ฅผ ๋ถํ ํ ์๋ ์์ต๋๋ค.
์๋๋๋ค. npx intlayer extract๋ฅผ ์คํํ๋ฉด Intlayer๊ฐ ์ปดํฌ๋ํธ๋ฅผ ์ฝ๊ณ ์ฌ์ฉ์ ๋๋ฉด ๋ฌธ์์ด์ ์ถ์ถํ์ฌ ๊ฐ ์ปดํฌ๋ํธ ์์ .content ํ์ผ์ ์์ฑํ๋ฏ๋ก ์นดํ๋ก๊ทธ์ ์ผ์ผ์ด ๋ณต์ฌํ ํ์ ์์ด diff๋ง ๊ฒํ ํ๋ฉด ๋ฉ๋๋ค. ์ด ๊ฐ์ด๋์ 12๋จ๊ณ๋ฅผ ํ์ธํ์ธ์.
์์ ์๋ํ๋ ํ์ดํ๋ผ์ธ์ ์ํด Intlayer ์ปดํ์ผ๋ฌ๋ ๋น๋ ํ์์ JSX, TSX, Vue ๋ฐ Svelte ์์ค์์ ๋์ผํ ์์ ์ ์ํํ์ฌ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ฌ์ ์ ์์ฑํ๊ณ HMR์ ํตํด ๋๊ธฐํํ๋ฏ๋ก ์๋์ผ๋ก ํค๋ฅผ ๊ด๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค.
์ปดํ์ผ๋ฌ๋ฅผ ์ผ๊ธฐ ์ ์ ์์๋์ด์ผ ํ ๋ ๊ฐ์ง ์ ํ ์ฌํญ์ด ์์ต๋๋ค. ์ ์ ๋ถ์์ผ๋ก ์๋ํ๋ฏ๋ก API ์ค๋ฅ ์ฝ๋๋ CMS ํ๋์ ๊ฐ์ด ๋ฐํ์์๋ง ์กด์ฌํ๋ ๋ฌธ์์ด์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ํ ํฐ ์ฝ๋๋ฒ ์ด์ค์์ ๋ช ๊ฐ์ง ์ด๋
ธํ
์ด์
์ด ํ์ํ className="active" ๋๋ ์ํ ์ฝ๋์ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
๋ก์ง๊ณผ ์ฌ์ฉ์ ๋๋ฉด ํ
์คํธ๋ฅผ ๊ตฌ๋ถํด์ผ ํฉ๋๋ค. extract ๋ช
๋ น์ ์ฌ์ฉ์๊ฐ ์ง์ ์ ์ดํ ์ ์๋๋ก ํ์ฌ ๋ ๊ฐ์ง ๋ฌธ์ ๋ฅผ ๋ชจ๋ ๋ฐฉ์งํฉ๋๋ค.
5๊ฐ์ง ๋๊ตฌ๊ฐ ๋ชจ๋ ์ ํ ์ฌํญ์ผ๋ก ์ ๊ณต๋ฉ๋๋ค:
- VS Code ํ์ฅ ํ๋ก๊ทธ๋จ:
useIntlayerํค์์ ์ด๋ฅผ ์ ์ธํ ์ฝํ ์ธ ํ์ผ๋ก ๋ฐ๋ก ์ด๋ํ๊ณ , ์ปดํฌ๋ํธ์์ ์ฝํ ์ธ ๋ฅผ ์ถ์ถํ๋ฉฐ, ๋ช ๋ น ํ๋ ํธ๋ ์ ์ฉ Intlayer ํญ์์ build, fill, test, push, pull์ ์คํํ ์ ์์ต๋๋ค. - LSP ์๋ฒ: LSP๋ฅผ ์ง์ํ๋ ๋ชจ๋ ์๋ํฐ์์ ์ ์๋ก ์ด๋, ๋ชจ๋ ์ฐธ์กฐ ์ฐพ๊ธฐ, ๋ฒ์ญ ๊ฐ ๋ง์ฐ์ค ์ค๋ฒ ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ํค ๋ฐ ํ๋ ์๋ ์์ฑ, ์ ์ธ๋์ง ์์ ํค์ ๋ํ ๊ฒฝ๊ณ ๋ฑ ๋์ผํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ํ
i18next,react-i18next,next-intl,use-intlํธ์ถ๋ ํด์ํ๋ฏ๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ ์ ์ฉํฉ๋๋ค. - MCP ์๋ฒ: Cursor, VS Code, Claude Desktop, Claude Code, ChatGPT์ Intlayer ๋ฌธ์์ CLI๋ฅผ ๋
ธ์ถํ์ฌ AI ์ด์์คํดํธ๊ฐ ์ต์ ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ํํ ๋ต๋ณํ๊ณ
intlayer fill๋ฑ์ ๋ช ๋ น์ ์ง์ ์คํํ ์ ์๊ฒ ํฉ๋๋ค. - Agent Skills:
intlayer-config,intlayer-cli,intlayer-content๋ฐ ๊ฐ ํ๋ ์์ํฌ ์ ์ฉ ์คํฌ์ ํตํด AI ์์ด์ ํธ์๊ฒ ๋ผ์ฐํ ์ค์ ๊ณผ ์ฝํ ์ธ ๋ ธ๋ ํ์ ์ ํ์ต์ํต๋๋ค. - ESLint ํ๋ฌ๊ทธ์ธ:
no-raw-text๊ท์น์ผ๋ก ํ๋์ฝ๋ฉ๋ ๋ฌธ์์ด์ ํ์ํ๊ณ , ์ ์ ์ฌ์ ํค ๋ฐ ์ฌ์ฉ๋์ง ์๋ ์ฝํ ์ธ ์ ๋ํ ์ถ๊ฐ ๊ท์น์ ์ ๊ณตํฉ๋๋ค.
