ЛокалізаціяІнтернаціоналізаціяШІ-переклад

Локалізація імейлів: як перекладати кампанії в усіх провідних ESP

У кожної платформи для розсилок свій підхід до роботи з мовами. Одні беруть переклад на себе, інші надають порожні слоти під локалі, а в одній вам доведеться прописувати умови вручну. Розповідаємо, як це влаштовано в Braze, Customer.io, Klaviyo, Mailchimp, Iterable та Brevo, і як перекласти текст, не зламавши Liquid-код.

Mariia Ivakhnenko
Mariia Ivakhnenko23 хв читання
На цій сторінці

Я займаюся lifecycle-маркетингом, тож чималу частину життя провів у редакторах кампаній. Локалізація імейлів — це те, що я постійно недооцінював. Переклад лендингу — це зрозуміле завдання зі сталою структурою. Переклад імейл-кампанії щоразу виглядає інакше залежно від інструмента, адже кожна платформа по-своєму визначає навіть те, що таке «мова».

Деякі платформи перекладають текст за вас. Інші — надають порожні слоти для локалей і очікують, що ви заповните їх самі. А одна взагалі змушує прописувати логіку розгалуження прямо в тілі листа. Та за всіма ними криється одна й та сама небезпека: ваш текст рясніє синтаксисом шаблонів, який має повернутися з перекладу недоторканим, символ у символ, інакше розсилка просто зламається.

У цьому посібнику ми розберемося, як насправді працює кожна з провідних платформ, як витягнути й повернути текст, а також які етапи роботи залишаються незмінними для всіх.

Три способи, як імейл-платформи працюють з мовами

Перш ніж переходити до розбору конкретних сервісів, варто зрозуміти, з яким із трьох типів архітектури ви маєте справу. Від цього залежить увесь ваш робочий процес, а змінити цей підхід зазвичай неможливо.

АрхітектураЩо надає платформаЩо надаєте виПлатформи
Вона перекладає за васМашинний переклад у редакторі, створення мовних варіантів на основі версії за замовчуваннямПеревірка, правки та список слів, які не потрібно перекладатиKlaviyo, Customer.io, Brevo
Надає слоти для локалейТегований контент, структура для варіантів, обмін даними через CSV або APIСамі перекладиBraze, Iterable
Вона нічого не надаєМердж-теги та умовиУвесь контент, прописаний як логіка розгалуження в тілі листаMailchimp

У середньому рядку опиняється більшість серйозних мультимовних програм, і саме йому в цьому посібнику приділено найбільше уваги. Адже коли «платформа надає вам порожню сітку локалей», без налагодженого робочого процесу вже не обійтися.

Локалізація листів у Braze

Braze працює за моделлю «тегування та заповнення» і має чи не найунікальніший синтаксис серед усіх платформ. Кожен фрагмент листа, який потрібно перекласти, ви обгортаєте тегом Liquid з унікальним ID:

{% translation greeting %}Hello!{% endtranslation %}

Загальний формат виглядає так: {% translation your_id_here %}default text{% endtranslation %}, а ідентифікатори мають бути унікальними в межах одного повідомлення. Щоб швидко обгорнути виділений текст, скористайтеся комбінацією клавіш (Cmd+Alt+L для macOS або Ctrl+Alt+L для Windows). Braze не перекладає контент самостійно: ви надаєте готові переклади, завантажуючи CSV-файл або використовуючи API перекладів, який на момент написання цього посібника перебуває на стадії раннього доступу.

Документовані обмеження стають важливими, щойно справа доходить до реальних кампаній:

ОбмеженняЗначення
Тегів перекладу на повідомлення200
Символів на текст за замовчуванням2 000
Перекладів на локаль409 600 байтів (близько 409,6 КБ)
Локалей на робочий простір200

Вкладені теги перекладу не підтримуються. Локаль визначається за даними профілю користувача (налаштовується в розділі Settings → Localization Settings) на основі стандартних атрибутів language та country або ж кастомного атрибута; якщо вказані обидва, пріоритет надається кастомному атрибуту.

Перед початком роботи варто знати про дві особливості Braze:

