Next.js storefront. Centra as commerce. Klaviyo as the mail pipe. next-intl as the dictionary. The market that paid the bills spoke Dutch. If a receipt arrived in English, the shopper did not file a Jira. They forwarded it to support and asked if they ordered from the wrong site.
Order confirmation in en. Password reset in en. Shipping update that says "Your order" to a profile whose Centra language is nl-NL. Klaviyo still "sent." The metric still fired. The copy was just from the wrong room.
I treated Klaviyo like it would pick Dutch because the profile had a Dutch email and a Dutch shipping address. Klaviyo sends whatever string you put on the event or in the template. It does not run next-intl. It does not read your Next.js request locale. A flow triggered off Placed Order will happily render the default template language.
The storefront already had next-intl wired for nl-NL. Product pages were fine. Transactional copy lived in a second pile: hardcoded English in the Klaviyo template, or a server helper that called getTranslations() without a locale and inherited the default.
That default was English. Of course it was.
Transactional HTML that we still render ourselves goes through next-intl with an explicit locale. Not "whatever the current request is." A Klaviyo event can be sent from a webhook, a queue, a Centra plugin callback. There is no incoming Accept-Language. If you do not pass nl-NL, you get the default.
const locale = profile.language === 'nl' ? 'nl-NL' : 'en';
const t = await getTranslations({ locale, namespace: 'Transactional' });
await klaviyo.events.create({
data: {
type: 'event',
attributes: {
metric: { data: { type: 'metric', attributes: { name: 'Placed Order' } } },
profile: { data: { type: 'profile', attributes: { email } } },
properties: {
subject: t('orderReceipt.subject'),
preview: t('orderReceipt.preview'),
},
},
},
});When Klaviyo owns the template, the template must branch on the profile language Centra already syncs (person|lookup:"Language"), or we send pre-rendered next-intl strings as event properties. Guessing from the shipping country is how Belgium gets French and the Netherlands gets English on a Tuesday.
next-intl already knew nl-NL. I just had not invited it to the email.
Happy coding!
Sander