# Internationalization (i18n)

**The Go SDK is server-side and does NOT expose a `t()` / label-render helper.**
There is no in-Go translation function — rendering translated labels happens in
the **browser** via the client SDK's `t()`. What the Go SDK provides is the SSR
wiring to bootstrap that browser loader.

## What the Go SDK provides: the i18n loader `<script>` tag

The package-level `shipeasy.I18nScriptTag` emits the loader script tag that, in
the browser, fetches and installs translations for a profile. It uses the
**public client key** (safe to embed in HTML) — never the server key. It runs off
the global configuration, so call `Configure` first:

```go
// clientKey is the PUBLIC client key; "{{PROFILE}}" is the locale profile.
tag := shipeasy.I18nScriptTag(clientKey, "{{PROFILE}}", shipeasy.BootstrapTagOptions{})
// emit `tag` in your document <head>, alongside BootstrapScriptTag.
```

Pair it with `shipeasy.BootstrapScriptTag` (see [Advanced](advanced.md) / SSR) so
the browser has flags AND translations on first paint:

```go
user := shipeasy.User{"user_id": "u_123"}
head := shipeasy.BootstrapScriptTag(user, shipeasy.BootstrapTagOptions{AnonID: anonID}) +
    shipeasy.I18nScriptTag(clientKey, "{{PROFILE}}", shipeasy.BootstrapTagOptions{})
```

`I18nScriptTag` defaults the profile to `en:prod` when you pass `""`, and the CDN
base to `https://cdn.shipeasy.ai` (override via `BootstrapTagOptions.BaseURL`).

## The cross-SDK story

1. **Server (this SDK):** emit `I18nScriptTag(clientKey, "{{PROFILE}}", …)` in
   the page `<head>`. The static `/sdk/i18n/loader.js` loader reads its `data-key`
   and `data-profile` attributes.
2. **Browser (the client SDK):** the loader fetches the `{{PROFILE}}` profile's
   labels from the CDN and installs them. Your front-end code then renders strings
   with the client SDK's `t("some.key")`.

So the Go SDK *bootstraps* i18n but does not *render* it. There is no
server-side `t()` in Go — do not look for one.
