langsys-js-typescript 위에 얹은 얇은 Vue 3 바인딩으로, 기본 시그널을 shallowRef로 연결하는 컴포저블을 기반으로 만들어졌습니다. 코드에 작성한 문구는 조회 키이자 기본 언어의 기본값 역할을 합니다.

AI 코딩 에이전트를 사용 중이신가요? 이 프롬프트를 전달해 보세요
Add Langsys translation to this Vue app.

1. Read https://docs.langsys.dev/llms.txt, then follow
   https://docs.langsys.dev/learn/sdk/vue/ for the install and setup.
2. The English text in the code is the translation key. Wrap user-facing
   strings as they are: no keys file, no extraction step, and no
   hand-written plural or gender branches (Langsys generates those).
3. Read the Langsys project id and API key from environment variables.
   The write key is for development and servers only; anything shipped
   to the browser gets the read-only key.
4. Keep brand names and user-generated content out of translation.

설치

npm install langsys-js-vue

아직 프로젝트나 키가 없으신가요? 빠른 시작으로 2분이면 둘 다 준비할 수 있습니다.

초기화

import { LangsysApp, createLocaleStore } from 'langsys-js-vue';

const locale = createLocaleStore('en-US');

await LangsysApp.init({
  projectid: import.meta.env.VITE_LANGSYS_PROJECT_ID,
  key: import.meta.env.VITE_LANGSYS_API_KEY, // read-only in the browser
  UserLocaleStore: locale,
});

시그널 읽기

로케일 스토어나 Vue 밖에서 공유하는 스토어와 같은 기본 SDK 시그널을 반응형으로 읽어야 하나요? useSignal(store)가 이를 Vue가 추적할 수 있는 shallowRef로 연결해 줍니다. (Svelte에는 별도의 장치가 필요 없습니다. 시그널이 Svelte의 스토어 규약을 기본적으로 충족하기 때문입니다.)

<script setup>
import { useSignal, useCurrentLocale } from 'langsys-js-vue';

// Vue tracks only its own refs — a base-SDK signal is invisible to it.
// useSignal(signal) bridges it into a shallowRef Vue can track.
const selected = useSignal(locale);   // your createLocaleStore(...)
const loaded = useCurrentLocale();    // shortcut for the loaded locale
</script>

<template>
  <footer>selected {{ selected }} · loaded {{ loaded }}</footer>
</template>

인터랙티브 플레이그라운드

문구와 카테고리를 수정하고 매개변수를 필드 또는 원시 JSON으로 설정한 다음, 로케일을 전환해 실제 SDK가 실시간으로 번역하는 모습을 확인해 보세요.

예시
매개변수
Output

Hello, Sarah! You have 3 new messages.

const t = useT();

<p>{{ t("Hello, {name}! You have {count} new messages.", "Greetings", {"name":"Sarah","count":3}) }}</p>
t() — 컴포넌트 안의 인라인 문자열 소스 보기 ↗
<script setup>
import { useT } from 'langsys-js-vue';
const t = useT();
const name = 'Sarah';
</script>

<template>
  <p>{{ t('Hello, {name}!', 'Greetings', { name }) }}</p>
</template>

어떤 것을 사용해야 하나요?

번역 중입니다… 사용 이유
코드 속 일반 문자열로, 라벨, 제목, 메시지 등이 해당됩니다. 매개변수도 포함되며, 수량은 단순하게 작성하면 Langsys가 복수형을 생성합니다. useT() 문자열을 반환합니다. 코드에 작성한 문구는 조회 키이자 기본 언어의 기본값입니다.
인라인 마크업이나 동적 값이 포함된 한 문장을 나누지 않고 그대로 유지합니다. <Phrase> 인라인 요소는 중립적인 토큰으로 바뀌므로 번역가는 마크업 위치를 포함해 문장 전체의 순서를 바꿀 수 있고, 실제 요소는 렌더링 시점에 다시 복원됩니다.
히어로, 푸터, 카드처럼 여러 문구가 들어 있는 마크업 영역. <Translate> 태그 하나로 해당 영역을 단일 콘텐츠 블록으로 등록합니다. 모든 텍스트 구간이 각각 하나의 문구로 추출되며 마크업 구조는 그대로 유지됩니다.
절대 번역되면 안 되는 내용 — 브랜드명, 코드, ID. <DontTranslate> 토크나이저와 렌더러는 해당 하위 트리를 건너뛰므로, 주변 문장이 번역되는 동안에도 그 부분은 원문 그대로 유지됩니다.

