# node: Подходы к переводу строк URL: https://generaltranslation.com/ru/docs/node/guides/strings.mdx --- title: Подходы к переводу строк description: Два подхода к переводу строк в Node.js — инлайн и с предварительно зарегистрированными строками --- В `gt-node` есть три способа переводить строки: 1. **Инлайн через `getGT()`** — переводите строки прямо в обработчиках запросов (этап сборки) 2. **С предварительно зарегистрированными строками через `msg()` / `getMessages()`** — определяйте строки на уровне модуля и разрешайте их во время выполнения (этап сборки) 3. **По запросу через `tx()`** — переводите строки во время выполнения, включая контент, неизвестный на этапе сборки ## Инлайн-перевод с `getGT()` Используйте [`getGT()`](/docs/node/api/get-gt), когда строка используется только в одном месте или когда контент зависит от данных конкретного запроса: ```js title="routes/greeting.js" import { getGT } from 'gt-node'; app.get('/api/greeting', async (req, res) => { const gt = await getGT(); res.json({ message: gt('Hello, world!'), }); }); ``` ### Интерполяция переменных Передавайте переменные во втором аргументе, используя заполнители `{name}`: ```js const gt = await getGT(); gt('Welcome, {name}!', { name: user.displayName }); gt('You have {count} new messages.', { count: unreadCount }); gt('{city} weather: {temp}°F', { city: 'Tokyo', temp: 72 }); ``` ## Предварительно зарегистрированные строки с `msg()` / `getMessages()` Используйте [`msg()`](/docs/node/api/get-messages), чтобы регистрировать строки на уровне модуля — вне обработчиков запросов. Затем используйте [`getMessages()`](/docs/node/api/get-messages) внутри обработчиков, чтобы преобразовывать их в строки для текущей локали: ```js title="messages.js" import { msg } from 'gt-node'; export const GREETING = msg('Hello, world!'); export const WELCOME = msg('Welcome, {name}!'); export const NOT_FOUND = msg('Resource not found.'); export const UNAUTHORIZED = msg('You must be logged in.'); ``` ```js title="routes/api.js" import { getMessages } from 'gt-node'; import { GREETING, WELCOME, NOT_FOUND } from './messages.js'; app.get('/api/greeting', async (req, res) => { const m = await getMessages(); res.json({ greeting: m(GREETING), welcome: m(WELCOME, { name: 'Alice' }), }); }); app.use(async (req, res) => { const m = await getMessages(); res.status(404).json({ error: m(NOT_FOUND) }); }); ``` Этот подход лучше всего использовать, когда: * Одна и та же строка используется в нескольких обработчиках * Строки вынесены в общие константы (сообщения об ошибках, метки, перечисления) * Вы хотите держать все переводимые строки в одном файле, чтобы их было проще проверять ## Перевод по запросу с `tx()` Используйте [`tx()`](/docs/node/api/strings/tx), если контент неизвестен на этапе сборки — например, это контент, созданный пользователями, или динамические данные, которые нельзя перевести заранее: ```js title="routes/translate.js" import { tx } from 'gt-node'; app.post('/api/translate', async (req, res) => { const translated = await tx(req.body.text); res.json({ translated }); }); ``` `tx` работает асинхронно и выполняет перевод по запросу через сеть, поэтому он медленнее, чем подходы на этапе сборки. Используйте его только в тех случаях, когда `getGT()` или `msg()` не покрывают этот сценарий использования. ## Что и когда использовать | Подход | Лучше всего подходит для | | ------------------------- | ----------------------------------------------------------------------------------------------------- | | `getGT()` | Разовых строк, содержимого для конкретного запроса, строк, используемых только в одном обработчике | | `msg()` / `getMessages()` | Общих констант, сообщений об ошибках, меток enum, централизованного управления строками | | `tx()` | Динамического контента или содержимого, созданного пользователями, которое неизвестно на этапе сборки | Оба подхода дают одинаковый результат перевода. Разница только в организации кода — выберите тот, который лучше подходит под структуру вашего проекта. ## Использование `$context` для снятия неоднозначности Неоднозначные строки могут приводить к неточным переводам. Добавьте `$context`, чтобы помочь переводчику правильно понять смысл: ```js // Инлайн const gt = await getGT(); gt('Apple', { $context: 'технологическая компания' }); gt('Spring', { $context: 'время года, а не пружина' }); // Предварительно зарегистрированный const APPLE = msg('Apple', { $context: 'фрукт' }); const SPRING = msg('Spring', { $context: 'металлическая пружина' }); ``` ## Полный пример ```js title="server.js" import express from 'express'; import { initializeGT, withGT, getGT, msg, getMessages } from 'gt-node'; initializeGT({ defaultLocale: 'en', locales: ['en', 'es', 'fr', 'ja'], projectId: process.env.GT_PROJECT_ID, }); // Предварительная регистрация общих строк const ERRORS = { notFound: msg('Resource not found.'), unauthorized: msg('You must be logged in.'), forbidden: msg('You do not have permission to access this resource.'), }; const app = express(); app.use((req, res, next) => { const locale = req.headers['accept-language']?.split(',')[0] || 'en'; withGT(locale, () => next()); }); // Инлайн-перевод app.get('/api/dashboard', async (req, res) => { const gt = await getGT(); res.json({ title: gt('Dashboard'), subtitle: gt('Welcome back, {name}!', { name: req.user.name }), }); }); // Предварительно зарегистрированные сообщения app.use(async (req, res) => { const m = await getMessages(); res.status(404).json({ error: m(ERRORS.notFound) }); }); app.listen(3000); ``` ## Следующие шаги * [`getGT` справка по API](/docs/node/api/get-gt) * [`msg` и `getMessages` справка по API](/docs/node/api/get-messages) * [`tx` справка по API](/docs/node/api/strings/tx) — перевод во время выполнения * [Определение локали и middleware](/docs/node/guides/middleware) — как работает контекст локали