Обгортання URL-адреси порушує відстеження кліків, якщо тільки фрагмент усередині не закінчується на ? або &. Braze наводить спосіб вирішення цієї проблеми безпосередньо в документації:

<a href="https://{% translation id_1 %}example.com{% endtranslation %}?">Shop Now</a>

Не відкривайте CSV-файл із перекладами в Excel. В офіційній документації Braze радять уникати цього через проблеми з відображенням неанглійських символів. Це найпоширеніша причина непомітного пошкодження даних локалізації в Braze, і винен у цьому Excel, а не сама платформа: він намагається вгадати кодування CSV-файлу і помиляється.

Контент-блоки у Braze можуть мати власні переклади — це дозволяє локалізувати спільний футер один раз для всіх кампаній. Посилайтеся на них як на {{content_blocks.${your_block}}}; блоки, вставлені за допомогою Liquid, залишаються пов’язаними й оновлюються автоматично, тоді як ті, що додані через випадне меню редактора, — ні. Якщо для певної локалі переклад блоку відсутній, він відображатиметься мовою оригіналу замість того, щоб видавати помилку.

Якщо ви віддаєте перевагу розгалуженню, а не тегуванню, Braze підтримує і такий ручний підхід:

{% if ${language} == 'en' %}
English content
{% elsif ${language} == 'es' %}
Spanish content
{% else %}
Fallback content
{% endif %}

Зверніть увагу: всередині тегу Liquid атрибут ${language} вказується без дужок, тоді як у самому тексті повідомлення він має бути обгорнутий: {{${language}}}. Braze радить завжди додавати гілку {% else %}, адже у деяких користувачів мова може бути не вказана, не підтримуватися або ж її неможливо визначити через налаштування пристрою.

Документація: Локалізація в Braze

Локалізація електронних листів у Customer.io

У Customer.io обрали протилежний підхід: локалізація тут нативна, вона інтегрована прямо в редактор повідомлень і має кнопку автоматичного ШІ-перекладу. Ви створюєте повідомлення мовою за замовчуванням і додаєте мовні варіанти без розгалуження кампанії. Це працює для email, SMS, WhatsApp, push-сповіщень та повідомлень у застосунку.

Назву атрибута мови ви обираєте самі. У розділі Workspace Settings → Language settings ви вказуєте Customer.io, який саме атрибут профілю містить дані про мову — це може бути language, locale або будь-який інший параметр, що вже використовується у вашій CRM. Значення мають бути або дволітерним кодом (en), або парою «мова-регіон», розділеною дефісом (en-US). Регістр не має значення, тому es-MX та es-mx працюватимуть однаково, проте дефіс є обов’язковим.

Автоматичний переклад охоплює текст повідомлення, теми та прехедери. А ось перелік того, що він не охоплює — і його варто виписати на видному місці:

  • Зображення (хоча alt-текст він перекладає)
  • Макети листів у редакторах rich-text та коду
  • Статичний текст Liquid, значення атрибутів та значення фільтрів
  • Сніпети
  • Текст кастомних компонентів, якщо тільки ви не від’єднаєте їх заздалегідь

Третій пункт заслуговує на окремий приклад, бо він найпідступніший. В офіційній документації Customer.io з локалізації наведено такий рядок:

Bonjour {{ customer.first_name | default:"ami" }}

Слово ami — це резервний варіант (fallback), який відображається всім, у кого в профілі не вказано ім’я. Це реальний текст, який бачать користувачі, і він міститься всередині фільтра Liquid, який автопереклад не чіпає. Якщо ви надішлете такий лист німецькій аудиторії, частина ваших отримувачів побачить привітання ami. Кожен резервний рядок у кожному фільтрі default: доводиться перекладати для кожного мовного варіанта вручну, і система ніяк про це не нагадає.

Ще два обмеження, які варто врахувати: переклади не оновлюються автоматично при зміні основного шаблону, а A/B-тести з перекладами працюють лише для одноразових розсилок, але не для автоматизацій чи розсилок, що запускаються через API.

