Next.js reference

18ways.config.*

Create 18ways.config.ts, 18ways.config.js, or 18ways.config.cjs in your app root and export your 18ways config there.

ts
import type { WaysConfig } from '@18ways/next/config';
 
export default {
  apiKey: process.env.NEXT_PUBLIC_18WAYS_PUBLIC_API_KEY,
  baseLocale: 'en-GB',
  router: 'app', // 'app', 'path', or 'none' depending on if you use app router, path router, or if you don't want the router to sync with locale at all
} satisfies WaysConfig;

withWays()

Import from @18ways/next/config and call it from next.config.js.

ts
import { withWays } from '@18ways/next/config';

When 18ways.config.* exists, withWays() loads it automatically. For router: 'path' it returns native Next i18n config with locale detection disabled. For router: 'app' and router: 'none', it injects the alias needed for direct imports from @18ways/next/server.

Common options:

OptionTypeNotes
apiKeystringRequired.
baseLocalestringSource locale and default locale for routing.
router'app' | 'path' | 'none'Locale-routing mode. Use none when some other router already owns locale URLs.
acceptedLocalesstring[]Explicit locale list. Required for path, optional otherwise. Keep path mode in sync with the languages enabled in your 18ways dashboard.
domainsArray<{domain, defaultLocale}>Optional domain routing map.
localeParamNamestringApp Router locale segment param. Defaults to lang.
persistLocaleCookieboolean | ((request) => boolean)Locale-cookie persistence policy for server and client locale changes.
cacheTtlnumberCache TTL for adapter requests.
fetchertypeof fetchCustom fetch implementation.

init(config)

Import from @18ways/next/server.

Use it when you want to bind a config object explicitly.

WaysRoot

Import WaysRoot directly from @18ways/next/server in your layouts after wrapping next.config.js with withWays(...).

Use WaysRoot in your layout so the adapter can seed runtime state for the current request. With App Router locale routing this usually means app/[lang]/layout.tsx.

getLocale()

Resolve the current locale on the server. This is the helper to use when you need locale state outside WaysRoot, for example in server-only SEO helpers or other request-bound server code.

htmlAttrs()

htmlAttrs() resolves the current lang and dir values for the document element.

generateWaysMetadata()

Use generateWaysMetadata() inside generateMetadata() when you want translated titles, descriptions, and locale-aware canonical or alternate URLs.

proxy.ts

For router: 'app', proxy.ts is the opinionated entrypoint for request-time locale redirects. Re-export from @18ways/next/proxy to handle / -> /{locale} and domain canonicalization.

ts
export { default, config } from '@18ways/next/proxy';

If you already have your own project proxy.ts or middleware.ts, use getWaysProxyResponse(request) and return it before the rest of your logic.

Client helpers

Import from @18ways/next/client.

useLocale()

Read and change the current locale. This is the hook you pair with LanguageSwitcher or your own custom selector UI.

useRouter()

Locale-aware wrapper around Next navigation. Pass locale="fr-FR" to force a localized target or locale={false} to force an unlocalized one.

Locale-aware wrapper around next/link with the same override model as useRouter().

useUnlocalizedPathname()

Read the current pathname without the locale prefix.

useLocalizedHref()

Lower-level helper for converting an internal href into the current locale-aware href.

Path routing config

In router: 'app' mode the adapter follows your route tree:

  • routes under app/[lang]/... are localized
  • routes outside that segment stay unlocalized

Link, useRouter(), and setLocale() treat internal routes as localized by default. Use locale={false} only when you need to target an unlocalized route explicitly.