Best practices
The fastest way to get bad translations is to make the runtime work around avoidable app structure problems.
Use real context names
Good context keys explain where the copy lives:
await engine.t('Pay now', {
context: 'checkout.payment-form',
});
await engine.t('Billing history', {
context: 'dashboard.billing-history',
});
await engine.t('Simple pricing', {
context: 'marketing.pricing-hero',
});Avoid anonymous buckets like page1, copy, or misc.
Translate complete thoughts
Good:
const label = await engine.t(
'Download your latest invoice as PDF'
);Avoid:
18ways can handle the common link case as one message. <T><a href="#">Click here</a> to see more</T> should stay as one sentence instead of being split apart and stitched back together.
const first = await engine.t('Download');
const second = await engine.t(
'your latest invoice'
);
const third = await engine.t('as PDF');
const stitched = [first, second, third].join(' ');Keep the package boundary clear
- If you are in Next.js, use
@18ways/nextfor locale resolution and metadata. - If you are only in React, keep locale state in your app and use
@18ways/react. - If you are outside React, use
@18ways/coreand own the UI integration yourself.
Let routing match your product
Public marketing pages usually want path-based locale routing for SEO. Internal dashboards often do
not. That is why the current site excludes /dashboard from path routing.
Keep source copy human
18ways works best when the source text reads like real product copy, not like a compressed translation key.
Good source copy gives the model better context and gives your team something readable in code.