홈샌드박스쇼케이스앱문서블로그
    • 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. Sveltekit
    \n\n\n

    {$content.title}

    \n\n

    {@const Title = $content.title}</h1>\n<!-- 콘텐츠를 문자열로 렌더링하기 -->\n<div aria-label={$content.title.value}></div>\n<div aria-label={$content.title.toString()}></div>\n<div aria-label={String($content.title)}></div>\n```\n\n### (선택 사항) 6단계: 라우팅 설정하기\n\n다음 단계에서는 SvelteKit에서 로케일 기반 라우팅을 설정하는 방법을 보여줍니다. 이를 통해 URL에 로케일 접두사(e.g., `/en/about`, `/fr/about`)를 포함시켜 SEO 및 사용자 경험을 향상시킬 수 있습니다.\n\n```bash\n.\n└─── src\n ├── app.d.ts # 로케일 타입 정의\n ├── hooks.server.ts # 로케일 라우팅 관리\n ├── lib\n │   └── getLocale.ts # 헤더, 쿠키에서 로케일 확인\n ├── params\n │   └── locale.ts # 로케일 파라미터 정의\n └── routes\n ├── [[locale=locale]] # 로케일을 설정하기 위한 라우트 그룹 래핑\n │   ├── +layout.svelte # 경로에 대한 로컬 레이아웃\n │   ├── +layout.ts\n │   ├── +page.svelte\n │   ├── +page.ts\n │   └── about\n │      ├── +page.svelte\n │      └── +page.ts\n └── +layout.svelte # 폰트 및 전역 스타일을 위한 루트 레이아웃\n```\n\n### 7단계: 서버 사이드 로케일 감지 처리 (Hooks)\n\nSvelteKit에서는 SSR 중에 올바른 콘텐츠를 렌더링하기 위해 서버가 사용자의 로케일을 알아야 합니다. 우리는 URL이나 쿠키에서 로케일을 감지하기 위해 `hooks.server.ts`를 사용합니다.\n\n`src/hooks.server.ts` 파일을 생성하거나 수정하세요:\n\n```typescript fileName=\"src/hooks.server.ts\"\nimport type { Handle } from \"@sveltejs/kit\";\nimport { getLocalizedUrl } from \"intlayer\";\nimport { getLocale } from \"$lib/getLocale\";\n\nexport const handle: Handle = async ({ event, resolve }) => {\n const detectedLocale = getLocale(event);\n\n // 현재 경로가 이미 로케일로 시작하는지 확인 (예: /fr, /en)\n const pathname = event.url.pathname;\n const targetPathname = getLocalizedUrl(pathname, detectedLocale);\n\n // URL에 로케일이 없으면 (예: 사용자가 \"/\" 방문 시) 리다이렉트\n if (targetPathname !== pathname) {\n return new Response(undefined, {\n headers: { Location: targetPathname },\n status: 307, // 임시 리다이렉트\n });\n }\n\n return resolve(event, {\n transformPageChunk: ({ html }) => html.replace(\"%lang%\", detectedLocale),\n });\n};\n```\n\n그런 다음, 요청 이벤트에서 사용자의 로케일을 가져오는 헬퍼를 만듭니다:\n\n```typescript fileName=\"src/lib/getLocale.ts\"\nimport {\n configuration,\n getLocaleFromStorage,\n localeDetector,\n type Locale,\n} from \"intlayer\";\nimport type { RequestEvent } from \"@sveltejs/kit\";\n\n/**\n * 요청 이벤트에서 사용자의 로케일을 가져옵니다.\n * 이 함수는 `src/hooks.server.ts`의 `handle` 훅에서 사용됩니다.\n *\n * 먼저 Intlayer 저장소(쿠키 또는 커스텀 헤더)에서 로케일을 가져오려고 시도합니다.\n * 로케일을 찾지 못하면 브라우저의 \"Accept-Language\" 협상으로 대체합니다.\n *\n * @param event - SvelteKit의 요청 이벤트\n * @returns 사용자의 로케일\n */\nexport const getLocale = (event: RequestEvent): Locale => {\n const defaultLocale = configuration?.internationalization?.defaultLocale;\n\n // Intlayer 저장소(쿠키 또는 헤더)에서 로케일을 가져오려고 시도\n const storedLocale = getLocaleFromStorage({\n // SvelteKit 쿠키 접근\n getCookie: (name: string) => event.cookies.get(name) ?? null,\n // SvelteKit 헤더 접근\n getHeader: (name: string) => event.request.headers.get(name) ?? null,\n });\n\n if (storedLocale) {\n return storedLocale;\n }\n\n // 브라우저 \"Accept-Language\" 협상으로 대체\n const negotiatorHeaders: Record<string, string> = {};\n\n // SvelteKit Headers 객체를 일반 Record<string, string>으로 변환\n event.request.headers.forEach((value, key) => {\n negotiatorHeaders[key] = value;\n });\n\n // `Accept-Language` 헤더에서 로케일 확인\n const userFallbackLocale = localeDetector(negotiatorHeaders);\n\n if (userFallbackLocale) {\n return userFallbackLocale;\n }\n\n // 일치하는 로케일이 없으면 기본 로케일 반환\n return defaultLocale;\n};\n```\n\n> `getLocaleFromStorage`는 구성에 따라 헤더 또는 쿠키에서 로케일을 확인합니다. 자세한 내용은 [Configuration](https://intlayer.org/doc/configuration) 문서를 참조하세요.\n\n> `localeDetector` 함수는 `Accept-Language` 헤더를 처리하여 가장 적합한 로케일을 반환합니다.\n\n로케일이 구성되지 않은 경우 404 오류를 반환하고자 합니다. 이를 쉽게 하기 위해 로케일이 유효한지 확인하는 `match` 함수를 만들 수 있습니다:\n\n```ts fileName=\"/src/params/locale.ts\"import { defaultLocale, locales, type Locale } from \"intlayer\";\nexport const match = (param: Locale = defaultLocale): boolean =>\n locales.includes(param);\n```\n\n> **참고:** `src/app.d.ts` 파일에 로케일 정의가 포함되어 있는지 확인하세요:\n>\n> ```typescript\n> declare global {\n> namespace App {\n> interface Locals {\n> locale: import(\"intlayer\").Locale;\n> }\n> }\n> }\n> ```\n\n`+layout.svelte` 파일에서는 i18n과 관련 없는 정적 콘텐츠만 남기고 모든 내용을 제거할 수 있습니다:\n\n```svelte fileName=\"src/+layout.svelte\"\n<script lang=\"ts\">\n\t import './layout.css';\n\n let { children } = $props();\n</script>\n\n<div class=\"app\">\n\t{@render children()}\n</div>\n\n<style>\n\t.app {\n /* */\n\t}\n</style>\n```\n\n그런 다음, `[[locale=locale]]` 그룹 아래에 새 페이지와 레이아웃을 생성합니다:\n\n```ts fileName=\"src/routes/[[locale=locale]]/+layout.ts\"\nimport type { Load } from \"@sveltejs/kit\";\nimport { defaultLocale, type Locale } from \"intlayer\";\n\nexport const prerender = true;\n\n// 제네릭 Load 타입 사용\nexport const load: Load = ({ params }) => {\n const locale: Locale = (params.locale as Locale) ?? defaultLocale;\n\n return {\n locale,\n };\n};\n```\n\n```svelte fileName=\"src/routes/[[locale=locale]]/+layout.svelte\"\n<script lang=\"ts\">\n\timport type { Snippet } from 'svelte';\n\timport { useIntlayer, setupIntlayer } from \"svelte-intlayer\";\n\timport Header from './Header.svelte';\n\timport type { LayoutData } from './$types';\n\n\tlet { children, data }: { children: Snippet, data: LayoutData } = $props();\n\n\t// 경로에서 로케일로 Intlayer 초기화\n $effect(() => {\n setupIntlayer(data.locale);\n });\n\t// 레이아웃 콘텐츠 사전 사용\n\tconst layoutContent = useIntlayer('layout');\n</script>\n\n<Header />\n\n<main>\n\t{@render children()}\n</main>\n\n<footer>\n\t<p>\n\t\t{$layoutContent.footer.prefix.value}{' '}\n\t\t<a href=\"https://svelte.dev/docs/kit\">{$layoutContent.footer.linkLabel.value}</a>{' '}\n\t\t{$layoutContent.footer.suffix.value}\n\t</p>\n</footer>\n\n<style>\n /* */\n</style>\n```\n\n```ts fileName=\"src/routes/[[locale=locale]]/+page.ts\"\nexport const prerender = true;\n```\n\n```svelte fileName=\"src/routes/[[locale=locale]]/+page.svelte\"\n<script lang=\"ts\">\n\timport { useIntlayer } from \"svelte-intlayer\";\n\n\t// 홈 콘텐츠 사전을 사용합니다\n\tconst homeContent = useIntlayer('home');\n</script>\n\n<svelte:head>\n\t<title>{$homeContent.title.value}\n\n\n
    \n\t

    \n\t\t{$homeContent.title}\n\t

    \n
    \n\n\n```\n\n### (선택 사항) 8단계: 국제화된 링크\n\nSEO를 위해 경로에 로케일 접두사를 붙이는 것이 권장됩니다(예: `/en/about`, `/fr/about`). 이 컴포넌트는 현재 로케일로 모든 링크에 자동으로 접두사를 붙입니다.\n\n```svelte fileName=\"src/lib/components/LocalizedLink.svelte\"\n\n\n\n \n\n```\n\nSvelteKit의 `goto`를 사용하는 경우, `getLocalizedUrl`과 같은 로직을 사용하여 로컬라이즈된 URL로 이동할 수 있습니다:\n\n```typescript\nimport { goto } from \"$app/navigation\";\nimport { getLocalizedUrl } from \"intlayer\";\nimport { useLocale } from \"svelte-intlayer\";\n\nconst { locale } = useLocale();\nconst localizedPath = getLocalizedUrl(\"/about\", $locale);\ngoto(localizedPath); // 로케일에 따라 /en/about 또는 /fr/about로 이동합니다.\n```\n\n### (선택 사항) 9단계: 언어 전환기\n\n사용자가 언어를 전환할 수 있도록 URL을 업데이트합니다.\n\n```svelte fileName=\"src/lib/components/LanguageSwitcher.svelte\"\n\n\n
      \n {#each availableLocales as localeEl}\n
    • \n {\n e.preventDefault();\n setLocale(localeEl); // 스토어에 로케일을 설정하고 onLocaleChange를 트리거합니다\n }}\n class:active={$locale === localeEl}\n >\n {getLocaleName(localeEl)}\n \n
    • \n {/each}\n
    \n\n\n```\n\n### (선택 사항) 10단계: 백엔드 프록시 추가\n\nSvelteKit 애플리케이션에 백엔드 프록시를 추가하려면 `vite-intlayer` 플러그인이 제공하는 `intlayerProxy` 함수를 사용할 수 있습니다. 이 플러그인은 URL, 쿠키 및 브라우저 언어 설정을 기반으로 사용자에게 가장 적합한 로케일을 자동으로 감지합니다.\n\n```ts fileName=\"vite.config.ts\"\nimport { defineConfig } from \"vite\";\nimport { intlayer, intlayerProxy } from \"vite-intlayer\";\nimport { sveltekit } from \"@sveltejs/kit/vite\";\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n plugins: [\n intlayerProxy(), // should be placed first\n intlayer(),\n sveltekit(),\n ],],\n});\n```\n\n### (선택 사항) 11단계: intlayer 에디터 / CMS 설정하기\n\nintlayer 에디터를 설정하려면 [intlayer 에디터 문서](/ko/doc/concept/editor)를 따라야 합니다.\n\nintlayer CMS를 설정하려면 [intlayer CMS 문서](/ko/doc/concept/cms)를 따라야 합니다.\n\nintlayer 에디터 선택기를 시각화하려면 intlayer 콘텐츠에서 컴포넌트 구문을 사용해야 합니다.\n\n```svelte fileName=\"Component.svelte\"\n\n\n
    \n\n \n

    {$content.title}

    \n\n \n {@const Component = $content.component}\n
    \n```\n\n### Git 구성\n\nIntlayer가 생성한 파일은 무시하는 것이 권장됩니다.\n\n```plaintext fileName=\".gitignore\"\n# Intlayer가 생성한 파일 무시\n.intlayer\n```\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### 더 나아가기\n\n- **비주얼 에디터**: UI에서 직접 번역을 편집할 수 있도록 [Intlayer 비주얼 에디터](/ko/doc/concept/editor)를 통합하세요.\n- **CMS**: [Intlayer CMS](/ko/doc/concept/cms)를 사용하여 콘텐츠 관리를 외부화하세요.\n","about":"SvelteKit 웹사이트를 다국어로 만드는 방법을 알아보세요. 서버 사이드 렌더링(SSR)을 사용하여 국제화(i18n) 및 번역하는 문서를 따라가세요.","url":"https://intlayer.org/ko/doc/environment/sveltekit","datePublished":"20-11-2025","dateModified":"06-05-2026","keywords":"국제화, 문서, Intlayer, SvelteKit, 자바스크립트, SSR","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"개발자, 콘텐츠 관리자"}}
    생성:2025-11-20마지막 업데이트: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. "초기 기록"
      v7.1.102025. 11. 20.

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

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

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

    문서에 대한 GitHub 링크
    복사

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

    Intlayer를 사용하여 SvelteKit 웹사이트 번역하기 | 국제화(i18n)

    ide.intlayer.org
    intlayer-sveltekit-template.vercel.app

    목차

    Intlayer란 무엇인가?

    Intlayer는 현대 웹 애플리케이션에서 다국어 지원을 간소화하기 위해 설계된 혁신적인 오픈 소스 국제화(i18n) 라이브러리입니다. SvelteKit의 서버 사이드 렌더링(SSR) 기능과 원활하게 작동합니다.

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

    • 컴포넌트 수준에서 선언적 사전을 사용하여 번역을 쉽게 관리할 수 있습니다.
    • 메타데이터, 라우트 및 콘텐츠를 동적으로 현지화할 수 있습니다.
    • 자동 생성된 타입으로 TypeScript 지원을 보장할 수 있습니다.
    • SvelteKit의 SSR을 활용하여 SEO 친화적인 국제화를 구현할 수 있습니다.

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

    시작하려면 새 SvelteKit 프로젝트를 생성하세요. 다음은 우리가 만들 최종 구조입니다:

    bash
    코드 복사

    코드를 클립보드에 복사

    .├── intlayer.config.ts├── package.json├── src│   ├── app.d.ts│   ├── app.html│   ├── hooks.server.ts│   ├── lib│   │   ├── getLocale.ts│   │   ├── LocaleSwitcher.svelte│   │   └── LocalizedLink.svelte│   ├── params│   │   └── locale.ts│   └── routes│       ├── [[locale=locale]]│       │   ├── +layout.svelte│       │   ├── +layout.ts│       │   ├── +page.svelte│       │   ├── +page.ts│       │   ├── about│       │   │   ├── +page.svelte│       │   │   ├── +page.ts│       │   │   └── page.content.ts│       │   ├── Counter.content.ts│       │   ├── Counter.svelte│       │   ├── Header.content.ts│       │   ├── Header.svelte│       │   ├── home.content.ts│       │   └── layout.content.ts│       ├── +layout.svelte│       └── layout.css├── static│   ├── favicon.svg│   └── robots.txt├── svelte.config.js├── tsconfig.json└── vite.config.ts

    1단계: 의존성 설치

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

    bash
    코드 복사

    코드를 클립보드에 복사

    npm install intlayer svelte-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer: 핵심 i18n 패키지입니다.
    • svelte-intlayer: Svelte/SvelteKit용 컨텍스트 제공자와 스토어를 제공합니다.
    • vite-intlayer: 콘텐츠 선언을 빌드 프로세스와 통합하는 Vite 플러그인입니다.

    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;

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

    vite.config.ts 파일을 업데이트하여 Intlayer 플러그인을 포함하세요. 이 플러그인은 콘텐츠 파일의 트랜스파일을 처리합니다.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { sveltekit } from "@sveltejs/kit/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [intlayer(), sveltekit()], // 순서가 중요하며, Intlayer는 SvelteKit보다 먼저 위치해야 합니다.});

    4단계: 콘텐츠 선언하기

    src 폴더 내 어디에서든 콘텐츠 선언 파일을 생성하세요 (예: src/lib/content 또는 컴포넌트와 함께). 이 파일들은 각 로케일별로 t() 함수를 사용하여 애플리케이션의 번역 가능한 콘텐츠를 정의합니다.

    5단계: 컴포넌트에서 Intlayer 사용하기

    이제 어떤 Svelte 컴포넌트에서든 useIntlayer 함수를 사용할 수 있습니다. 이 함수는 locale이 변경될 때 자동으로 업데이트되는 반응형 스토어를 반환합니다. 이 함수는 SSR과 클라이언트 사이드 내비게이션 모두에서 현재 locale을 자동으로 인식합니다.

    참고: useIntlayer는 Svelte 스토어를 반환하므로, 반응형 값을 접근하려면 `--- createdAt: 2025-11-20 updatedAt: 2026-05-06 title: SvelteKit 앱 번역 방법 – i18n 가이드 2026 description: SvelteKit 웹사이트를 다국어로 만드는 방법을 알아보세요. 서버 사이드 렌더링(SSR)을 사용하여 국제화(i18n) 및 번역하는 문서를 따라가세요. keywords:

    • 국제화
    • 문서
    • Intlayer
    • SvelteKit
    • 자바스크립트
    • SSR slugs:
    • doc
    • environment
    • sveltekit applicationTemplate: https://github.com/aymericzip/intlayer-sveltekit-template history:
    • version: 7.1.10 date: 2025-11-20 changes: 초기 기록

    Intlayer를 사용하여 SvelteKit 웹사이트 번역하기 | 국제화(i18n)

    목차

    Intlayer란 무엇인가?

    Intlayer는 현대 웹 애플리케이션에서 다국어 지원을 간소화하기 위해 설계된 혁신적인 오픈 소스 국제화(i18n) 라이브러리입니다. SvelteKit의 서버 사이드 렌더링(SSR) 기능과 원활하게 작동합니다.

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

    • 컴포넌트 수준에서 선언적 사전을 사용하여 번역을 쉽게 관리할 수 있습니다.
    • 메타데이터, 라우트 및 콘텐츠를 동적으로 현지화할 수 있습니다.
    • 자동 생성된 타입으로 TypeScript 지원을 보장할 수 있습니다.
    • SvelteKit의 SSR을 활용하여 SEO 친화적인 국제화를 구현할 수 있습니다.

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

    시작하려면 새 SvelteKit 프로젝트를 생성하세요. 다음은 우리가 만들 최종 구조입니다:

    bash
    코드 복사

    코드를 클립보드에 복사

    .├── intlayer.config.ts├── package.json├── src│   ├── app.d.ts│   ├── app.html│   ├── hooks.server.ts│   ├── lib│   │   ├── getLocale.ts│   │   ├── LocaleSwitcher.svelte│   │   └── LocalizedLink.svelte│   ├── params│   │   └── locale.ts│   └── routes│       ├── [[locale=locale]]│       │   ├── +layout.svelte│       │   ├── +layout.ts│       │   ├── +page.svelte│       │   ├── +page.ts│       │   ├── about│       │   │   ├── +page.svelte│       │   │   ├── +page.ts│       │   │   └── page.content.ts│       │   ├── Counter.content.ts│       │   ├── Counter.svelte│       │   ├── Header.content.ts│       │   ├── Header.svelte│       │   ├── home.content.ts│       │   └── layout.content.ts│       ├── +layout.svelte│       └── layout.css├── static│   ├── favicon.svg│   └── robots.txt├── svelte.config.js├── tsconfig.json└── vite.config.ts

    1단계: 의존성 설치

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

    bash
    코드 복사

    코드를 클립보드에 복사

    npm install intlayer svelte-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer: 핵심 i18n 패키지입니다.
    • svelte-intlayer: Svelte/SvelteKit용 컨텍스트 제공자와 스토어를 제공합니다.
    • vite-intlayer: 콘텐츠 선언을 빌드 프로세스와 통합하는 Vite 플러그인입니다.

    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;

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

    vite.config.ts 파일을 업데이트하여 Intlayer 플러그인을 포함하세요. 이 플러그인은 콘텐츠 파일의 트랜스파일을 처리합니다.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

    import { sveltekit } from "@sveltejs/kit/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [intlayer(), sveltekit()], // 순서가 중요하며, Intlayer는 SvelteKit보다 먼저 위치해야 합니다.});

    4단계: 콘텐츠 선언하기

    src 폴더 내 어디에서든 콘텐츠 선언 파일을 생성하세요 (예: src/lib/content 또는 컴포넌트와 함께). 이 파일들은 각 로케일별로 t() 함수를 사용하여 애플리케이션의 번역 가능한 콘텐츠를 정의합니다.

    5단계: 컴포넌트에서 Intlayer 사용하기

    접두사를 사용해야 합니다 (예: $content.title).

    src/lib/components/Component.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">  import { useIntlayer } from "svelte-intlayer";  // "hero-section"은 4단계에서 정의한 키에 해당합니다.  const content = useIntlayer("hero-section");</script><!-- 간단한 콘텐츠로 렌더링 --><h1>{$content.title}</h1><!-- 에디터를 사용하여 편집 가능한 콘텐츠로 렌더링 --><h1>{@const Title = $content.title}<Title /></h1><!-- 콘텐츠를 문자열로 렌더링하기 --><div aria-label={$content.title.value}></div><div aria-label={$content.title.toString()}></div><div aria-label={String($content.title)}></div>

    (선택 사항) 6단계: 라우팅 설정하기

    다음 단계에서는 SvelteKit에서 로케일 기반 라우팅을 설정하는 방법을 보여줍니다. 이를 통해 URL에 로케일 접두사(e.g., /en/about, /fr/about)를 포함시켜 SEO 및 사용자 경험을 향상시킬 수 있습니다.

    bash
    코드 복사

    코드를 클립보드에 복사

    .└─── src    ├── app.d.ts                  # 로케일 타입 정의    ├── hooks.server.ts           # 로케일 라우팅 관리    ├── lib    │   └── getLocale.ts          # 헤더, 쿠키에서 로케일 확인    ├── params    │   └── locale.ts             # 로케일 파라미터 정의    └── routes        ├── [[locale=locale]]     # 로케일을 설정하기 위한 라우트 그룹 래핑        │   ├── +layout.svelte    # 경로에 대한 로컬 레이아웃        │   ├── +layout.ts        │   ├── +page.svelte        │   ├── +page.ts        │   └── about        │       ├── +page.svelte        │       └── +page.ts        └── +layout.svelte         # 폰트 및 전역 스타일을 위한 루트 레이아웃

    7단계: 서버 사이드 로케일 감지 처리 (Hooks)

    SvelteKit에서는 SSR 중에 올바른 콘텐츠를 렌더링하기 위해 서버가 사용자의 로케일을 알아야 합니다. 우리는 URL이나 쿠키에서 로케일을 감지하기 위해 hooks.server.ts를 사용합니다.

    src/hooks.server.ts 파일을 생성하거나 수정하세요:

    src/hooks.server.ts
    코드 복사

    코드를 클립보드에 복사

    import type { Handle } from "@sveltejs/kit";import { getLocalizedUrl } from "intlayer";import { getLocale } from "$lib/getLocale";export const handle: Handle = async ({ event, resolve }) => {  const detectedLocale = getLocale(event);  // 현재 경로가 이미 로케일로 시작하는지 확인 (예: /fr, /en)  const pathname = event.url.pathname;  const targetPathname = getLocalizedUrl(pathname, detectedLocale);  // URL에 로케일이 없으면 (예: 사용자가 "/" 방문 시) 리다이렉트  if (targetPathname !== pathname) {    return new Response(undefined, {      headers: { Location: targetPathname },      status: 307, // 임시 리다이렉트    });  }  return resolve(event, {    transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),  });};

    그런 다음, 요청 이벤트에서 사용자의 로케일을 가져오는 헬퍼를 만듭니다:

    src/lib/getLocale.ts
    코드 복사

    코드를 클립보드에 복사

    import {  configuration,  getLocaleFromStorage,  localeDetector,  type Locale,} from "intlayer";import type { RequestEvent } from "@sveltejs/kit";/** * 요청 이벤트에서 사용자의 로케일을 가져옵니다. * 이 함수는 `src/hooks.server.ts`의 `handle` 훅에서 사용됩니다. * * 먼저 Intlayer 저장소(쿠키 또는 커스텀 헤더)에서 로케일을 가져오려고 시도합니다. * 로케일을 찾지 못하면 브라우저의 "Accept-Language" 협상으로 대체합니다. * * @param event - SvelteKit의 요청 이벤트 * @returns 사용자의 로케일 */export const getLocale = (event: RequestEvent): Locale => {  const defaultLocale = configuration?.internationalization?.defaultLocale;  // Intlayer 저장소(쿠키 또는 헤더)에서 로케일을 가져오려고 시도  const storedLocale = getLocaleFromStorage({    // SvelteKit 쿠키 접근    getCookie: (name: string) => event.cookies.get(name) ?? null,    // SvelteKit 헤더 접근    getHeader: (name: string) => event.request.headers.get(name) ?? null,  });  if (storedLocale) {    return storedLocale;  }  // 브라우저 "Accept-Language" 협상으로 대체  const negotiatorHeaders: Record<string, string> = {};  // SvelteKit Headers 객체를 일반 Record<string, string>으로 변환  event.request.headers.forEach((value, key) => {    negotiatorHeaders[key] = value;  });  // `Accept-Language` 헤더에서 로케일 확인  const userFallbackLocale = localeDetector(negotiatorHeaders);  if (userFallbackLocale) {    return userFallbackLocale;  }  // 일치하는 로케일이 없으면 기본 로케일 반환  return defaultLocale;};
    getLocaleFromStorage는 구성에 따라 헤더 또는 쿠키에서 로케일을 확인합니다. 자세한 내용은 Configuration 문서를 참조하세요.
    localeDetector 함수는 Accept-Language 헤더를 처리하여 가장 적합한 로케일을 반환합니다.

    로케일이 구성되지 않은 경우 404 오류를 반환하고자 합니다. 이를 쉽게 하기 위해 로케일이 유효한지 확인하는 match 함수를 만들 수 있습니다:

    /src/params/locale.ts
    코드 복사

    코드를 클립보드에 복사

    export const match = (param: Locale = defaultLocale): boolean =>  locales.includes(param);

    참고: src/app.d.ts 파일에 로케일 정의가 포함되어 있는지 확인하세요:

    typescript
    코드 복사

    코드를 클립보드에 복사

    declare global {  namespace App {    interface Locals {      locale: import("intlayer").Locale;    }  }}

    +layout.svelte 파일에서는 i18n과 관련 없는 정적 콘텐츠만 남기고 모든 내용을 제거할 수 있습니다:

    src/+layout.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">     import './layout.css';    let { children } = $props();</script><div class="app">    {@render children()}</div><style>    .app {    /*  */    }</style>

    그런 다음, [[locale=locale]] 그룹 아래에 새 페이지와 레이아웃을 생성합니다:

    src/routes/[[locale=locale]]/+layout.ts
    코드 복사

    코드를 클립보드에 복사

    import type { Load } from "@sveltejs/kit";import { defaultLocale, type Locale } from "intlayer";export const prerender = true;// 제네릭 Load 타입 사용export const load: Load = ({ params }) => {  const locale: Locale = (params.locale as Locale) ?? defaultLocale;  return {    locale,  };};
    src/routes/[[locale=locale]]/+layout.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">    import type { Snippet } from 'svelte';    import { useIntlayer, setupIntlayer } from "svelte-intlayer";    import Header from './Header.svelte';    import type { LayoutData } from './$types';    let { children, data }: { children: Snippet, data: LayoutData } = $props();    // 경로에서 로케일로 Intlayer 초기화  $effect(() => {      setupIntlayer(data.locale);  });    // 레이아웃 콘텐츠 사전 사용    const layoutContent = useIntlayer('layout');</script><Header /><main>    {@render children()}</main><footer>    <p>        {$layoutContent.footer.prefix.value}{' '}        <a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}        {$layoutContent.footer.suffix.value}    </p></footer><style>  /*  */</style>
    src/routes/[[locale=locale]]/+page.ts
    코드 복사

    코드를 클립보드에 복사

    export const prerender = true;
    src/routes/[[locale=locale]]/+page.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">    import { useIntlayer } from "svelte-intlayer";    // 홈 콘텐츠 사전을 사용합니다    const homeContent = useIntlayer('home');</script><svelte:head>    <title>{$homeContent.title.value}</title></svelte:head><section>    <h1>        {$homeContent.title}    </h1></section><style>  /*  */</style>

    (선택 사항) 8단계: 국제화된 링크

    SEO를 위해 경로에 로케일 접두사를 붙이는 것이 권장됩니다(예: /en/about, /fr/about). 이 컴포넌트는 현재 로케일로 모든 링크에 자동으로 접두사를 붙입니다.

    src/lib/components/LocalizedLink.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">  import { getLocalizedUrl } from "intlayer";  import { useLocale } from "svelte-intlayer";  let { href = "" } = $props();  const { locale } = useLocale();  // 현재 로케일로 URL에 접두사를 붙이는 헬퍼  $: localizedHref = getLocalizedUrl(href, $locale);</script><a href={localizedHref}>  <slot /></a>

    SvelteKit의 goto를 사용하는 경우, getLocalizedUrl과 같은 로직을 사용하여 로컬라이즈된 URL로 이동할 수 있습니다:

    typescript
    코드 복사

    코드를 클립보드에 복사

    import { goto } from "$app/navigation";import { getLocalizedUrl } from "intlayer";import { useLocale } from "svelte-intlayer";const { locale } = useLocale();const localizedPath = getLocalizedUrl("/about", $locale);goto(localizedPath); // 로케일에 따라 /en/about 또는 /fr/about로 이동합니다.

    (선택 사항) 9단계: 언어 전환기

    사용자가 언어를 전환할 수 있도록 URL을 업데이트합니다.

    src/lib/components/LanguageSwitcher.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">  import { getLocalizedUrl, getLocaleName } from 'intlayer';  import { useLocale } from "svelte-intlayer";  import { page } from '$app/stores';  import { goto } from '$app/navigation';  const { locale, setLocale, availableLocales } = useLocale({    onLocaleChange: (newLocale) => {      const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);      goto(localizedPath);    },  });</script><ul class="locale-list">  {#each availableLocales as localeEl}    <li>      <a        href={getLocalizedUrl($page.url.pathname, localeEl)}        onclick={(e) => {          e.preventDefault();          setLocale(localeEl); // 스토어에 로케일을 설정하고 onLocaleChange를 트리거합니다        }}        class:active={$locale === localeEl}      >        {getLocaleName(localeEl)}      </a>    </li>  {/each}</ul><style>  /* */</style>

    (선택 사항) 10단계: 백엔드 프록시 추가

    SvelteKit 애플리케이션에 백엔드 프록시를 추가하려면 vite-intlayer 플러그인이 제공하는 intlayerProxy 함수를 사용할 수 있습니다. 이 플러그인은 URL, 쿠키 및 브라우저 언어 설정을 기반으로 사용자에게 가장 적합한 로케일을 자동으로 감지합니다.

    vite.config.ts
    코드 복사

    코드를 클립보드에 복사

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

    (선택 사항) 11단계: intlayer 에디터 / CMS 설정하기

    intlayer 에디터를 설정하려면 intlayer 에디터 문서를 따라야 합니다.

    intlayer CMS를 설정하려면 intlayer CMS 문서를 따라야 합니다.

    intlayer 에디터 선택기를 시각화하려면 intlayer 콘텐츠에서 컴포넌트 구문을 사용해야 합니다.

    Component.svelte
    코드 복사

    코드를 클립보드에 복사

    <script lang="ts">  import { useIntlayer } from "svelte-intlayer";  const content = useIntlayer("component");</script><div>  <!-- 간단한 콘텐츠로 렌더링 -->  <h1>{$content.title}</h1>  <!-- 컴포넌트로 렌더링 (에디터에서 필요) -->  {@const Component = $content.component}<Component /></div>

    Git 구성

    Intlayer가 생성한 파일은 무시하는 것이 권장됩니다.

    .gitignore
    코드 복사

    코드를 클립보드에 복사

    # Intlayer가 생성한 파일 무시.intlayer

    (선택 사항) 단계 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

    더 나아가기

    • 비주얼 에디터: UI에서 직접 번역을 편집할 수 있도록 Intlayer 비주얼 에디터를 통합하세요.
    • CMS: Intlayer CMS를 사용하여 콘텐츠 관리를 외부화하세요.
    Vite 및 Svelte
    Vite 및 Preact

    Alt+→

    이 페이지에서

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

      .├── intlayer.config.ts├── package.json├── src│   ├── app.d.ts│   ├── app.html│   ├── hooks.server.ts│   ├── lib│   │   ├── getLocale.ts│   │   ├── LocaleSwitcher.svelte│   │   └── LocalizedLink.svelte│   ├── params│   │   └── locale.ts│   └── routes│       ├── [[locale=locale]]│       │   ├── +layout.svelte│       │   ├── +layout.ts│       │   ├── +page.svelte│       │   ├── +page.ts│       │   ├── about│       │   │   ├── +page.svelte│       │   │   ├── +page.ts│       │   │   └── page.content.ts│       │   ├── Counter.content.ts│       │   ├── Counter.svelte│       │   ├── Header.content.ts│       │   ├── Header.svelte│       │   ├── home.content.ts│       │   └── layout.content.ts│       ├── +layout.svelte│       └── layout.css├── static│   ├── favicon.svg│   └── robots.txt├── svelte.config.js├── tsconfig.json└── vite.config.ts
      npm install intlayer svelte-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },};export default config;
      import { sveltekit } from "@sveltejs/kit/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [intlayer(), sveltekit()], // 순서가 중요하며, Intlayer는 SvelteKit보다 먼저 위치해야 합니다.});
      .├── intlayer.config.ts├── package.json├── src│   ├── app.d.ts│   ├── app.html│   ├── hooks.server.ts│   ├── lib│   │   ├── getLocale.ts│   │   ├── LocaleSwitcher.svelte│   │   └── LocalizedLink.svelte│   ├── params│   │   └── locale.ts│   └── routes│       ├── [[locale=locale]]│       │   ├── +layout.svelte│       │   ├── +layout.ts│       │   ├── +page.svelte│       │   ├── +page.ts│       │   ├── about│       │   │   ├── +page.svelte│       │   │   ├── +page.ts│       │   │   └── page.content.ts│       │   ├── Counter.content.ts│       │   ├── Counter.svelte│       │   ├── Header.content.ts│       │   ├── Header.svelte│       │   ├── home.content.ts│       │   └── layout.content.ts│       ├── +layout.svelte│       └── layout.css├── static│   ├── favicon.svg│   └── robots.txt├── svelte.config.js├── tsconfig.json└── vite.config.ts
      npm install intlayer svelte-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },};export default config;
      import { sveltekit } from "@sveltejs/kit/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [intlayer(), sveltekit()], // 순서가 중요하며, Intlayer는 SvelteKit보다 먼저 위치해야 합니다.});
      <script lang="ts">  import { useIntlayer } from "svelte-intlayer";  // "hero-section"은 4단계에서 정의한 키에 해당합니다.  const content = useIntlayer("hero-section");</script><!-- 간단한 콘텐츠로 렌더링 --><h1>{$content.title}</h1><!-- 에디터를 사용하여 편집 가능한 콘텐츠로 렌더링 --><h1>{@const Title = $content.title}<Title /></h1><!-- 콘텐츠를 문자열로 렌더링하기 --><div aria-label={$content.title.value}></div><div aria-label={$content.title.toString()}></div><div aria-label={String($content.title)}></div>
      .└─── src    ├── app.d.ts                  # 로케일 타입 정의    ├── hooks.server.ts           # 로케일 라우팅 관리    ├── lib    │   └── getLocale.ts          # 헤더, 쿠키에서 로케일 확인    ├── params    │   └── locale.ts             # 로케일 파라미터 정의    └── routes        ├── [[locale=locale]]     # 로케일을 설정하기 위한 라우트 그룹 래핑        │   ├── +layout.svelte    # 경로에 대한 로컬 레이아웃        │   ├── +layout.ts        │   ├── +page.svelte        │   ├── +page.ts        │   └── about        │       ├── +page.svelte        │       └── +page.ts        └── +layout.svelte         # 폰트 및 전역 스타일을 위한 루트 레이아웃
      import type { Handle } from "@sveltejs/kit";import { getLocalizedUrl } from "intlayer";import { getLocale } from "$lib/getLocale";export const handle: Handle = async ({ event, resolve }) => {  const detectedLocale = getLocale(event);  // 현재 경로가 이미 로케일로 시작하는지 확인 (예: /fr, /en)  const pathname = event.url.pathname;  const targetPathname = getLocalizedUrl(pathname, detectedLocale);  // URL에 로케일이 없으면 (예: 사용자가 "/" 방문 시) 리다이렉트  if (targetPathname !== pathname) {    return new Response(undefined, {      headers: { Location: targetPathname },      status: 307, // 임시 리다이렉트    });  }  return resolve(event, {    transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),  });};
      import {  configuration,  getLocaleFromStorage,  localeDetector,  type Locale,} from "intlayer";import type { RequestEvent } from "@sveltejs/kit";/** * 요청 이벤트에서 사용자의 로케일을 가져옵니다. * 이 함수는 `src/hooks.server.ts`의 `handle` 훅에서 사용됩니다. * * 먼저 Intlayer 저장소(쿠키 또는 커스텀 헤더)에서 로케일을 가져오려고 시도합니다. * 로케일을 찾지 못하면 브라우저의 "Accept-Language" 협상으로 대체합니다. * * @param event - SvelteKit의 요청 이벤트 * @returns 사용자의 로케일 */export const getLocale = (event: RequestEvent): Locale => {  const defaultLocale = configuration?.internationalization?.defaultLocale;  // Intlayer 저장소(쿠키 또는 헤더)에서 로케일을 가져오려고 시도  const storedLocale = getLocaleFromStorage({    // SvelteKit 쿠키 접근    getCookie: (name: string) => event.cookies.get(name) ?? null,    // SvelteKit 헤더 접근    getHeader: (name: string) => event.request.headers.get(name) ?? null,  });  if (storedLocale) {    return storedLocale;  }  // 브라우저 "Accept-Language" 협상으로 대체  const negotiatorHeaders: Record<string, string> = {};  // SvelteKit Headers 객체를 일반 Record<string, string>으로 변환  event.request.headers.forEach((value, key) => {    negotiatorHeaders[key] = value;  });  // `Accept-Language` 헤더에서 로케일 확인  const userFallbackLocale = localeDetector(negotiatorHeaders);  if (userFallbackLocale) {    return userFallbackLocale;  }  // 일치하는 로케일이 없으면 기본 로케일 반환  return defaultLocale;};
      export const match = (param: Locale = defaultLocale): boolean =>  locales.includes(param);
      declare global {  namespace App {    interface Locals {      locale: import("intlayer").Locale;    }  }}
      <script lang="ts">     import './layout.css';    let { children } = $props();</script><div class="app">    {@render children()}</div><style>    .app {    /*  */    }</style>
      import type { Load } from "@sveltejs/kit";import { defaultLocale, type Locale } from "intlayer";export const prerender = true;// 제네릭 Load 타입 사용export const load: Load = ({ params }) => {  const locale: Locale = (params.locale as Locale) ?? defaultLocale;  return {    locale,  };};
      <script lang="ts">    import type { Snippet } from 'svelte';    import { useIntlayer, setupIntlayer } from "svelte-intlayer";    import Header from './Header.svelte';    import type { LayoutData } from './$types';    let { children, data }: { children: Snippet, data: LayoutData } = $props();    // 경로에서 로케일로 Intlayer 초기화  $effect(() => {      setupIntlayer(data.locale);  });    // 레이아웃 콘텐츠 사전 사용    const layoutContent = useIntlayer('layout');</script><Header /><main>    {@render children()}</main><footer>    <p>        {$layoutContent.footer.prefix.value}{' '}        <a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}        {$layoutContent.footer.suffix.value}    </p></footer><style>  /*  */</style>
      export const prerender = true;
      <script lang="ts">    import { useIntlayer } from "svelte-intlayer";    // 홈 콘텐츠 사전을 사용합니다    const homeContent = useIntlayer('home');</script><svelte:head>    <title>{$homeContent.title.value}</title></svelte:head><section>    <h1>        {$homeContent.title}    </h1></section><style>  /*  */</style>
      <script lang="ts">  import { getLocalizedUrl } from "intlayer";  import { useLocale } from "svelte-intlayer";  let { href = "" } = $props();  const { locale } = useLocale();  // 현재 로케일로 URL에 접두사를 붙이는 헬퍼  $: localizedHref = getLocalizedUrl(href, $locale);</script><a href={localizedHref}>  <slot /></a>
      import { goto } from "$app/navigation";import { getLocalizedUrl } from "intlayer";import { useLocale } from "svelte-intlayer";const { locale } = useLocale();const localizedPath = getLocalizedUrl("/about", $locale);goto(localizedPath); // 로케일에 따라 /en/about 또는 /fr/about로 이동합니다.
      <script lang="ts">  import { getLocalizedUrl, getLocaleName } from 'intlayer';  import { useLocale } from "svelte-intlayer";  import { page } from '$app/stores';  import { goto } from '$app/navigation';  const { locale, setLocale, availableLocales } = useLocale({    onLocaleChange: (newLocale) => {      const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);      goto(localizedPath);    },  });</script><ul class="locale-list">  {#each availableLocales as localeEl}    <li>      <a        href={getLocalizedUrl($page.url.pathname, localeEl)}        onclick={(e) => {          e.preventDefault();          setLocale(localeEl); // 스토어에 로케일을 설정하고 onLocaleChange를 트리거합니다        }}        class:active={$locale === localeEl}      >        {getLocaleName(localeEl)}      </a>    </li>  {/each}</ul><style>  /* */</style>
      import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";import { sveltekit } from "@sveltejs/kit/vite";// https://vitejs.dev/config/export default defineConfig({  plugins: [    intlayerProxy(), // should be placed first    intlayer(),    sveltekit(),  ],],});
      <script lang="ts">  import { useIntlayer } from "svelte-intlayer";  const content = useIntlayer("component");</script><div>  <!-- 간단한 콘텐츠로 렌더링 -->  <h1>{$content.title}</h1>  <!-- 컴포넌트로 렌더링 (에디터에서 필요) -->  {@const Component = $content.component}<Component /></div>
      # 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