홈샌드박스쇼케이스앱문서블로그
    • English영어
      EN
    • русский러시아어
      RU
    • 日本語일본어
      JA
    • français프랑스어
      FR
    • 한국어한국어
      KO
    • 中文중국어
      ZH
    • español스페인어
      ES
    • Deutsch독일어
      DE
    • العربية아랍어
      AR
    • italiano이탈리아어
      IT
    • British English영어(영국)
      EN-GB
    • português포르투갈어
      PT
    • हिन्दी힌디어
      HI
    • Türkçe튀르키예어
      TR
    • polski폴란드어
      PL
    • Indonesia인도네시아어
      ID
    • Tiếng Việt베트남어
      VI
    • українська우크라이나어
      UK
    /
    프레임워크로 문서 필터링
    Alt+←
    Intlayer의 이점
    시작하기
    개념
    • Intlayer 작동 방식
    • 구성
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • 비주얼 편집기
    • CMS
    • CI/CD 통합
    • 번역복수형열거조건성별삽입파일중첩MarkdownHTML함수 가져오기
    • 로케일별 파일
    • 컴파일러
    • 자동 채우기
    • 테스트
    • 번들 최적화
    환경
    • Next.js 14 및 앱 라우터
      Next.js 15
      Next.js 로케일 없는 URL
      Next.js 및 페이지 라우터
      컴파일러
    • Tanstack Start Solid
    • Astro 및 React
      Astro 및 Svelte
      Astro 및 Vue
      Astro 및 Solid
      Astro 및 Preact
      Astro 및 Lit
      Astro 및 Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt 및 Vue
    • Vite 및 Solid
    • SvelteKit
    • Vite 및 Preact
    • Vite 및 Vanilla JS
    • Vite 및 Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native 및 Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx 및 React
    Plugins
    • JSON
    • gettext (.po)
    VS Code 확장 기능
    에이전트
    • MCP 서버
    • 에이전트 기술
    릴리스
    • v8
    • v7
    • v6
    벤치마크
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    블로그
    질문 발표
    1. Documentation
    2. 환경
    3. Vite 및 Vue
    \n\n\n```\n\n#### Intlayer에서 콘텐츠 접근하기\n\nIntlayer는 콘텐츠에 접근할 수 있는 다양한 API를 제공합니다:\n\n- **컴포넌트 기반 문법** (권장):\n `` 또는 `` 문법을 사용하여 콘텐츠를 Intlayer 노드로 렌더링합니다. 이는 [비주얼 에디터](/ko/doc/concept/editor) 및 [CMS](/ko/doc/concept/cms)와 원활하게 통합됩니다.\n\n- **문자열 기반 문법**:\n `{{ myContent }}`를 사용하여 비주얼 에디터 지원 없이 콘텐츠를 일반 텍스트로 렌더링합니다.\n\n- **원시 HTML 문법**:\n `
    `를 사용하여 Visual Editor 지원 없이 콘텐츠를 원시 HTML로 렌더링할 수 있습니다.\n\n- **구조 분해 문법**:\n `useIntlayer` 컴포저블은 콘텐츠가 포함된 Proxy를 반환합니다. 이 Proxy는 반응성을 유지하면서 콘텐츠에 접근하기 위해 구조 분해할 수 있습니다.\n - `const content = useIntlayer(\"myContent\");`를 사용하고 `{{ content.myContent }}` / ``를 사용합니다.\n - 또는 `const { myContent } = useIntlayer(\"myContent\");`를 사용하고 `{{ myContent }}` / ``를 사용하여 콘텐츠를 구조 분해합니다.\n\n### (선택 사항) 6단계: 콘텐츠의 언어 변경\n\n콘텐츠의 언어를 변경하려면 `useLocale` 컴포저블에서 제공하는 `setLocale` 함수를 사용할 수 있습니다. 이 함수는 애플리케이션의 로케일을 설정하고 콘텐츠를 그에 맞게 업데이트할 수 있게 해줍니다.\n\n언어를 전환하는 컴포넌트를 만드세요:\n\n```vue fileName=\"src/components/LocaleSwitcher.vue\"\n\n\n\n```\n\n그런 다음, 이 컴포넌트를 App.vue에서 사용하세요:\n\n```vue fileName=\"src/App.vue\"\n\n\n\n```\n\n### (선택 사항) 7단계: 애플리케이션에 지역화된 라우팅 추가하기\n\nVue 애플리케이션에 지역화된 라우팅을 추가하는 것은 일반적으로 locale 접두사가 붙은 Vue Router를 사용하는 것을 포함합니다. 이렇게 하면 각 언어별로 고유한 경로가 생성되어 SEO 및 SEO 친화적인 URL에 유용합니다.\n\n예시:\n\n```plaintext\n- https://example.com/about\n- https://example.com/es/about\n- https://example.com/fr/about\n```\n\n먼저, Vue Router를 설치하세요:\n\n```bash packageManager=\"npm\"\nnpm install vue-router\nnpx intlayer init\n```\n\n```bash packageManager=\"pnpm\"\npnpm add vue-router\npnpm intlayer init\n```\n\n```bash packageManager=\"yarn\"\nyarn add vue-router\n```\n\n그런 다음, 로케일 기반 라우팅을 처리하는 라우터 구성을 만듭니다:\n\n```js fileName=\"src/router/index.ts\"\nimport {\n localeFlatMap,\n type Locale,\n} from 'intlayer';\nimport { createIntlayerClient } from \"vue-intlayer\";\nimport { createRouter, createWebHistory } from 'vue-router';\nimport HomeView from './views/home/HomeView.vue';\nimport RootView from './views/root/Root.vue';\n\n/**\n * 로케일별 경로와 메타데이터를 가진 라우트를 선언합니다.\n */\nconst routes = localeFlatMap(({ urlPrefix, locale }) => [\n {\n path: `${urlPrefix}/`,\n name: `Root-${locale}`,\n component: RootView,\n meta: {\n locale,\n },\n },\n {\n path: `${urlPrefix}/home`,\n name: `Home-${locale}`,\n component: HomeView,\n meta: {\n locale,\n },\n },\n]);\n\n// 라우터 인스턴스 생성\nexport const router = createRouter({\n history: createWebHistory(),\n routes,\n});\n\n// 로케일 처리를 위한 네비게이션 가드 추가\nrouter.beforeEach((to, _from, next) => {\n const client = createIntlayerClient();\n\n const metaLocale = to.meta.locale as Locale;\n\n // 라우트 메타에 정의된 로케일 재사용\n client.setLocale(metaLocale);\n next();\n});\n```\n\n> 이름은 라우터에서 경로를 식별하는 데 사용됩니다. 모든 경로에서 고유해야 충돌을 방지하고 올바른 내비게이션 및 링크를 보장할 수 있습니다.\n\n그런 다음, main.js 파일에서 라우터를 등록하세요:\n\n```js fileName=\"src/main.ts\"\nimport { createApp } from \"vue\";\nimport App from \"./App.vue\";\nimport { router } from \"./router\";\nimport \"./style.css\";\n\nconst app = createApp(App);\n\n// 앱에 라우터 추가\napp.use(router);\n\n// 앱 마운트\napp.mount(\"#app\");\n```\n\n그런 다음 `App.vue` 파일을 업데이트하여 RouterView 컴포넌트를 렌더링합니다. 이 컴포넌트는 현재 경로에 매칭되는 컴포넌트를 표시합니다.\n\n```vue fileName=\"src/App.vue\"\n\n\n\n```\n\n동시에, `intlayerProxy`을 사용하여 애플리케이션에 서버 사이드 라우팅을 추가할 수도 있습니다. 이 플러그인은 URL을 기반으로 현재 로케일을 자동으로 감지하고 적절한 로케일 쿠키를 설정합니다. 로케일이 지정되지 않은 경우, 사용자의 브라우저 언어 설정을 기반으로 가장 적합한 로케일을 결정합니다. 로케일이 감지되지 않으면 기본 로케일로 리디렉션합니다.\n\n```typescript {3,7} fileName=\"vite.config.ts\" codeFormat={[\"typescript\", \"esm\", \"commonjs\"]}\nimport { defineConfig } from \"vite\";\nimport vue from \"@vitejs/plugin-vue\";\nimport { intlayer, intlayerProxy } from \"vite-intlayer\";\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n plugins: [\n intlayerProxy(), // should be placed first\n vue(),\n intlayer(),\n ],\n});\n```\n\n### (선택 사항) 8단계: 로케일 변경 시 URL 변경하기\n\n사용자가 언어를 변경할 때 URL을 자동으로 업데이트하려면, `LocaleSwitcher` 컴포넌트를 Vue Router를 사용하도록 수정할 수 있습니다:\n\n```vue fileName=\"src/components/LocaleSwitcher.vue\"\n\n\n\n```\n\n팁: 더 나은 SEO 및 접근성을 위해, 10단계에서 보여준 것처럼 ``와 같은 태그를 사용하여 지역화된 페이지에 링크하세요. 이렇게 하면 검색 엔진이 언어별 URL을 올바르게 발견하고 색인화할 수 있습니다. SPA 동작을 유지하려면 @click.prevent로 기본 내비게이션을 방지하고, useLocale을 사용해 로케일을 변경하며, Vue Router를 통해 프로그래밍 방식으로 이동할 수 있습니다.\n\n```html\n
      \n
    1. \n \n
      \n English\n 영어\n EN\n
      \n
      \n
    2. \n
    3. \n \n
      \n Español\n 스페인어\n ES\n
      \n \n
    4. \n
    \n```\n\n### (선택 사항) 9단계: HTML 언어 및 방향 속성 변경\n\n애플리케이션이 여러 언어를 지원할 때, 현재 로케일에 맞게 `` 태그의 `lang` 및 `dir` 속성을 업데이트하는 것이 매우 중요합니다. 이렇게 하면 다음을 보장합니다:\n\n- **접근성**: 화면 낭독기 및 보조 기술은 올바른 `lang` 속성에 의존하여 콘텐츠를 정확하게 발음하고 해석합니다.\n- **텍스트 렌더링**: `dir` (방향) 속성은 텍스트가 올바른 순서로 렌더링되도록 보장합니다(예: 영어는 왼쪽에서 오른쪽으로, 아랍어나 히브리어는 오른쪽에서 왼쪽으로), 이는 가독성에 필수적입니다.\n- **SEO**: 검색 엔진은 `lang` 속성을 사용하여 페이지의 언어를 판단하고, 검색 결과에서 적절한 현지화된 콘텐츠를 제공하는 데 도움을 줍니다.\n\n로케일이 변경될 때 이러한 속성을 동적으로 업데이트함으로써, 모든 지원 언어에 대해 일관되고 접근 가능한 사용자 경험을 보장할 수 있습니다.\n\n```js fileName=\"src/composables/useI18nHTMLAttributes.ts\"\nimport { watch } from \"vue\";\nimport { useLocale } from \"vue-intlayer\";\nimport { getHTMLTextDir } from \"intlayer\";\n\n/**\n * 현재 로케일에 따라 HTML 요소의 `lang` 및 `dir` 속성을 업데이트하는 컴포저블입니다.\n *\n * @example\n * // App.vue 또는 전역 컴포넌트에서\n * import { useI18nHTMLAttributes } from './composables/useI18nHTMLAttributes'\n *\n * useI18nHTMLAttributes()\n */\nexport const useI18nHTMLAttributes = () => {\n const { locale } = useLocale();\n\n // 로케일이 변경될 때마다 HTML 속성을 업데이트합니다.\n watch(\n () => locale.value,\n (newLocale) => {\n if (!newLocale) return;\n\n // 언어 속성 업데이트\n document.documentElement.lang = newLocale;\n\n // 텍스트 방향 설정 (대부분 언어는 ltr, 아랍어, 히브리어 등은 rtl)\n document.documentElement.dir = getHTMLTextDir(newLocale);\n },\n { immediate: true }\n );\n};\n```\n\n이 컴포저블을 `App.vue` 또는 전역 컴포넌트에서 사용하세요:\n\n```vue fileName=\"src/App.vue\"\n\n\n\n```\n\n### (선택 사항) 10단계: 지역화된 링크 컴포넌트 만들기\n\n애플리케이션의 내비게이션이 현재 로케일을 준수하도록 하려면, 커스텀 `Link` 컴포넌트를 만들 수 있습니다. 이 컴포넌트는 내부 URL에 현재 언어 접두사를 자동으로 붙여줍니다. 예를 들어, 프랑스어 사용자가 \"About\" 페이지 링크를 클릭하면 `/about` 대신 `/fr/about`로 리디렉션됩니다.\n\n이 동작은 여러 가지 이유로 유용합니다:\n\n- **SEO 및 사용자 경험**: 로컬라이즈된 URL은 검색 엔진이 언어별 페이지를 올바르게 색인화하도록 돕고, 사용자가 선호하는 언어로 된 콘텐츠를 제공합니다.\n- **일관성**: 애플리케이션 전반에 걸쳐 로컬라이즈된 링크를 사용함으로써 내비게이션이 현재 로케일 내에서 유지되어 예상치 못한 언어 전환을 방지합니다.\n- **유지보수성**: 로컬라이제이션 로직을 단일 컴포넌트에 중앙 집중화하면 URL 관리를 단순화하여 애플리케이션이 성장함에 따라 코드베이스를 더 쉽게 유지보수하고 확장할 수 있습니다.\n\n```vue fileName=\"src/components/Link.vue\"\n\n\n\n```\n\nVue Router와 함께 사용하려면, 라우터 전용 버전을 만드세요:\n\n```vue fileName=\"src/components/RouterLink.vue\"\n\n\n\n```\n\n이 컴포넌트들을 애플리케이션에서 사용하세요:\n\n```vue fileName=\"src/App.vue\"\n\n\n\n```\n\n### (선택 사항) 11단계: 마크다운 렌더링\n\nIntlayer는 Vue 애플리케이션에서 Markdown 콘텐츠를 직접 렌더링하는 것을 지원합니다. 기본적으로 Markdown은 일반 텍스트로 처리됩니다. Markdown을 풍부한 HTML로 변환하려면 Markdown 파서인 [markdown-it](https://github.com/markdown-it/markdown-it)을 통합할 수 있습니다.\n\n이는 번역에 목록, 링크 또는 강조와 같은 서식이 포함된 콘텐츠가 있을 때 특히 유용합니다.\n\n기본적으로 Intlayer는 Markdown을 문자열로 렌더링합니다. 하지만 Intlayer는 `installIntlayerMarkdown` 함수를 사용하여 Markdown을 HTML로 렌더링하는 방법도 제공합니다.\n\n> `intlayer` 패키지를 사용하여 Markdown 콘텐츠를 선언하는 방법은 [markdown 문서](https://github.com/aymericzip/intlayer/tree/main/docs/ko/dictionary/markdown.md)를 참조하세요.\n\n```ts fileName=\"main.ts\"\nimport MarkdownIt from \"markdown-it\";\nimport { createApp, h } from \"vue\";\nimport { installIntlayer, installIntlayerMarkdown } from \"vue-intlayer\";\n\nconst app = createApp(App);\n\napp.use(intlayer);\n\nconst md = new MarkdownIt({\n html: true, // HTML 태그 허용\n linkify: true, // URL 자동 링크 변환\n typographer: true, // 스마트 따옴표, 대시 등 활성화\n});\n\n// Intlayer에게 마크다운을 HTML로 변환할 때 md.render()를 사용하도록 지시\ninstallIntlayerMarkdown(app, (markdown) => {\n const html = md.render(markdown);\n return h(\"div\", { innerHTML: html });\n});\n```\n\n등록이 완료되면, 컴포넌트 기반 문법을 사용하여 마크다운 콘텐츠를 직접 표시할 수 있습니다:\n\n```vue\n\n\n\n```\n\n### TypeScript 구성\n\nIntlayer는 모듈 확장을 사용하여 TypeScript의 이점을 활용하고 코드베이스를 더욱 견고하게 만듭니다.\n\n![Autocompletion](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)\n\n![Translation error](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)\n\nTypeScript 구성에 자동 생성된 타입이 포함되어 있는지 확인하세요.\n\n```json5 fileName=\"tsconfig.json\"\n{\n // ... 기존 TypeScript 구성\n \"include\": [\n // ... 기존 TypeScript 구성\n \".intlayer/**/*.ts\", // 자동 생성된 타입 포함\n ],\n}\n```\n\n### Git 구성\n\nIntlayer에서 생성된 파일은 무시하는 것이 권장됩니다. 이렇게 하면 Git 저장소에 해당 파일을 커밋하는 것을 방지할 수 있습니다.\n\n이를 위해 `.gitignore` 파일에 다음 지침을 추가할 수 있습니다:\n\n```bash\n# Intlayer에서 생성된 파일 무시\n.intlayer\n```\n\n### VS Code 확장 프로그램\n\nIntlayer와 함께 개발 경험을 향상시키기 위해 공식 **Intlayer VS Code 확장 프로그램**을 설치할 수 있습니다.\n\n[VS Code 마켓플레이스에서 설치하기](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)\n\n이 확장 프로그램은 다음 기능을 제공합니다:\n\n- 번역 키에 대한 **자동 완성**.\n- 누락된 번역에 대한 **실시간 오류 감지**.\n- 번역된 콘텐츠의 **인라인 미리보기**.\n- 번역을 쉽게 생성하고 업데이트할 수 있는 **빠른 작업**.\n\n확장 프로그램 사용 방법에 대한 자세한 내용은 [Intlayer VS Code 확장 문서](https://intlayer.org/doc/vs-code-extension)를 참조하세요.\n\n---\n\n### (선택 사항) 단계 1 : 컴포넌트 콘텐츠 추출\n\n기존 코드베이스가 있는 경우 수천 개의 파일을 변환하는 데 시간이 많이 걸릴 수 있습니다.\n\n이 프로세스를 용이하게 하기 위해 Intlayer는 컴포넌트를 변환하고 콘텐츠를 추출하기 위한 [컴파일러](/ko/doc/compiler) / [추출기](/ko/doc/concept/cli/extract)를 제안합니다.\n\n설정하려면 `intlayer.config.ts` 파일에 `compiler` 섹션을 추가할 수 있습니다.\n\n```typescript fileName=\"intlayer.config.ts\" codeFormat={[\"typescript\", \"esm\", \"commonjs\"]}\nimport { type IntlayerConfig } from \"intlayer\";\n\nconst config: IntlayerConfig = {\n // ... 나머지 구성\n compiler: {\n /**\n * 컴파일러 활성화 여부를 나타냅니다.\n */\n enabled: true,\n\n /**\n * 출력 파일 경로를 정의합니다.\n */\n output: ({ fileName, extension }) => `./${fileName}${extension}`,\n\n /**\n * 변환 후 컴포넌트를 저장할지 여부를 나타냅니다. 그렇게 하면 컴파일러를 한 번만 실행하여 앱을 변환한 다음 제거할 수 있습니다.\n */\n saveComponents: false,\n\n /**\n * 사전 키 접두사\n */\n dictionaryKeyPrefix: \"\",\n },\n};\n\nexport default config;\n```\n\n\n \n\n컴포넌트를 변환하고 콘텐츠를 추출하기 위해 추출기를 실행합니다\n\n```bash packageManager=\"npm\"\nnpx intlayer extract\n```\n\n```bash packageManager=\"pnpm\"\npnpm intlayer extract\n```\n\n```bash packageManager=\"yarn\"\nyarn intlayer extract\n```\n\n```bash packageManager=\"bun\"\nbun x intlayer extract\n```\n\n \n \n\n`vite.config.ts`를 업데이트하여 `intlayerCompiler` 플러그인을 포함합니다.\n\n```ts fileName=\"vite.config.ts\"\nimport { defineConfig } from \"vite\";\nimport { intlayer, intlayerCompiler } from \"vite-intlayer\";\n\nexport default defineConfig({\n plugins: [\n intlayer(),\n intlayerCompiler(), // 컴파일러 플러그인을 추가합니다\n ],\n});\n```\n\n```bash packageManager=\"npm\"\nnpm run build # 또는 npm run dev\n```\n\n```bash packageManager=\"pnpm\"\npnpm run build # 또는 pnpm run dev\n```\n\n```bash packageManager=\"yarn\"\nyarn build # 또는 yarn dev\n```\n\n```bash packageManager=\"bun\"\nbun run build # Or bun run dev\n```\n\n \n\n\n### (선택) 사이트맵과 robots.txt(빌드 시 생성)\n\nIntlayer는 `generateSitemap`과 `getMultilingualUrls`로 크롤러용 다국어 `sitemap.xml`과 `robots.txt`를 만들어 `public/`에 자동으로 쓸 수 있습니다. 보통 Vite 실행 **전에** 작은 Node 스크립트를 돌립니다(예: npm `predev` / `prebuild`).\n\n#### 사이트맵\n\nIntlayer 사이트맵 생성기는 로케일 설정을 반영하고 크롤러용 메타데이터를 포함합니다.\n\n> 생성된 사이트맵은 `xhtml:link`(hreflang)를 지원합니다. 단순 URL 나열이 아니라 각 페이지의 모든 언어 버전을 양방향으로 연결합니다(예: `/about`, `/fr/about`, `/about?lang=fr` - 라우팅 모드에 따름).\n\n#### Robots.txt\n\n`getMultilingualUrls`로 `Disallow`가 민감 경로의 모든 현지화 변형에 적용되도록 하세요.\n\n#### 1. 프로젝트 루트에 `generate-seo.mjs` 추가\n\n```javascript fileName=\"generate-seo.mjs\"\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { generateSitemap, getMultilingualUrls } from \"intlayer\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst SITE_URL = (process.env.SITE_URL || \"http://localhost:5173\").replace(\n /\\/$/,\n \"\"\n);\n\nconst pathList = [\n { path: \"/\", changefreq: \"daily\", priority: 1.0 },\n { path: \"/about\", changefreq: \"monthly\", priority: 0.7 },\n];\n\nconst sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });\nfs.writeFileSync(path.join(__dirname, \"public\", \"sitemap.xml\"), sitemapXml);\n\nconst getAllMultilingualUrls = (urls) =>\n urls.flatMap((url) => Object.values(getMultilingualUrls(url)));\n\nconst disallowedPaths = getAllMultilingualUrls([\"/admin\", \"/private\"]);\n\nconst robotsTxt = [\n \"User-agent: *\",\n \"Allow: /\",\n ...disallowedPaths.map((path) => `Disallow: ${path}`),\n \"\",\n `Sitemap: ${SITE_URL}/sitemap.xml`,\n].join(\"\\n\");\n\nfs.writeFileSync(path.join(__dirname, \"public\", \"robots.txt\"), robotsTxt);\n\nconsole.log(\"SEO files generated successfully.\");\n```\n\n스크립트가 `intlayer`를 import하려면 패키지가 설치되어 있어야 합니다. 프로덕션에서는 환경 변수 `SITE_URL`을 설정하세요(CI 등).\n\n> Node ESM에는 `generate-seo.mjs` 사용을 권장합니다. `generate-seo.js`를 쓰면 `package.json`의 `\"type\": \"module\"` 등으로 ESM을 켜세요.\n\n#### 2. Vite 전에 스크립트 실행\n\n```json fileName=\"package.json\"\n{\n \"scripts\": {\n \"dev\": \"vite\",\n \"prebuild\": \"node generate-seo.mjs\",\n \"build\": \"vite build\",\n \"preview\": \"vite preview\"\n }\n}\n```\n\npnpm이나 yarn을 쓰면 명령을 맞게 바꾸세요. CI에서 호출해도 됩니다.\n\n### 더 나아가기\n\n더 나아가려면 [비주얼 에디터](/ko/doc/concept/editor)를 구현하거나 [CMS](/ko/doc/concept/cms)를 사용하여 콘텐츠를 외부화할 수 있습니다.\n\n---\n","about":"Vite와 Vue 웹사이트를 다국어로 만드는 방법을 알아보세요. 국제화(i18n) 및 번역을 위한 문서를 따라가세요.","url":"https://intlayer.org/ko/doc/environment/vite-and-vue","datePublished":"18-04-2025","dateModified":"06-05-2026","keywords":"국제화, 문서, Intlayer, Vite, Vue, 자바스크립트","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"개발자, 콘텐츠 관리자"}}
    생성:2025-04-18마지막 업데이트:2026-05-06
    GitHub에서 애플리케이션 템플릿 보기

    이 페이지에는 애플리케이션 템플릿이 제공됩니다.

    쇼케이스 애플리케이션 보기

    이 페이지는 템플릿의 라이브 데모로 연결됩니다.

    비디오 튜토리얼 보기

    이 페이지에는 비디오 튜토리얼이 제공됩니다.

    이 문서를 원하는 AI 어시스턴트에 참조하세요
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    이 페이지와 원하는 AI 어시스턴트를 사용하여 문서를 요약합니다

    버전 기록

    1. "Solid useIntlayer API 사용법을 직접 속성 액세스로 업데이트"
      v8.9.02026. 5. 4.
    2. "init 명령어 추가"
      v7.5.92025. 12. 30.
    3. "이력 초기화"
      v5.5.102025. 6. 29.

    이 페이지의 콘텐츠는 AI를 사용하여 번역되었습니다.

    영어 원본 내용의 최신 버전을 보기
    문서 수정

    이 문서를 개선할 아이디어가 있으시면 GitHub에 풀 리퀘스트를 제출하여 자유롭게 기여해 주세요.

    문서에 대한 GitHub 링크
    복사

    문서의 Markdown을 클립보드에 복사

    Intlayer로 Vite and Vue 번역하기 | 국제화(i18n)

    GitHub에서 애플리케이션 템플릿을 확인하세요.

    Intlayer란 무엇인가요?

    Intlayer는 현대 웹 애플리케이션에서 다국어 지원을 간소화하기 위해 설계된 혁신적인 오픈 소스 국제화(i18n) 라이브러리입니다.

    Intlayer를 사용하면 다음을 할 수 있습니다:

    • 컴포넌트 수준에서 선언적 사전을 사용하여 번역을 쉽게 관리할 수 있습니다.
    • 메타데이터, 라우트 및 콘텐츠를 동적으로 현지화할 수 있습니다.
    • 자동 생성된 타입으로 TypeScript 지원을 보장하여 자동 완성 및 오류 감지를 향상시킵니다.
    • 동적 로케일 감지 및 전환과 같은 고급 기능을 활용할 수 있습니다.

    Vite와 Vue 애플리케이션에서 Intlayer 설정 단계별 가이드

    www.youtube.com
    ide.intlayer.org
    intlayer-vite-vue-template.vercel.app

    GitHub에서 애플리케이션 템플릿을 확인하세요.

    1단계: 의존성 설치

    npm을 사용하여 필요한 패키지를 설치하세요:

    bash
    코드 복사

    코드를 클립보드에 복사

    npm install intlayer vue-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer

      구성 관리, 번역, 콘텐츠 선언, 트랜스파일링 및 CLI 명령어를 위한 국제화 도구를 제공하는 핵심 패키지입니다.

    • vue-intlayer Intlayer를 Vue 애플리케이션과 통합하는 패키지로, Vue 국제화를 위한 컨텍스트 프로바이더와 컴포저블을 제공합니다.

    • vite-intlayer Vite 번들러(Vite bundler)와 Intlayer를 통합하기 위한 Vite 플러그인과, 사용자의 선호 로케일 감지, 쿠키 관리, URL 리디렉션 처리를 위한 미들웨어를 포함합니다.

    2단계: 프로젝트 구성

    애플리케이션의 언어를 구성하기 위한 설정 파일을 만듭니다:

    intlayer.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          // 다른 로케일들
        ],
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    export default config;
    이 구성 파일을 통해 지역화된 URL, 미들웨어 리디렉션, 쿠키 이름, 콘텐츠 선언의 위치 및 확장자 설정, 콘솔에서 Intlayer 로그 비활성화 등 다양한 설정을 할 수 있습니다. 사용 가능한 모든 매개변수 목록은 구성 문서를 참조하세요.

    3단계: Vite 구성에 Intlayer 통합하기

    intlayer 플러그인을 구성에 추가하세요.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { defineConfig } from "vite";
    import vue from "@vitejs/plugin-vue";
    import { intlayer } from "vite-intlayer";
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [vue(), intlayer()],
    });
    intlayer() Vite 플러그인은 Intlayer를 Vite와 통합하는 데 사용됩니다. 이 플러그인은 콘텐츠 선언 파일을 빌드하고 개발 모드에서 이를 모니터링하는 역할을 합니다. 또한 Vite 애플리케이션 내에서 Intlayer 환경 변수를 정의하며, 성능 최적화를 위한 별칭(alias)도 제공합니다.

    4단계: 콘텐츠 선언하기

    번역을 저장하기 위해 콘텐츠 선언을 생성하고 관리하세요:

    src/helloWorld.content.ts
    코드 복사

    코드를 클립보드에 복사

    import { t, type Dictionary } from "intlayer";
    
    const helloWorldContent = {
      key: "helloworld",
      content: {
        count: t({ en: "count is ", fr: "le compte est ", es: "el recuento es " }),
        edit: t({
          en: "Edit <code>components/HelloWorld.vue</code> and save to test HMR",
          fr: "Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR",
          es: "Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR",
        }),
        checkOut: t({
          ko: "확인하세요 ",
          en: "Check out ",
          fr: "Vérifiez ",
          es: "Compruebe ",
        }),
        officialStarter: t({
          ko: ", 공식 Vue + Vite 스타터",
          en: ", the official Vue + Vite starter",
          fr: ", le starter officiel Vue + Vite",
          es: ", el starter oficial Vue + Vite",
        }),
        learnMore: t({
          ko: "Vue에 대한 IDE 지원에 대해 자세히 알아보려면 ",
          en: "Learn more about IDE Support for Vue in the ",
          fr: "En savoir plus sur le support IDE pour Vue dans le ",
          es: "Aprenda más sobre el soporte IDE para Vue en el ",
        }),
        vueDocs: t({
          ko: "Vue 문서 확장 가이드",
          en: "Vue Docs Scaling up Guide",
          fr: "Vue Docs Scaling up Guide",
          es: "Vue Docs Scaling up Guide",
        }),
        readTheDocs: t({
          en: "Click on the Vite and Vue logos to learn more",
          fr: "Cliquez sur les logos Vite et Vue pour en savoir plus",
          es: "Haga clic en los logotipos de Vite y Vue para obtener más información",
          ko: "더 알아보려면 Vite와 Vue 로고를 클릭하세요",
        }),
      },
    } satisfies Dictionary;
    
    export default helloWorldContent;
    귀하의 콘텐츠 선언은 애플리케이션 내 어디에서나 정의할 수 있으며, contentDir 디렉토리(기본값: ./src)에 포함되기만 하면 됩니다. 또한 콘텐츠 선언 파일 확장자(기본값: .content.{json,ts,tsx,js,jsx,mjs,cjs})와 일치해야 합니다.
    자세한 내용은 콘텐츠 선언 문서를 참조하세요.

    5단계: 코드에서 Intlayer 활용하기

    Intlayer의 국제화 기능을 Vue 애플리케이션 전반에서 활용하려면, 먼저 메인 파일에서 Intlayer 싱글톤 인스턴스를 등록해야 합니다. 이 단계는 애플리케이션 내 모든 컴포넌트에 국제화 컨텍스트를 제공하여 컴포넌트 트리 어디에서나 번역을 사용할 수 있도록 하기 때문에 매우 중요합니다.

    코드 복사

    코드를 클립보드에 복사

    import { createApp } from "vue";import { intlayer } from "vue-intlayer";import App from "./App.vue";import "./style.css";const app = createApp(App);// 최상위에 프로바이더를 주입합니다app.use(intlayer);// 앱을 마운트합니다app.mount("#app");

    메인 Vue 컴포넌트를 생성하고 useIntlayer 컴포저블을 사용하여 애플리케이션 전반에서 콘텐츠 사전에 접근할 수 있습니다:

    src/HelloWord.vue
    코드 복사

    코드를 클립보드에 복사

    <script setup lang="ts">import { ref } from "vue";import { useIntlayer } from "vue-intlayer";defineProps({  msg: String,});const {  count,  edit,  checkOut,  officialStarter,  learnMore,  vueDocs,  readTheDocs,} = useIntlayer("helloworld");const countRef = ref(0);</script><template>  <h1>{{ msg }}</h1>  <div class="card">    <button type="button" @click="countRef++">      <count />      {{ countRef }}    </button>    <p v-html="edit"></p>  </div>  <p>    <checkOut />    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"      >create-vue</a    >, <officialStarter />  </p>  <p>    <learnMore />    <a      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"      target="_blank"      ><vueDocs /></a    >.  </p>  <p class="read-the-docs"><readTheDocs /></p>  <p class="read-the-docs">{{ readTheDocs }}</p></template>

    Intlayer에서 콘텐츠 접근하기

    Intlayer는 콘텐츠에 접근할 수 있는 다양한 API를 제공합니다:

    • 컴포넌트 기반 문법 (권장): <myContent /> 또는 <Component :is="myContent" /> 문법을 사용하여 콘텐츠를 Intlayer 노드로 렌더링합니다. 이는 비주얼 에디터 및 CMS와 원활하게 통합됩니다.

    • 문자열 기반 문법: {{ myContent }}를 사용하여 비주얼 에디터 지원 없이 콘텐츠를 일반 텍스트로 렌더링합니다.

    • 원시 HTML 문법: <div v-html="myContent" />를 사용하여 Visual Editor 지원 없이 콘텐츠를 원시 HTML로 렌더링할 수 있습니다.

    • 구조 분해 문법: useIntlayer 컴포저블은 콘텐츠가 포함된 Proxy를 반환합니다. 이 Proxy는 반응성을 유지하면서 콘텐츠에 접근하기 위해 구조 분해할 수 있습니다.

      • const content = useIntlayer("myContent");를 사용하고 {{ content.myContent }} / <content.myContent />를 사용합니다.
      • 또는 const { myContent } = useIntlayer("myContent");를 사용하고 {{ myContent }} / <myContent/>를 사용하여 콘텐츠를 구조 분해합니다.

    (선택 사항) 6단계: 콘텐츠의 언어 변경

    콘텐츠의 언어를 변경하려면 useLocale 컴포저블에서 제공하는 setLocale 함수를 사용할 수 있습니다. 이 함수는 애플리케이션의 로케일을 설정하고 콘텐츠를 그에 맞게 업데이트할 수 있게 해줍니다.

    언어를 전환하는 컴포넌트를 만드세요:

    src/components/LocaleSwitcher.vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <div class="locale-switcher">    <select v-model="selectedLocale" @change="changeLocale">      <option v-for="loc in availableLocales" :key="loc" :value="loc">        {{ getLocaleName(loc) }}      </option>    </select>  </div></template><script setup lang="ts">import { ref, watch } from "vue";import { getLocaleName } from "intlayer";import { useLocale } from "vue-intlayer";// 로케일 정보와 setLocale 함수 가져오기const { locale, availableLocales, setLocale } = useLocale();// ref로 선택된 로케일 추적const selectedLocale = ref(locale.value);// 선택이 변경될 때 로케일 업데이트const changeLocale = () => setLocale(selectedLocale.value);// selectedLocale을 전역 locale과 동기화 유지watch(  () => locale.value,  (newLocale) => {    selectedLocale.value = newLocale;  });</script>

    그런 다음, 이 컴포넌트를 App.vue에서 사용하세요:

    src/App.vue
    코드 복사

    코드를 클립보드에 복사

    <script setup lang="ts">import { useIntlayer } from "vue-intlayer";import HelloWorld from "@components/HelloWorld.vue";import LocaleSwitcher from "@components/LocaleSwitcher.vue";import { ref, watch } from "vue";const content = useIntlayer("app"); // 관련 intlayer 선언 파일 생성</script><template>  <div>    <LocaleSwitcher />    <a href="https://vite.dev" target="_blank">      <img src="/vite.svg" class="logo" :alt="content.viteLogo" />    </a>    <a href="https://vuejs.org/" target="_blank">      <img src="./assets/vue.svg" class="logo vue" :alt="content.vueLogo" />    </a>  </div>  <HelloWorld :msg="content.title" /></template>

    (선택 사항) 7단계: 애플리케이션에 지역화된 라우팅 추가하기

    Vue 애플리케이션에 지역화된 라우팅을 추가하는 것은 일반적으로 locale 접두사가 붙은 Vue Router를 사용하는 것을 포함합니다. 이렇게 하면 각 언어별로 고유한 경로가 생성되어 SEO 및 SEO 친화적인 URL에 유용합니다.

    예시:

    plaintext
    코드 복사

    코드를 클립보드에 복사

    - https://example.com/about- https://example.com/es/about- https://example.com/fr/about

    먼저, Vue Router를 설치하세요:

    bash
    코드 복사

    코드를 클립보드에 복사

    npm install vue-routernpx intlayer init

    그런 다음, 로케일 기반 라우팅을 처리하는 라우터 구성을 만듭니다:

    src/router/index.ts
    코드 복사

    코드를 클립보드에 복사

    import {  localeFlatMap,  type Locale,} from 'intlayer';import { createIntlayerClient } from "vue-intlayer";import { createRouter, createWebHistory } from 'vue-router';import HomeView from './views/home/HomeView.vue';import RootView from './views/root/Root.vue';/** * 로케일별 경로와 메타데이터를 가진 라우트를 선언합니다. */const routes = localeFlatMap(({ urlPrefix, locale }) => [  {    path: `${urlPrefix}/`,    name: `Root-${locale}`,    component: RootView,    meta: {      locale,    },  },  {    path: `${urlPrefix}/home`,    name: `Home-${locale}`,    component: HomeView,    meta: {      locale,    },  },]);// 라우터 인스턴스 생성export const router = createRouter({  history: createWebHistory(),  routes,});// 로케일 처리를 위한 네비게이션 가드 추가router.beforeEach((to, _from, next) => {  const client = createIntlayerClient();  const metaLocale = to.meta.locale as Locale;  // 라우트 메타에 정의된 로케일 재사용  client.setLocale(metaLocale);  next();});
    이름은 라우터에서 경로를 식별하는 데 사용됩니다. 모든 경로에서 고유해야 충돌을 방지하고 올바른 내비게이션 및 링크를 보장할 수 있습니다.

    그런 다음, main.js 파일에서 라우터를 등록하세요:

    src/main.ts
    코드 복사

    코드를 클립보드에 복사

    import { createApp } from "vue";import App from "./App.vue";import { router } from "./router";import "./style.css";const app = createApp(App);// 앱에 라우터 추가app.use(router);// 앱 마운트app.mount("#app");

    그런 다음 App.vue 파일을 업데이트하여 RouterView 컴포넌트를 렌더링합니다. 이 컴포넌트는 현재 경로에 매칭되는 컴포넌트를 표시합니다.

    src/App.vue
    코드 복사

    코드를 클립보드에 복사

    <script setup lang="ts">import LocaleSwitcher from "@components/LocaleSwitcher.vue";</script><template>  <nav>    <LocaleSwitcher />  </nav>  <RouterView /></template>

    동시에, intlayerProxy을 사용하여 애플리케이션에 서버 사이드 라우팅을 추가할 수도 있습니다. 이 플러그인은 URL을 기반으로 현재 로케일을 자동으로 감지하고 적절한 로케일 쿠키를 설정합니다. 로케일이 지정되지 않은 경우, 사용자의 브라우저 언어 설정을 기반으로 가장 적합한 로케일을 결정합니다. 로케일이 감지되지 않으면 기본 로케일로 리디렉션합니다.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { defineConfig } from "vite";
    import vue from "@vitejs/plugin-vue";
    import { intlayer, intlayerProxy } from "vite-intlayer";
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        intlayerProxy(), // should be placed first
        vue(),
        intlayer(),
      ],
    });

    (선택 사항) 8단계: 로케일 변경 시 URL 변경하기

    사용자가 언어를 변경할 때 URL을 자동으로 업데이트하려면, LocaleSwitcher 컴포넌트를 Vue Router를 사용하도록 수정할 수 있습니다:

    src/components/LocaleSwitcher.vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <div class="locale-switcher">    <select v-model="selectedLocale" @change="changeLocale">      <option v-for="loc in availableLocales" :key="loc" :value="loc">        {{ getLocaleName(loc) }}      </option>    </select>  </div></template><script setup lang="ts">import { ref, watch } from "vue";import { useRouter } from "vue-router";import { Locales, getLocaleName, getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";// Vue Router 가져오기const router = useRouter();// 로케일 정보와 setLocale 함수 가져오기const { locale, availableLocales, setLocale } = useLocale({  onLocaleChange: (newLocale) => {    // 현재 경로를 가져와서 로케일이 적용된 URL 생성    const currentPath = router.currentRoute.value.fullPath;    const localizedPath = getLocalizedUrl(currentPath, newLocale);    // 페이지를 새로고침하지 않고 로케일이 적용된 경로로 이동    router.push(localizedPath);  },});// 선택된 로케일을 ref로 추적const selectedLocale = ref(locale.value);// 선택이 변경될 때 로케일을 업데이트합니다.const changeLocale = () => {  setLocale(selectedLocale.value);};// selectedLocale을 전역 로케일과 동기화 상태로 유지합니다.watch(  () => locale.value,  (newLocale) => {    selectedLocale.value = newLocale;  });</script>

    팁: 더 나은 SEO 및 접근성을 위해, 10단계에서 보여준 것처럼 <a href="/fr/home" hreflang="fr">와 같은 태그를 사용하여 지역화된 페이지에 링크하세요. 이렇게 하면 검색 엔진이 언어별 URL을 올바르게 발견하고 색인화할 수 있습니다. SPA 동작을 유지하려면 @click.prevent로 기본 내비게이션을 방지하고, useLocale을 사용해 로케일을 변경하며, Vue Router를 통해 프로그래밍 방식으로 이동할 수 있습니다.

    html
    코드 복사

    코드를 클립보드에 복사

    <ol>  <li>    <a      hreflang="x-default"      aria-label="영어로 전환"      target="_self"      aria-current="page"      href="/doc/get-started"    >      <div>        <span dir="ltr" lang="en">English</span>        <span>영어</span>        <span>EN</span>      </div>    </a>  </li>  <li>    <a      hreflang="es"      aria-label="스페인어로 전환"      target="_self"      href="/es/doc/get-started"    >      <div>        <span dir="ltr" lang="es">Español</span>        <span>스페인어</span>        <span>ES</span>      </div>    </a>  </li></ol>

    (선택 사항) 9단계: HTML 언어 및 방향 속성 변경

    애플리케이션이 여러 언어를 지원할 때, 현재 로케일에 맞게 <html> 태그의 lang 및 dir 속성을 업데이트하는 것이 매우 중요합니다. 이렇게 하면 다음을 보장합니다:

    • 접근성: 화면 낭독기 및 보조 기술은 올바른 lang 속성에 의존하여 콘텐츠를 정확하게 발음하고 해석합니다.
    • 텍스트 렌더링: dir (방향) 속성은 텍스트가 올바른 순서로 렌더링되도록 보장합니다(예: 영어는 왼쪽에서 오른쪽으로, 아랍어나 히브리어는 오른쪽에서 왼쪽으로), 이는 가독성에 필수적입니다.
    • SEO: 검색 엔진은 lang 속성을 사용하여 페이지의 언어를 판단하고, 검색 결과에서 적절한 현지화된 콘텐츠를 제공하는 데 도움을 줍니다.

    로케일이 변경될 때 이러한 속성을 동적으로 업데이트함으로써, 모든 지원 언어에 대해 일관되고 접근 가능한 사용자 경험을 보장할 수 있습니다.

    src/composables/useI18nHTMLAttributes.ts
    코드 복사

    코드를 클립보드에 복사

    import { watch } from "vue";import { useLocale } from "vue-intlayer";import { getHTMLTextDir } from "intlayer";/** * 현재 로케일에 따라 HTML <html> 요소의 `lang` 및 `dir` 속성을 업데이트하는 컴포저블입니다. * * @example * // App.vue 또는 전역 컴포넌트에서 * import { useI18nHTMLAttributes } from './composables/useI18nHTMLAttributes' * * useI18nHTMLAttributes() */export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  // 로케일이 변경될 때마다 HTML 속성을 업데이트합니다.  watch(    () => locale.value,    (newLocale) => {      if (!newLocale) return;      // 언어 속성 업데이트      document.documentElement.lang = newLocale;      // 텍스트 방향 설정 (대부분 언어는 ltr, 아랍어, 히브리어 등은 rtl)      document.documentElement.dir = getHTMLTextDir(newLocale);    },    { immediate: true }  );};

    이 컴포저블을 App.vue 또는 전역 컴포넌트에서 사용하세요:

    src/App.vue
    코드 복사

    코드를 클립보드에 복사

    <script setup lang="ts">import { useI18nHTMLAttributes } from "@composables/useI18nHTMLAttributes";// 현재 로케일에 따라 HTML 속성을 적용합니다useI18nHTMLAttributes();</script><template>  <!-- 앱 템플릿 --></template>

    (선택 사항) 10단계: 지역화된 링크 컴포넌트 만들기

    애플리케이션의 내비게이션이 현재 로케일을 준수하도록 하려면, 커스텀 Link 컴포넌트를 만들 수 있습니다. 이 컴포넌트는 내부 URL에 현재 언어 접두사를 자동으로 붙여줍니다. 예를 들어, 프랑스어 사용자가 "About" 페이지 링크를 클릭하면 /about 대신 /fr/about로 리디렉션됩니다.

    이 동작은 여러 가지 이유로 유용합니다:

    • SEO 및 사용자 경험: 로컬라이즈된 URL은 검색 엔진이 언어별 페이지를 올바르게 색인화하도록 돕고, 사용자가 선호하는 언어로 된 콘텐츠를 제공합니다.
    • 일관성: 애플리케이션 전반에 걸쳐 로컬라이즈된 링크를 사용함으로써 내비게이션이 현재 로케일 내에서 유지되어 예상치 못한 언어 전환을 방지합니다.
    • 유지보수성: 로컬라이제이션 로직을 단일 컴포넌트에 중앙 집중화하면 URL 관리를 단순화하여 애플리케이션이 성장함에 따라 코드베이스를 더 쉽게 유지보수하고 확장할 수 있습니다.
    src/components/Link.vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <a :href="localizedHref" v-bind="$attrs">    <slot />  </a></template><script setup lang="ts">import { computed } from "vue";import { getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";const props = defineProps({  href: {    type: String,    required: true,  },});const { locale } = useLocale();// 링크가 외부 링크인지 확인const isExternalLink = computed(() => /^https?:\/\//.test(props.href || ""));// 내부 링크에 대해 로컬라이즈된 href 생성const localizedHref = computed(() =>  isExternalLink.value ? props.href : getLocalizedUrl(props.href, locale.value));</script>

    Vue Router와 함께 사용하려면, 라우터 전용 버전을 만드세요:

    src/components/RouterLink.vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <router-link :to="localizedTo" v-bind="$attrs">    <slot />  </router-link></template><script setup lang="ts">import { computed } from "vue";import { getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";const props = defineProps({  to: {    type: [String, Object],    required: true,  },});const { locale } = useLocale();// router-link용으로 지역화된 to-prop 생성const localizedTo = computed(() => {  if (typeof props.to === "string") {    return getLocalizedUrl(props.to, locale.value);  } else {    // 'to'가 객체인 경우, path 속성을 현지화합니다.    return {      ...props.to,      path: getLocalizedUrl(props.to.path ?? "/", locale.value),    };  }});</script>

    이 컴포넌트들을 애플리케이션에서 사용하세요:

    src/App.vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <div>    <!-- Vue 라우터 -->    <RouterLink to="/">루트</RouterLink>    <RouterLink to="/home">홈</RouterLink>    <!-- 기타 -->    <Link href="/">루트</Link>    <Link href="/home">홈</Link>  </div></template><script setup lang="ts">import Link from "@components/Link.vue";import RouterLink from "@components/RouterLink.vue";</script>

    (선택 사항) 11단계: 마크다운 렌더링

    Intlayer는 Vue 애플리케이션에서 Markdown 콘텐츠를 직접 렌더링하는 것을 지원합니다. 기본적으로 Markdown은 일반 텍스트로 처리됩니다. Markdown을 풍부한 HTML로 변환하려면 Markdown 파서인 markdown-it을 통합할 수 있습니다.

    이는 번역에 목록, 링크 또는 강조와 같은 서식이 포함된 콘텐츠가 있을 때 특히 유용합니다.

    기본적으로 Intlayer는 Markdown을 문자열로 렌더링합니다. 하지만 Intlayer는 installIntlayerMarkdown 함수를 사용하여 Markdown을 HTML로 렌더링하는 방법도 제공합니다.

    intlayer 패키지를 사용하여 Markdown 콘텐츠를 선언하는 방법은 markdown 문서를 참조하세요.
    main.ts
    코드 복사

    코드를 클립보드에 복사

    import MarkdownIt from "markdown-it";import { createApp, h } from "vue";import { installIntlayer, installIntlayerMarkdown } from "vue-intlayer";const app = createApp(App);app.use(intlayer);const md = new MarkdownIt({  html: true, // HTML 태그 허용  linkify: true, // URL 자동 링크 변환  typographer: true, // 스마트 따옴표, 대시 등 활성화});// Intlayer에게 마크다운을 HTML로 변환할 때 md.render()를 사용하도록 지시installIntlayerMarkdown(app, (markdown) => {  const html = md.render(markdown);  return h("div", { innerHTML: html });});

    등록이 완료되면, 컴포넌트 기반 문법을 사용하여 마크다운 콘텐츠를 직접 표시할 수 있습니다:

    vue
    코드 복사

    코드를 클립보드에 복사

    <template>  <div>    <myMarkdownContent />  </div></template><script setup lang="ts">import { useIntlayer } from "vue-intlayer";const { myMarkdownContent } = useIntlayer("my-component");</script>

    TypeScript 구성

    Intlayer는 모듈 확장을 사용하여 TypeScript의 이점을 활용하고 코드베이스를 더욱 견고하게 만듭니다.

    Autocompletion

    Translation error

    TypeScript 구성에 자동 생성된 타입이 포함되어 있는지 확인하세요.

    tsconfig.json
    코드 복사

    코드를 클립보드에 복사

    {  // ... 기존 TypeScript 구성  "include": [    // ... 기존 TypeScript 구성    ".intlayer/**/*.ts", // 자동 생성된 타입 포함  ],}

    Git 구성

    Intlayer에서 생성된 파일은 무시하는 것이 권장됩니다. 이렇게 하면 Git 저장소에 해당 파일을 커밋하는 것을 방지할 수 있습니다.

    이를 위해 .gitignore 파일에 다음 지침을 추가할 수 있습니다:

    bash
    코드 복사

    코드를 클립보드에 복사

    #  Intlayer에서 생성된 파일 무시.intlayer

    VS Code 확장 프로그램

    Intlayer와 함께 개발 경험을 향상시키기 위해 공식 Intlayer VS Code 확장 프로그램을 설치할 수 있습니다.

    VS Code 마켓플레이스에서 설치하기

    이 확장 프로그램은 다음 기능을 제공합니다:

    • 번역 키에 대한 자동 완성.
    • 누락된 번역에 대한 실시간 오류 감지.
    • 번역된 콘텐츠의 인라인 미리보기.
    • 번역을 쉽게 생성하고 업데이트할 수 있는 빠른 작업.

    확장 프로그램 사용 방법에 대한 자세한 내용은 Intlayer VS Code 확장 문서를 참조하세요.


    (선택 사항) 단계 1 : 컴포넌트 콘텐츠 추출

    기존 코드베이스가 있는 경우 수천 개의 파일을 변환하는 데 시간이 많이 걸릴 수 있습니다.

    이 프로세스를 용이하게 하기 위해 Intlayer는 컴포넌트를 변환하고 콘텐츠를 추출하기 위한 컴파일러 / 추출기를 제안합니다.

    설정하려면 intlayer.config.ts 파일에 compiler 섹션을 추가할 수 있습니다.

    intlayer.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      // ... 나머지 구성
      compiler: {
        /**
         * 컴파일러 활성화 여부를 나타냅니다.
         */
        enabled: true,
    
        /**
         * 출력 파일 경로를 정의합니다.
         */
        output: ({ fileName, extension }) => `./${fileName}${extension}`,
    
        /**
         * 변환 후 컴포넌트를 저장할지 여부를 나타냅니다. 그렇게 하면 컴파일러를 한 번만 실행하여 앱을 변환한 다음 제거할 수 있습니다.
         */
        saveComponents: false,
    
        /**
         * 사전 키 접두사
         */
        dictionaryKeyPrefix: "",
      },
    };
    
    export default config;

    컴포넌트를 변환하고 콘텐츠를 추출하기 위해 추출기를 실행합니다

    bash
    코드 복사

    코드를 클립보드에 복사

    npx intlayer extract

    vite.config.ts를 업데이트하여 intlayerCompiler 플러그인을 포함합니다.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // 컴파일러 플러그인을 추가합니다 ],});
    bash
    코드 복사

    코드를 클립보드에 복사

    npm run build # 또는 npm run dev

    (선택) 사이트맵과 robots.txt(빌드 시 생성)

    Intlayer는 generateSitemap과 getMultilingualUrls로 크롤러용 다국어 sitemap.xml과 robots.txt를 만들어 public/에 자동으로 쓸 수 있습니다. 보통 Vite 실행 전에 작은 Node 스크립트를 돌립니다(예: npm predev / prebuild).

    사이트맵

    Intlayer 사이트맵 생성기는 로케일 설정을 반영하고 크롤러용 메타데이터를 포함합니다.

    생성된 사이트맵은 xhtml:link(hreflang)를 지원합니다. 단순 URL 나열이 아니라 각 페이지의 모든 언어 버전을 양방향으로 연결합니다(예: /about, /fr/about, /about?lang=fr - 라우팅 모드에 따름).

    Robots.txt

    getMultilingualUrls로 Disallow가 민감 경로의 모든 현지화 변형에 적용되도록 하세요.

    1. 프로젝트 루트에 generate-seo.mjs 추가

    generate-seo.mjs
    코드 복사

    코드를 클립보드에 복사

    import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");

    스크립트가 intlayer를 import하려면 패키지가 설치되어 있어야 합니다. 프로덕션에서는 환경 변수 SITE_URL을 설정하세요(CI 등).

    Node ESM에는 generate-seo.mjs 사용을 권장합니다. generate-seo.js를 쓰면 package.json의 "type": "module" 등으로 ESM을 켜세요.

    2. Vite 전에 스크립트 실행

    package.json
    코드 복사

    코드를 클립보드에 복사

    {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}

    pnpm이나 yarn을 쓰면 명령을 맞게 바꾸세요. CI에서 호출해도 됩니다.

    더 나아가기

    더 나아가려면 비주얼 에디터를 구현하거나 CMS를 사용하여 콘텐츠를 외부화할 수 있습니다.


    Compiler
    Nuxt 및 Vue
    Alt+→

    이 페이지에서

      토론은 익명이며 일반적인 문제를 해결하기 위해 정기적으로 검토됩니다. 기능 아이디어, 문서에 대한 피드백 또는 Intlayer와 관련된 모든 것을 자유롭게 공유하세요, 이 의견을 로드맵 구성과 제품 개선에 활용합니다.

      npm install intlayer vue-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { createApp } from "vue";import { intlayer } from "vue-intlayer";import App from "./App.vue";import "./style.css";const app = createApp(App);// 최상위에 프로바이더를 주입합니다app.use(intlayer);// 앱을 마운트합니다app.mount("#app");
      <script setup lang="ts">import { ref } from "vue";import { useIntlayer } from "vue-intlayer";defineProps({  msg: String,});const {  count,  edit,  checkOut,  officialStarter,  learnMore,  vueDocs,  readTheDocs,} = useIntlayer("helloworld");const countRef = ref(0);</script><template>  <h1>{{ msg }}</h1>  <div class="card">    <button type="button" @click="countRef++">      <count />      {{ countRef }}    </button>    <p v-html="edit"></p>  </div>  <p>    <checkOut />    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"      >create-vue</a    >, <officialStarter />  </p>  <p>    <learnMore />    <a      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"      target="_blank"      ><vueDocs /></a    >.  </p>  <p class="read-the-docs"><readTheDocs /></p>  <p class="read-the-docs">{{ readTheDocs }}</p></template>
      <template>  <div class="locale-switcher">    <select v-model="selectedLocale" @change="changeLocale">      <option v-for="loc in availableLocales" :key="loc" :value="loc">        {{ getLocaleName(loc) }}      </option>    </select>  </div></template><script setup lang="ts">import { ref, watch } from "vue";import { getLocaleName } from "intlayer";import { useLocale } from "vue-intlayer";// 로케일 정보와 setLocale 함수 가져오기const { locale, availableLocales, setLocale } = useLocale();// ref로 선택된 로케일 추적const selectedLocale = ref(locale.value);// 선택이 변경될 때 로케일 업데이트const changeLocale = () => setLocale(selectedLocale.value);// selectedLocale을 전역 locale과 동기화 유지watch(  () => locale.value,  (newLocale) => {    selectedLocale.value = newLocale;  });</script>
      <script setup lang="ts">import { useIntlayer } from "vue-intlayer";import HelloWorld from "@components/HelloWorld.vue";import LocaleSwitcher from "@components/LocaleSwitcher.vue";import { ref, watch } from "vue";const content = useIntlayer("app"); // 관련 intlayer 선언 파일 생성</script><template>  <div>    <LocaleSwitcher />    <a href="https://vite.dev" target="_blank">      <img src="/vite.svg" class="logo" :alt="content.viteLogo" />    </a>    <a href="https://vuejs.org/" target="_blank">      <img src="./assets/vue.svg" class="logo vue" :alt="content.vueLogo" />    </a>  </div>  <HelloWorld :msg="content.title" /></template>
      - https://example.com/about- https://example.com/es/about- https://example.com/fr/about
      npm install vue-routernpx intlayer init
      import {  localeFlatMap,  type Locale,} from 'intlayer';import { createIntlayerClient } from "vue-intlayer";import { createRouter, createWebHistory } from 'vue-router';import HomeView from './views/home/HomeView.vue';import RootView from './views/root/Root.vue';/** * 로케일별 경로와 메타데이터를 가진 라우트를 선언합니다. */const routes = localeFlatMap(({ urlPrefix, locale }) => [  {    path: `${urlPrefix}/`,    name: `Root-${locale}`,    component: RootView,    meta: {      locale,    },  },  {    path: `${urlPrefix}/home`,    name: `Home-${locale}`,    component: HomeView,    meta: {      locale,    },  },]);// 라우터 인스턴스 생성export const router = createRouter({  history: createWebHistory(),  routes,});// 로케일 처리를 위한 네비게이션 가드 추가router.beforeEach((to, _from, next) => {  const client = createIntlayerClient();  const metaLocale = to.meta.locale as Locale;  // 라우트 메타에 정의된 로케일 재사용  client.setLocale(metaLocale);  next();});
      import { createApp } from "vue";import App from "./App.vue";import { router } from "./router";import "./style.css";const app = createApp(App);// 앱에 라우터 추가app.use(router);// 앱 마운트app.mount("#app");
      <script setup lang="ts">import LocaleSwitcher from "@components/LocaleSwitcher.vue";</script><template>  <nav>    <LocaleSwitcher />  </nav>  <RouterView /></template>
      <template>  <div class="locale-switcher">    <select v-model="selectedLocale" @change="changeLocale">      <option v-for="loc in availableLocales" :key="loc" :value="loc">        {{ getLocaleName(loc) }}      </option>    </select>  </div></template><script setup lang="ts">import { ref, watch } from "vue";import { useRouter } from "vue-router";import { Locales, getLocaleName, getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";// Vue Router 가져오기const router = useRouter();// 로케일 정보와 setLocale 함수 가져오기const { locale, availableLocales, setLocale } = useLocale({  onLocaleChange: (newLocale) => {    // 현재 경로를 가져와서 로케일이 적용된 URL 생성    const currentPath = router.currentRoute.value.fullPath;    const localizedPath = getLocalizedUrl(currentPath, newLocale);    // 페이지를 새로고침하지 않고 로케일이 적용된 경로로 이동    router.push(localizedPath);  },});// 선택된 로케일을 ref로 추적const selectedLocale = ref(locale.value);// 선택이 변경될 때 로케일을 업데이트합니다.const changeLocale = () => {  setLocale(selectedLocale.value);};// selectedLocale을 전역 로케일과 동기화 상태로 유지합니다.watch(  () => locale.value,  (newLocale) => {    selectedLocale.value = newLocale;  });</script>
      <ol>  <li>    <a      hreflang="x-default"      aria-label="영어로 전환"      target="_self"      aria-current="page"      href="/doc/get-started"    >      <div>        <span dir="ltr" lang="en">English</span>        <span>영어</span>        <span>EN</span>      </div>    </a>  </li>  <li>    <a      hreflang="es"      aria-label="스페인어로 전환"      target="_self"      href="/es/doc/get-started"    >      <div>        <span dir="ltr" lang="es">Español</span>        <span>스페인어</span>        <span>ES</span>      </div>    </a>  </li></ol>
      import { watch } from "vue";import { useLocale } from "vue-intlayer";import { getHTMLTextDir } from "intlayer";/** * 현재 로케일에 따라 HTML <html> 요소의 `lang` 및 `dir` 속성을 업데이트하는 컴포저블입니다. * * @example * // App.vue 또는 전역 컴포넌트에서 * import { useI18nHTMLAttributes } from './composables/useI18nHTMLAttributes' * * useI18nHTMLAttributes() */export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  // 로케일이 변경될 때마다 HTML 속성을 업데이트합니다.  watch(    () => locale.value,    (newLocale) => {      if (!newLocale) return;      // 언어 속성 업데이트      document.documentElement.lang = newLocale;      // 텍스트 방향 설정 (대부분 언어는 ltr, 아랍어, 히브리어 등은 rtl)      document.documentElement.dir = getHTMLTextDir(newLocale);    },    { immediate: true }  );};
      <script setup lang="ts">import { useI18nHTMLAttributes } from "@composables/useI18nHTMLAttributes";// 현재 로케일에 따라 HTML 속성을 적용합니다useI18nHTMLAttributes();</script><template>  <!-- 앱 템플릿 --></template>
      <template>  <a :href="localizedHref" v-bind="$attrs">    <slot />  </a></template><script setup lang="ts">import { computed } from "vue";import { getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";const props = defineProps({  href: {    type: String,    required: true,  },});const { locale } = useLocale();// 링크가 외부 링크인지 확인const isExternalLink = computed(() => /^https?:\/\//.test(props.href || ""));// 내부 링크에 대해 로컬라이즈된 href 생성const localizedHref = computed(() =>  isExternalLink.value ? props.href : getLocalizedUrl(props.href, locale.value));</script>
      <template>  <router-link :to="localizedTo" v-bind="$attrs">    <slot />  </router-link></template><script setup lang="ts">import { computed } from "vue";import { getLocalizedUrl } from "intlayer";import { useLocale } from "vue-intlayer";const props = defineProps({  to: {    type: [String, Object],    required: true,  },});const { locale } = useLocale();// router-link용으로 지역화된 to-prop 생성const localizedTo = computed(() => {  if (typeof props.to === "string") {    return getLocalizedUrl(props.to, locale.value);  } else {    // 'to'가 객체인 경우, path 속성을 현지화합니다.    return {      ...props.to,      path: getLocalizedUrl(props.to.path ?? "/", locale.value),    };  }});</script>
      <template>  <div>    <!-- Vue 라우터 -->    <RouterLink to="/">루트</RouterLink>    <RouterLink to="/home">홈</RouterLink>    <!-- 기타 -->    <Link href="/">루트</Link>    <Link href="/home">홈</Link>  </div></template><script setup lang="ts">import Link from "@components/Link.vue";import RouterLink from "@components/RouterLink.vue";</script>
      import MarkdownIt from "markdown-it";import { createApp, h } from "vue";import { installIntlayer, installIntlayerMarkdown } from "vue-intlayer";const app = createApp(App);app.use(intlayer);const md = new MarkdownIt({  html: true, // HTML 태그 허용  linkify: true, // URL 자동 링크 변환  typographer: true, // 스마트 따옴표, 대시 등 활성화});// Intlayer에게 마크다운을 HTML로 변환할 때 md.render()를 사용하도록 지시installIntlayerMarkdown(app, (markdown) => {  const html = md.render(markdown);  return h("div", { innerHTML: html });});
      <template>  <div>    <myMarkdownContent />  </div></template><script setup lang="ts">import { useIntlayer } from "vue-intlayer";const { myMarkdownContent } = useIntlayer("my-component");</script>
      {  // ... 기존 TypeScript 구성  "include": [    // ... 기존 TypeScript 구성    ".intlayer/**/*.ts", // 자동 생성된 타입 포함  ],}
      #  Intlayer에서 생성된 파일 무시.intlayer
      npx intlayer extract
      import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // 컴파일러 플러그인을 추가합니다 ],});
      npm run build # 또는 npm run dev
      import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");
      {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}