Skip to content
better-i18n.com
Bu sayfada

Better i18n Content lets you ship localized content — blog posts, marketing pages, FAQs, anything structured — from a single source of truth to every framework you use, with view analytics out of the box.

What you get #

  • Content models — Define your shape once (fields, types, relations). Use it everywhere.
  • Localized entries — Each entry stores per-language translations alongside source values.
  • REST delivery — Public CDN-backed API at content.better-i18n.com. Cache-Control + KV-backed responses.
  • View analytics@better-i18n/content SDK tracks content.view events with framework adapters for Next.js, React, Expo, Svelte, Vue, and vanilla JS.
Code
Dashboard (define models + entries)
   │
   ▼
Content API (content.better-i18n.com)
   │              │
   │              └─►  POST /v1/track ─► CF Analytics Engine
   ▼                                         │
GET /v1/content/...                          ▼
   │                                   Dashboard charts
   ▼                                   (views, languages, top entries)
Your app (Next.js, React, Expo, ...)

Reads are cached at the edge (KV, 60s TTL). Writes from the SDK are fire-and-forget — sendBeacon first, fetch keepalive fallback. Never blocks page renders.

Install #

npm install @better-i18n/sdk

Add your first model #

Code
### Get your API Key

1. Go to [dash.better-i18n.com](https://dash.better-i18n.com)
2. Navigate to **Settings** → **API Keys**
3. Select **Content** as the type
4. Create and copy your API key

> [!WARNING]

Keep your API key secret. Never commit it to version control. Use environment variables instead.

Code
### Create a client

```typescript title="lib/content.ts"
import { createClient } from "@better-i18n/sdk";

export const content = createClient({
  projectId: "your-org/your-project",
  apiKey: process.env.BETTER_I18N_API_KEY!,
});
```

Find your project ID in **Settings → General → Project ID**, or read it off the dashboard URL: `dash.better-i18n.com/{org}/{project}`.



### Fetch content

```typescript
import { content } from "./lib/content";

// List all content models
const models = await content.getModels();

// List published entries (chainable API)
const { data: posts, total } = await content
  .from("blog-posts")
  .eq("status", "published")
  .limit(10);

// Get a single entry in French
const { data: post } = await content
  .from("blog-posts")
  .language("fr")
  .single("hello-world");

console.log(post.title, post.body);
```



### Track views

Install the analytics SDK and call `useTrackView()` on your content pages. See [Analytics](/sdk/analytics).

Environment variables #

.env
BETTER_I18N_API_KEY=bi_your-api-key
BETTER_I18N_PROJECT=acme/web-app
VariableRequiredDescription
BETTER_I18N_API_KEYYesYour API key from the dashboard
BETTER_I18N_PROJECTYesProject identifier in org/project format

Configuration options #

OptionTypeRequiredDefaultDescription
projectIdstringYesProject ID — accepts org/project slug or canonical UUID. Find both in dashboard Settings → General → Project ID.
apiKeystringYesAPI key for authentication
apiBasestringNohttps://content.better-i18n.comCustom API base URL
debugbooleanNofalseLog request URLs and responses to console

Debugging #

Enable debug mode to see exactly what the SDK is doing:

TypeScript
const client = createClient({
  projectId: "acme/web-app",
  apiKey: process.env.BETTER_I18N_API_KEY!,
  debug: true,
});

This logs all requests and responses to the console:

Code
[better-i18n] Client initialized { apiBase: "https://content.better-i18n.com", org: "acme", project: "web-app" }
[better-i18n] → getEntries(blog-posts) https://content.better-i18n.com/v1/content/acme/web-app/models/blog-posts/entries?status=published
[better-i18n] ← 200 OK

Next steps #

  • Models & Entries — define schema in dashboard + query with chainable from() API
  • REST API — raw HTTP for any framework
  • Analytics — track which content gets viewed