Сніпети заслуговують на окрему згадку. Це механізм для повторного використання контенту ({{snippets.your_snippet}}, ліміт 16 КБ на кожен за замовчуванням), і автоматичний переклад їх ігнорує. Customer.io рекомендує прописувати умовні конструкції прямо всередині сніпета:

{% if customer.language == 'fr' %}
  Se désabonner
{% elsif customer.language == 'de' %}
  Abmelden
{% else %}
  Unsubscribe
{% endif %}

Тож зазвичай робота в Customer.io зводиться до створення нативних варіантів для текстів повідомлень та ручного налаштування умовних конструкцій у кожному спільному сніпеті. Про це варто знати, перш ніж припускати, що кнопка ШІ охоплює абсолютно все.

Документація: Локалізація в Customer.io

Локалізація листів у Klaviyo

Функція Klaviyo називається Smart Translations; вона автоматично перекладає вміст повідомлень на понад 60 мов безпосередньо в редакторі кампаній або ланцюжків (flows). Ви можете активувати її в меню Settings → Account → Translation за допомогою перемикача «Translate messages». Вона доступна лише для платних акаунтів і не пропонується у пробній версії.

У документації Klaviyo зазначено конкретний перелік елементів, що перекладаються автоматично: текстові блоки, мітки та альтернативний текст. Теми листів до цього списку не входять, тому обов’язково перевірте це у своєму акаунті, перш ніж вважати, що кампанія повністю охоплена перекладом.

Для визначення мови за замовчуванням система використовує поле Locale у профілі, а якщо воно відсутнє — поля Country або Language. Klaviyo підтримує коди BCP-47 (en-GB, es-ES), а також текстові значення на кшталт English або French.

Є дві речі, які роблять роботу з Klaviyo приємною. Перша — це список Do Not Translate: назви брендів, продуктів та будь-які терміни, які модель не повинна чіпати. Ви вказуєте їх один раз на рівні акаунта. Більшість платформ не мають аналогів цієї функції, хоча саме вона визначає, чи залишиться назва вашого продукту незмінною в десяти локалях, чи перетвориться на десять різних слів.

Друга — це меню індивідуального налаштування для кожного елемента. Для будь-якого перекладеного фрагмента доступні опції Re-translate, Match source, Edit та Ignore, а перемикатися між мовами можна за допомогою стрілок у верхній частині редактора. Це перетворює перевірку на швидкий перегляд позначених пунктів замість повного перечитування тексту.

Klaviyo також підтримує двосторонній обмін даними через CSV — це саме те, що вам потрібно, якщо ви залучаєте перекладачів або зовнішні інструменти. У меню Translate → actions доступна опція Export CSV у форматі Smartling або Simple. Колонки у файлі — це block_id (унікальний ідентифікатор для кожного рядка під переклад), source (оригінальний текст) та окремі колонки для кожної мови, названі відповідними кодами. Правила суворі й логічні: не редагуйте та не видаляйте значення block_id, не додавайте нові рядки та не змінюйте текст у колонці source.

Користувачів, які раніше працювали з Braze або Customer.io, часто дивує один факт: Klaviyo не використовує Liquid. Платформа базується на синтаксисі шаблонів Django.

{% if person|lookup:'Loyalty Points' > 150 %}
Hey VIP! You've always got free shipping & free returns
{% elif person|lookup:'Loyalty Points' > 0 %}
You have {{ person|lookup:'Loyalty Points' }} points, and you just need 150 to become a VIP!
{% else %}
Have you heard about our VIP program? Join today on our website to start earning rewards.
{% endif %}

Теги настільки схожі на Liquid, що їх легко сплутати, аж поки плутанина між elif та elsif не зіпсує вам пів дня. Персоналізація з резервним варіантом (fallback) виглядає так: {{ first_name|default:'friend' }}.

Документація: Smart Translations у Klaviyo · Синтаксис Django

Локалізація електронних листів у Mailchimp

Mailchimp не має вбудованої підтримки мультимовних кампаній. Натомість він пропонує умовні мерж-теги (conditional merge tags), а стандартний підхід полягає в тому, щоб вписати всі мовні версії в один лист, де умови самі виберуть потрібний контент.