간단한 기준: 문자열 → useT() · 마크업이 포함된 문장 → <Phrase> · 마크업 영역 → <Translate> · 건드리면 안 되는 부분 → <DontTranslate>.

왼쪽에는 각 콘텐츠 컴포넌트가 실시간으로 렌더링되고, 오른쪽에는 이를 만드는 코드가 표시됩니다.

시청하기 이 기본 요소들의 데모 영상은 현재 Svelte 페이지에 있습니다. 사용 방식은 동일하고 구문만 다릅니다. <Translate> (1:04) · <Phrase> (1:06) · <DontTranslate> (0:34).

<Translate> — content block

Welcome to our store

Browse the catalog in your language.

<Translate> — 콘텐츠 블록 소스 보기 ↗
<script setup>
import { Translate } from 'langsys-js-vue';
</script>

<template>
  <Translate category="Home">
    <h3>Welcome to our store</h3>
    <p>Browse the catalog in your language.</p>
  </Translate>
</template>

<Phrase> — params & markup

Hi %name%, you have %count% items in your cart.
<Phrase> — 매개변수 및 마크업 (%name%) 소스 보기 ↗
<Phrase category="Cart" :params="{ name: 'Sarah', count: 3 }">
  Hi %name%, you have %count% items in your cart.
</Phrase>

<DontTranslate> — never translated

Welcome! This sentence always stays in English. Thanks for visiting!

<DontTranslate> 소스 보기 ↗
<!-- Inside a translated region, the marked span alone stays verbatim. -->
<Translate category="Tour">
  <p>Welcome! <DontTranslate>This sentence always stays in English.</DontTranslate> Thanks for visiting!</p>
</Translate>

성 일치

스페인어, 프랑스어, 러시아어는 {username} has been invited을(를) 대상 인물에 맞춰 활용합니다. Langsys는 복수형을 생성하는 것과 같은 방식으로 번역 중에 이러한 분기를 생성하며, 인수 이름은 변수 이름 뒤에 _gender를 붙인 형태이고 값은 male, female, other 중 하나입니다. 알고 있다면 항상 전달하세요. 작동 방식과 이 값이 필요한 문구를 찾는 방법 →

성별 인수 전달하기
<script setup>
import { useT } from 'langsys-js-vue';
const props = defineProps({ user: Object });
const t = useT();
</script>

<template>
  <!-- Pass the agreement argument alongside the value it inflects.
       user.gender is 'male' | 'female' | 'other'. -->
  <p>{{ t('{username} has been invited', 'Team',
       { username: props.user.name, username_gender: props.user.gender }) }}</p>
</template>

성별을 모르시나요? 'other'를 명시적으로 전달하세요. 중립 분기입니다. 그래도 값이 누락되면 SDK가 대신 other 분기를 선택하므로(langsys-js-typescript 0.6.4 이상) 문장은 여전히 자연스럽게 표시됩니다. 현재 TypeScript는 인라인 params 객체에 있는 username_gender를 거부합니다(오류 TS2353, 수정 사항 검토 중). 수정본이 배포되기 전까지는 params 객체를 먼저 만든 다음 해당 변수를 전달하세요.

서버 사이드 렌더링

서버(Nuxt)에서 카탈로그를 가져와 클라이언트에 전달하면, SDK가 다시 가져오지 않고 시작할 수 있습니다. SDK는 브라우저에서 번역하므로, 서버에서 렌더링된 HTML은 SDK가 시작되기 전까지 기본 언어로 표시됩니다.

// Nuxt: the server plugin seeds the catalog, the client init reuses it.
LangsysApp.init({
  projectid, key,
  UserLocaleStore: locale,
  initialTranslations,        // fetched on the server
  initialTranslationsLocale,  // fetched on the server
  ssrTokenStrategy: 'client',
});
문서 및 학습 센터 검색