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:

tsx
'use client';
 
import { Ways } from '@18ways/react';
 
export function AppPage() {
  return (
    <>
      <Ways context="checkout.payment-form">
        <PaymentForm />
      </Ways>
      <Ways context="dashboard.billing-history">
        <BillingHistory />
      </Ways>
      <Ways context="marketing.pricing-hero">
        <PricingHero />
      </Ways>
    </>
  );
}

Avoid anonymous buckets like page1, copy, or misc.

Translate complete thoughts

Good:

tsx
'use client';
 
import Link from 'next/link';
import { T } from '@18ways/react';
 
export function InvoiceLink() {
  return (
    <T>
      Download your latest invoice as{' '}
      <Link href="/invoices/latest.pdf">PDF</Link>
    </T>
  );
}

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.

tsx
import { T } from '@18ways/react';
 
export function InvoiceLink() {
  return (
    <>
      <T>Download</T>{' '}
      <T>your latest invoice</T>{' '}
      <T>as PDF</T>
    </>
  );
}

Keep the package boundary clear

  • If you are in Next.js, use @18ways/next for 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/core and 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.