*|IF:MC_LANGUAGE=es|*
Spanish content here.
*|ELSEIF:MC_LANGUAGE=de|*
German content here.
*|ELSE:|*
Display English content for everyone else.
*|END:IF|*

*|MC_LANGUAGE|* містить код мови контакту, а *|MC_LANGUAGE_LABEL|* — її зрозумілу назву. Mailchimp намагається визначити мову за браузером підписника; ви також можете вказати її вручну для кожного контакту в розділі profile → Settings → Language або масово під час імпорту. Майте на увазі, що *|END:IF|* закриває як блоки IF, так і IFNOT.

Саме це обмеження зазвичай стає вирішальним. Локалізований лист із темою не тією мовою втрачає шанси на відкриття ще до того, як його текст матиме значення. Тому більшість команд, які працюють у Mailchimp із понад двома мовами, зрештою все одно створюють окремі кампанії для кожної мови — і тоді підхід з умовними мерж-тегами виявляється марним. Про це варто знати ще на етапі планування, а не після того, як шаблон уже готовий.

Документація: Переклад контенту в Mailchimp

Локалізація електронних листів в Iterable

Iterable має повноцінну функцію локалей, а документація платформи напрочуд прямолінійно пояснює, що це насправді означає:

Локалі не перекладають контент.

Ви отримуєте структуру для варіантів, а переклади додаєте самі. Натомість усі варіанти мають спільний templateId, тому ваші метрики залишаються єдиними, а не розпорошуються між десятьма окремими шаблонами. Кожен, хто намагався скласти звіт за кампанією, розділеною на мовні копії, підтвердить: лише заради цього варто все налаштувати.

Поле має називатися виключно locale. Iterable прямо наголошує: якщо ви назвете його languagePreference або якось інакше, система не зможе зіставити користувачів із відповідними варіантами. Назви локалей відповідають стандартам ISO-639 та ISO-3166 (fr-CA, fr-FR); також підтримуються трилітерні коди. Оскільки локалі неможливо перейменувати після створення, краще визначитися зі схемою назв заздалегідь, поки ви не встигли наплодити їх зо два десятки. Якщо поле локалі порожнє, використовується локалізація за замовчуванням. У разі невідповідності система діє згідно з налаштуваннями на рівні проєкту: або пропускає надсилання, або відправляє версію за замовчуванням.

Iterable також прямо застерігає від використання власних обхідних шляхів:

Хоча Iterable — гнучка платформа, і ви можете створювати контент кількома мовами за допомогою Handlebars або Catalog, ці методи не вважаються найкращими практиками для локалізації.

Для шаблонів використовується Handlebars, а назви полів чутливі до регістру. Є один нюанс, на якому можна обпектися у візуальному редакторі (WYSIWYG): умовні конструкції потрібно обгортати в HTML-коментарі, інакше редактор їх пошкодить.

<!--{{#if activeUser}}-->
    <div>Hi active user!</div>
<!--{{else}}-->
    <div>Hi inactive user</div>
<!--{{/if}}-->

Для двостороннього обміну даними запит GET /api/templates/email/get дозволяє витягнути вміст шаблону для перекладачів.

Документація: Мультимовність в Iterable

Локалізація електронних листів у Brevo

Brevo належить до тих платформ, які пропонують вбудовані інструменти перекладу, і є найпрямішим конкурентом Mailchimp за цією конкретною функцією. Ви створюєте одну кампанію, яка адаптується до мови або коду країни контакту, натискаєте Add languages, і Brevo дублює кампанію для кожної мови, щоб ви могли перекласти її вручну або за допомогою Aura — вбудованого ШІ-помічника.

Можливості налаштування для кожної мови тут ширші, ніж зазвичай: можна змінювати ім’я відправника, тему листа, текст передперегляду та сам дизайн листа, а також адресу для відповіді, відстеження в Google Analytics і кастомну сторінку відписки. Можливість змінювати тему — найважливіша, адже це саме те, чого не вміє Mailchimp.

Задокументовані обмеження: переклади на основі файлів не підтримуються (отже, немає двостороннього обміну через CSV, що робить Brevo невідповідним вибором, якщо ви працюєте із зовнішніми бюро перекладів), функція не працює з A/B-тестами, а для кожної мови потрібно створювати окремі збережені розділи. Контакти, чий мовний атрибут не збігається з жодним із налаштованих варіантів, отримають версію за замовчуванням.

Документація: Мультимовні кампанії в Brevo

Liquid, Handlebars та мерж-теги: те, що має залишитися незмінним

Яку б платформу ви не використовували, сам етап перекладу має одну жорстку вимогу. Ваш текст містить синтаксис шаблонів, і кожен його символ має залишитися в точності таким, як у джерелі. Перекладений {% endif %} — це гарантована помилка під час надсилання.

Ось як виглядає синтаксис на різних платформах, згаданих у цьому посібнику:

ПлатформаМоваПерсоналізаціяУмовні оператори
BrazeLiquid{{${first_name}}}{% if %} / {% elsif %} / {% else %} / {% endif %}
Customer.ioLiquid{{customer.first_name}}{% if %} / {% elsif %} / {% else %} / {% endif %}
KlaviyoDjango{{ first_name }}{% if %} / {% elif %} / {% else %} / {% endif %}
MailchimpМерж-теги*|FNAME|**|IF:X|* / *|ELSEIF:X|* / *|ELSE:|* / *|END:IF|*
IterableHandlebars{{firstName}}{{#if}} / {{else}} / {{/if}}
BrevoМова шаблонів Brevo{{ contact.FIRSTNAME }}{% if %} / {% else %} / {% endif %}

Майже всі проблеми в цьому процесі зводяться до трьох основних сценаріїв збоїв.

Модель перекладає токен. Ви отримуєте {{ prénom }} або {% si %}, через що розсилка не спрацьовує або відображає технічний текст як є. Будь-який професійний інструмент маскує токени перед тим, як текст потрапить до моделі, і відновлює їх після цього — так модель навіть не сприймає їх як слова.

Модель переміщує токен. Порядок слів у різних мовах природним чином відрізняється, тому токен має змінити своє місце. Проблема виникає тоді, коли він потрапляє не в ту частину речення або коли {% if %} та {% endif %} опиняються в неправильному порядку. Позиція має значення; рішення полягає в тому, щоб перевіряти, чи збігається набір токенів на виході з тим, що був на вході, і перекладати блок заново, якщо вони не збігаються.

Змінюється кількість токенів. Найнебезпечніше — це втрата токена, адже лист усе одно відобразиться, але в ньому бракуватиме імені або цілої логічної гілки. Саме тому автоматичний підрахунок набагато важливіший за перевірку «на око».

І правило, що об’єднує всі три випадки: умовні гілки — це окремі рядки. У цьому рядку є два незалежні фрагменти тексту; якщо перекладач або модель отримає їх одним суцільним блоком, результат буде гіршим, ніж якби кожен із них подавався окремо з відповідним контекстом:

{% if ${loyalty_tier} == 'gold' %}Gold members get an extra 10%.{% else %}Join Gold for an extra 10%.{% endif %}

HTML-листи та таблиці рядків — це два різні завдання

На цьому шляху є роздоріжжя, яке визначає всю подальшу роботу, і зазвичай люди помічають його вже на півдорозі.

Деякий контент електронних листів — це документ: HTML-шаблон, готовий лист, щось зі структурою та логікою викладу, що читається зверху вниз. Ви хочете, щоб це перекладалося як зв’язний текст, оскільки заголовок і основний текст під ним нерозривно пов’язані, а перекладач, який бачить обидва елементи, приймає кращі рішення, ніж той, кому показують лише один із них.

Інший контент листів — це таблиця рядків: список із ключами, де кожен рядок існує сам по собі. cta_button, subject_line, footer_unsub. Вони містять метадані, які важливіші за сам текст: ключ, який ніколи не повинен змінюватися, примітку щодо контексту та часто обмеження кількості символів, адже занадто довга тема листа обрізається в поштовій скриньці.

CSV-файли Braze, Klaviyo та будь-які формати файлів локалізації зі світу розробки ПЗ (gettext PO, XLIFF) — це таблиці рядків. Ваші HTML-шаблони — це документи. Якщо ставитися до таблиці рядків як до документа, ви втратите ключі; якщо ж до документа як до таблиці рядків — ви розшматуєте текст на розрізнені фрагменти.

Саме тому ми реалізували підтримку файлів із рядками у Transept як окремий сценарій, а не просто включили її до імпорту документів. CSV-файл із текстами листів відображається у вигляді сітки з ключами, оригіналами та перекладами, де обмеження кількості символів працює як живий лічильник, а до кожного рядка додається примітка з контекстом.

Сітка рядків у Transept із завантаженим CSV-файлом розсилки. Видно рядки для subject_line, preheader, hero_headline, hero_body, cta_button, loyalty_line, shipping_note та footer_unsub. У стовпці оригіналу збережено тег персоналізації Braze та умову Liquid, праворуч — переклади німецькою, а під кожним із них — лічильники символів на кшталт 46/90 та 8/18.

Головна особливість полягає в тому, що файл зберігає свою початкову структуру. Ви експортуєте перекладений оригінальний файл, де всі ключі та стовпці залишаються на своїх місцях — саме там, де їх очікує платформа, — замість того, щоб потім переробляти його вручну.

Що ми виявили, додаючи підтримку імейлів у Transept

Ми реалізували імпорт файлів рядків саме для цього робочого процесу, і в ході роботи виявилися нюанси, про які я ніде не бачив жодних згадок. Це наші власні спостереження, засновані на нашому коді та результатах тестів.

Суто технічно, «50% off» — це специфікатор printf

У програмних рядках часто використовуються заповнювачі printf: %s, %d, %1$s. Якщо ви маскуєте їх перед перекладом, типовий регулярний вираз зазвичай охоплює повний набір прапорів printf, включно з прапором пробілу (% d додає пробіл перед додатними числами). З погляду синтаксису printf це допустимо, і такий підхід цілком виправданий.

Але для маркетингових текстів це справжня катастрофа. Якщо враховувати прапор пробілу, у фразі 50% off з’являється збіг: % o розпізнається як вісімкове перетворення з прапором пробілу. Те саме стосується 100% organic. Або Up to 70% off — чи не найпоширенішої конструкції в рекламних листах.

Ми перевірили обидва варіанти:

Вхідні даніСуворий патернЗ прапором пробілу
50% off your first orderнемає збігів% o
100% organic cottonнемає збігів% o
Привіт, %s, ви заощадили %d%%%s, %d, %%%s, %d, %%

Маскування % o перетворює рядок зі знижкою на заповнювач, і в результаті модель отримує понівечене речення. Ми свідомо ігноруємо прапор пробілу й нічого не втрачаємо: у реальних таблицях рядків він не використовується.

Тег персоналізації Braze має три закривальні фігурні дужки

Цю проблему ми виявили під час написання цього посібника — чудовий аргумент на користь створення таких інструкцій.

Синтаксис Braze — {{${first_name}}}. Порахуйте закривальні фігурні дужки: власна дужка атрибута }, а потім ще дві, що закривають тег виводу Liquid. Три поспіль.

Майже кожен токенізатор Liquid виконує нежадібний пошук до перших }}. Зіткнувшись із {{${first_name}}}, він спрацьовує на одну дужку раніше: захоплює {{${first_name}} і залишає одиноку } посеред тексту для перекладу. Здається, що токен оброблено правильно, але зайва дужка потрапляє до моделі як звичайний текст і повертається зміщеною, продубльованою або взагалі зникає.

{{${first_name}}}, your spring sale starts now

  non-greedy scan  →  token: {{${first_name}}     leftover: "}, your spring sale starts now"
  brace-aware scan →  token: {{${first_name}}}    leftover: ", your spring sale starts now"

Наш інструмент спрацював саме за першим сценарієм. Ми виявили цю помилку й виправили її, дозволивши один рівень вкладеності всередині токена, а також додали точний синтаксис Braze до набору тестів. Якщо ви підтримуєте власний інструментарій для імейлів, протестуйте його саме на {{${attribute}}}, адже звичайна форма {{ attribute }} працює без проблем і повністю приховує цей баг.

Лапки всередині заповнювачів порушують структуру JSON-відповідей

Коли ви надсилаєте моделі пакет рядків і обмежуєте формат відповіді JSON, неекранована " всередині рядка відповіді передчасно закриває його, через що решта пакета відкидається. Ми натрапили на цю проблему в заповнювачах, що містили атрибути в лапках, і на одній із моделей вона відтворювалася приблизно у 58% запусків.

Рішення не в тому, щоб покращувати інструкції з екранування в промпті. Натомість варто зробити формат передачі даних безлапковим, щоб помилка стала неможливою: модель бачитиме лише заповнювачі без лапок, а канонічна форма з лапками відновлюватиметься згодом. Спроби через промпт змусити модель не порушувати JSON здебільшого спрацьовують, і це найгірший сценарій для надійності, адже ви не помічатимете збоїв.

Нечіткі записи — це сигнал, а не переклад

Якщо ваші рядки походять із PO-файлів gettext, записи мають прапор fuzzy, що означає: «відповідність знайдено автоматично, людина її не підтвердила». Сприймати такі нечіткі записи як готові переклади — це все одно що затверджувати купу здогадок.

Ми виключаємо їх під час первинного наповнення, перекладаємо заново і знімаємо прапор fuzzy на виході, оскільки на той момент запис уже перевірено і позначка більше не відповідає дійсності.

Найкращі практики локалізації імейл-кампаній

Звички, що відрізняють злагоджений процес від болісного, наведені приблизно в порядку того, скільки нервів вони допомагають зберегти.

Визначте коди локалей один раз на рівні профілю. Дволітерні або з уточненням регіону — головне, щоб вони були однаковими всюди. Більшість випадків, коли «переклад не відображається», стаються через те, що профіль nl-BE намагається отримати повідомлення з кодом nl.

Додавайте контекст до кожного рядка ще до початку перекладу. Перекладач, бачачи Shop the sale у таблиці, не знає, що це — кнопка, заголовок чи посилання, і що на все є лише вісімнадцять символів. Кожна платформа, де є поле для контексту чи опису, просить вас надати саме ту інформацію, яка найбільше покращує якість результату, проте майже ніхто цього не робить.

Ставтеся до лімітів символів як до ключового обмеження. Німецька мова приблизно в 1,5–2 рази довша за англійську. Заклик до дії (CTA), що поміщається в англійській версії, вийде за межі блоку, а тема листа обірветься на пів слові в поштовій скриньці. Передавайте інформацію про ліміт разом із рядком, щоб перекладач бачив лічильник.

Складіть список термінів, що не потребують перекладу. Назви продуктів, брендів, функцій. У Klaviyo ця функція вбудована; на інших платформах вона реалізується через глосарій. У будь-якому разі зафіксуйте їх перед першим запуском, а не після того, як знайдете шість варіантів назви власного продукту.

Перекладайте резервні варіанти. Кожен фільтр default:, кожну гілку {% else %}, кожне «Привіт», що з’являється за відсутності імені. Це рядки, які ніколи не потрапляють у попередній перегляд, тому їх не перевіряють, хоча їх отримують користувачі, про яких ви знаєте найменше.

Використовуйте готові рішення повторно. Тексти кампаній постійно повторюються: той самий футер, той самий рядок відписки, те саме сезонне оформлення щороку. Пам’ять перекладів дозволяє один раз затвердити варіант «Купуйте на розпродажі», і він використовуватиметься в усіх наступних кампаніях замість того, щоб розгалужуватися на три версії через різні рішення під час різних запусків.

Робіть тестову розсилку кожною мовою перед фінальним відправленням. Сформуйте реальний шаблон для справжнього профілю в кожній локалі. Умовні конструкції, що виглядають правильними в редакторі, можуть давати збої, які виявляються лише під час рендерингу. Це дозволяє помітити неперекладений резервний текст або зламану гілку умови, поки це ще нічого не коштує.

Поширені запитання

Що таке локалізація імейлів?

Локалізація імейлів — це процес адаптації імейл-кампанії до іншої мови та ринку: текстів, тем і прехедерів, резервних варіантів персоналізації та правил оформлення, притаманних цільовій локалі. Вона відрізняється від звичайного перекладу тим, що імейл містить синтаксис шаблонів (теги злиття, умовні конструкції Liquid або Handlebars), який має залишитися недоторканим, а також має обмеження на кшталт довжини теми листа, яких необхідно дотримуватися під час перекладу.

Які імейл-платформи автоматично перекладають кампанії?

Klaviyo (Smart Translations, понад 60 мов), Customer.io (AI-автопереклад для імейлів, SMS, WhatsApp, пуш-повідомлень та сповіщень у додатку) і Brevo (через асистента Aura) генерують переклади безпосередньо в редакторі. Braze та Iterable забезпечують інфраструктуру для локалей, проте очікують, що переклади ви надасте самостійно. Mailchimp не має вбудованої функції багатомовних кампаній і покладається на умовні теги злиття.

Чи можна перекласти тему листа в Mailchimp?

Ні. У документації Mailchimp зазначено, що перекласти тему листа неможливо, оскільки умовні теги злиття не працюють у полі теми. Щоб надсилати локалізовані теми через Mailchimp, потрібно створювати окрему кампанію для кожної мови, сегментуючи аудиторію за полем мови контакту.

Як зробити так, щоб переклад не ламав теги Liquid?

Маскуйте токени перед тим, як текст потрапить до моделі перекладу, щоб вона не сприймала їх як слова. Після перекладу відновіть їх і переконайтеся, що набір токенів у результаті збігається з вхідними даними, перш ніж приймати результат. Якість також зростає, якщо перекладати кожну гілку умови як окремий рядок, а не передавати весь блок {% if %}...{% endif %} суцільним масивом — так кожна гілка перекладається як самостійне речення, яким вона і є.

Чим HTML-імейл відрізняється від таблиці рядків?

HTML-імейл — це документ: зв’язний текст зі своєю структурою, який краще перекладати цілком, щоб зберегти контекст між заголовком і основним текстом. Таблиця рядків — це список із ключами, де кожен рядок існує окремо; він містить ключ, який не можна змінювати, зазвичай примітку про контекст і часто обмеження за кількістю символів. Експортовані CSV-файли з Braze та Klaviyo, файли gettext PO та XLIFF — усе це приклади таблиць рядків. Вони потребують різного підходу: якщо працювати з таблицею рядків як із документом, можна втратити ключі, а якщо сприймати документ як таблицю рядків, текст перетвориться на розрізнені фрагменти.

Що краще використовувати для перекладу: експорт у CSV чи API платформи?

CSV — практичний вибір, коли перекладом займається людина або зовнішній підрядник; саме такий підхід описано в документації Braze та Klaviyo. Автоматизований обмін через API доцільніший, якщо процес повторюється за графіком або обсяги настільки великі, що ручне оброблення файлів стає «вузьким місцем». Braze пропонує API для перекладів (на момент написання статті він у ранньому доступі), а Iterable відкриває доступ до вмісту шаблонів через GET /api/templates/email/get. Brevo не підтримує жоден із цих варіантів: у сервісі немає перекладу на основі файлів, тому кампанії доводиться локалізувати безпосередньо в інтерфейсі.

Скільки мов може підтримувати одна імейл-кампанія?

Усе залежить від платформи. Braze дозволяє використовувати до 200 локалей на робочий простір і 200 тегів перекладу в одному повідомленні. Klaviyo охоплює понад 60 мов завдяки Smart Translations. Customer.io підтримує кілька сотень мовних і регіональних кодів. На практиці ліміти платформи рідко стають перешкодою; зазвичай усе впирається в те, скільки мов ви здатні перевіряти та підтримувати в актуальному стані в міру оновлення вихідного тексту.

Автор

Mariia Ivakhnenko
Mariia IvakhnenkoСпівзасновниця

Співзасновниця Transept. Має три дипломи з англійської мови та літератури — Київ, Острава та рік у Зальцбурзі — і, як українка, більшу частину свого письменницького життя проводить англійською. Прийшла в AI як промпт-інженерка, потім займалася продуктовим маркетингом. Вона пише напіввигадані історії про реальних людей і постійно повертається до питання про те, що втрачається між мовами.