@intlayer/docs 9.0.0-canary.10 → 9.0.0-canary.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_CMS.md +16 -1
- package/docs/ar/releases/v9.md +58 -1
- package/docs/ar/self_hosting.md +349 -0
- package/docs/bn/intlayer_CMS.md +570 -0
- package/docs/bn/releases/v9.md +358 -0
- package/docs/cs/releases/v9.md +358 -0
- package/docs/de/intlayer_CMS.md +117 -1
- package/docs/de/releases/v9.md +61 -1
- package/docs/de/self_hosting.md +349 -0
- package/docs/en/intlayer_CMS.md +171 -1
- package/docs/en/releases/v9.md +45 -2
- package/docs/en/self_hosting.md +349 -0
- package/docs/en-GB/intlayer_CMS.md +16 -1
- package/docs/en-GB/releases/v9.md +47 -2
- package/docs/en-GB/self_hosting.md +349 -0
- package/docs/es/intlayer_CMS.md +117 -1
- package/docs/es/releases/v9.md +61 -1
- package/docs/es/self_hosting.md +349 -0
- package/docs/fr/intlayer_CMS.md +117 -1
- package/docs/fr/releases/v9.md +61 -1
- package/docs/fr/self_hosting.md +349 -0
- package/docs/hi/intlayer_CMS.md +16 -1
- package/docs/hi/releases/v9.md +59 -1
- package/docs/hi/self_hosting.md +349 -0
- package/docs/id/releases/v9.md +31 -1
- package/docs/id/self_hosting.md +349 -0
- package/docs/it/intlayer_CMS.md +117 -1
- package/docs/it/releases/v9.md +61 -1
- package/docs/it/self_hosting.md +349 -0
- package/docs/ja/intlayer_CMS.md +191 -10
- package/docs/ja/releases/v9.md +31 -1
- package/docs/ja/self_hosting.md +349 -0
- package/docs/ko/intlayer_CMS.md +189 -6
- package/docs/ko/releases/v9.md +30 -1
- package/docs/ko/self_hosting.md +349 -0
- package/docs/nl/releases/v9.md +358 -0
- package/docs/pl/intlayer_CMS.md +16 -1
- package/docs/pl/releases/v9.md +58 -1
- package/docs/pl/self_hosting.md +349 -0
- package/docs/pt/intlayer_CMS.md +117 -1
- package/docs/pt/releases/v9.md +61 -1
- package/docs/pt/self_hosting.md +349 -0
- package/docs/ru/intlayer_CMS.md +196 -15
- package/docs/ru/releases/v9.md +59 -1
- package/docs/ru/self_hosting.md +349 -0
- package/docs/tr/intlayer_CMS.md +16 -1
- package/docs/tr/releases/v9.md +46 -1
- package/docs/tr/self_hosting.md +349 -0
- package/docs/uk/intlayer_CMS.md +16 -1
- package/docs/uk/releases/v9.md +58 -1
- package/docs/uk/self_hosting.md +349 -0
- package/docs/vi/releases/v9.md +31 -1
- package/docs/vi/self_hosting.md +349 -0
- package/docs/zh/releases/v9.md +31 -1
- package/docs/zh/self_hosting.md +349 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +20 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-06-30
|
|
3
|
+
updatedAt: 2026-06-30
|
|
4
|
+
title: "Intlayer selbst hosten"
|
|
5
|
+
description: "Betreiben Sie eine komplette Intlayer-Instanz auf Ihrer eigenen Infrastruktur mit einem einzigen Befehl. Kein Intlayer Cloud-Konto erforderlich."
|
|
6
|
+
keywords:
|
|
7
|
+
- Selbst-Hosting
|
|
8
|
+
- Docker
|
|
9
|
+
- Docker Compose
|
|
10
|
+
- Intlayer
|
|
11
|
+
- CMS
|
|
12
|
+
- Installation
|
|
13
|
+
- Infrastruktur
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- self-hosting
|
|
17
|
+
author: aymericzip
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Intlayer selbst hosten
|
|
21
|
+
|
|
22
|
+
Intlayer kann vollständig auf Ihrer eigenen Infrastruktur ausgeführt werden – kein Intlayer Cloud-Konto erforderlich. Ein einziger Befehl startet einen produktionsbereiten Stack:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Der Installer lädt eine `docker-compose.yml` und eine `.env` herunter, generiert automatisch die erforderlichen Secrets und startet alle Container mit `docker compose up -d`.
|
|
29
|
+
|
|
30
|
+
## Inhaltsverzeichnis
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Architektur
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
┌─────────────────────────────┐
|
|
40
|
+
browser ──────▶ │ app (TanStack Start) :3000│ ──┐
|
|
41
|
+
└─────────────────────────────┘ │ VITE_BACKEND_URL
|
|
42
|
+
┌─────────────────────────────┐ │
|
|
43
|
+
│ backend (Fastify/Bun) :3100│ ◀─┘
|
|
44
|
+
└──────────────┬──────────────┘
|
|
45
|
+
┌──────────┬─────────┼──────────┬───────────┐
|
|
46
|
+
▼ ▼ ▼ ▼ ▼
|
|
47
|
+
mongo:27017 redis:6379 minio:9000 mailpit:1025 Chromium
|
|
48
|
+
(1-node RS) (S3 API) (SMTP) (in-image)
|
|
49
|
+
minio:9001 mailpit:8025
|
|
50
|
+
(console) (web UI)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Chromium (wird für die Erzeugung von Puppeteer-Screenshots verwendet) ist im Backend-Image gebündelt – es wird kein separater Container benötigt.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Voraussetzungen
|
|
58
|
+
|
|
59
|
+
- **Docker** ≥ 24 und **Docker Compose** ≥ v2. Fehlt eines davon, gibt der Installer den Installationslink aus und beendet sich.
|
|
60
|
+
- Ports `3000`, `3100`, `8025`, `9000` und `9001` auf dem Host verfügbar.
|
|
61
|
+
- Ein Linux- oder macOS-Host (oder WSL2 unter Windows).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Schnellstart
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Was der Installer tut:
|
|
72
|
+
|
|
73
|
+
1. Überprüft, ob `docker` und `docker compose` vorhanden sind.
|
|
74
|
+
2. Lädt `docker-compose.yml` und `.env.example` in `./intlayer/` herunter.
|
|
75
|
+
3. Falls keine `.env` existiert, kopiert er das Beispiel und generiert zufällige Secrets für `BETTER_AUTH_SECRET`, `S3_ACCESS_KEY_ID` und `S3_SECRET_ACCESS_KEY` mittels `openssl rand`.
|
|
76
|
+
4. Führt `docker compose pull` + `docker compose up -d` aus.
|
|
77
|
+
5. Gibt die URLs aus: Dashboard `:3000`, API `:3100`, E-Mail-UI `:8025`, MinIO-Konsole `:9001`.
|
|
78
|
+
|
|
79
|
+
Nachdem der Stack gestartet ist, öffnen Sie **http://localhost:3000** und erstellen Sie Ihr erstes Konto.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Dienste
|
|
84
|
+
|
|
85
|
+
| Service | Image | Host port(s) | Zweck |
|
|
86
|
+
| :---------- | :----------------------------------- | :--------------------------------------------- | :-------------------------------------------------------- |
|
|
87
|
+
| **app** | built from `apps/app/Dockerfile` | `3000` | TanStack Start Dashboard (CMS-Benutzeroberfläche) |
|
|
88
|
+
| **backend** | built from `apps/backend/Dockerfile` | `3100` | Fastify REST API (`/health` Endpunkt) |
|
|
89
|
+
| **mongo** | `mongo:7` | intern | Einzelknoten-Replica Set (`rs0`) |
|
|
90
|
+
| **redis** | `redis:7-alpine` | intern | Job-Warteschlangen (BullMQ) und Caching (ioredis) |
|
|
91
|
+
| **minio** | `minio/minio` | `9000` (S3), `9001` (Konsole) | S3-kompatibler Objektspeicher für Avatare und Screenshots |
|
|
92
|
+
| **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (Web-Benutzeroberfläche) | Lokale Transaktions-E-Mail-Senke |
|
|
93
|
+
|
|
94
|
+
Interne Ports (mongo, redis) werden standardmäßig nicht zum Host exponiert.
|
|
95
|
+
|
|
96
|
+
> MinIO-Port `9000` muss vom Browser erreichbar sein, da hochgeladene Assets (Avatare, Screenshots) direkt von `S3_PUBLIC_URL=http://localhost:9000/intlayer` geladen werden.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Umgebungsvariablen
|
|
101
|
+
|
|
102
|
+
Der Installer generiert eine gebrauchsfertige `.env`. Die folgende Tabelle beschreibt jede Variable.
|
|
103
|
+
|
|
104
|
+
### Erforderlich (automatisch generiert oder abgefragt)
|
|
105
|
+
|
|
106
|
+
| Variable | Beispiel | Beschreibung |
|
|
107
|
+
| :--------------------- | :---------------------------------------------- | :--------------------------------------------------------------- |
|
|
108
|
+
| `NODE_ENV` | `production` | Laufzeitumgebung |
|
|
109
|
+
| `PORT` | `3100` | Backend-Listenport |
|
|
110
|
+
| `BACKEND_URL` | `http://localhost:3100` | Öffentliche URL der Backend-API |
|
|
111
|
+
| `APP_URL` | `http://localhost:3000` | Öffentliche URL des Dashboards |
|
|
112
|
+
| `DOMAIN` | `localhost` | Cookie-Domain |
|
|
113
|
+
| `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | Vollständige MongoDB-Verbindungs-URI |
|
|
114
|
+
| `REDIS_URL` | `redis://redis:6379` | Redis-Verbindungs-URL |
|
|
115
|
+
| `BETTER_AUTH_SECRET` | _(generiert)_ | 32-Byte-Secret für die Session-Signierung |
|
|
116
|
+
| `MAIL_PROVIDER` | `smtp` | Mail-Transport: `smtp` oder `resend` |
|
|
117
|
+
| `MAIL_SMTP_HOST` | `mailpit` | SMTP-Hostname (Mailpit Container-Name) |
|
|
118
|
+
| `MAIL_SMTP_PORT` | `1025` | SMTP-Port |
|
|
119
|
+
| `MAIL_FROM` | `Intlayer <no-reply@localhost>` | Absenderadresse |
|
|
120
|
+
| `S3_ENDPOINT` | `http://minio:9000` | S3-kompatibler Endpunkt |
|
|
121
|
+
| `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | Öffentliche URL für das Laden von Browser-Assets |
|
|
122
|
+
| `S3_BUCKET_NAME` | `intlayer` | Bucket-Name |
|
|
123
|
+
| `S3_ACCESS_KEY_ID` | _(generiert)_ | MinIO-Zugangsschlüssel |
|
|
124
|
+
| `S3_SECRET_ACCESS_KEY` | _(generiert)_ | MinIO-Geheimschlüssel |
|
|
125
|
+
| `VITE_BACKEND_URL` | `http://localhost:3100` | Backend-URL, die zur Build-Zeit in das Dashboard integriert wird |
|
|
126
|
+
| `VITE_DOMAIN` | `localhost` | Domain, die zur Build-Zeit in das Dashboard integriert wird |
|
|
127
|
+
|
|
128
|
+
### Optional (Funktionen funktionieren bei Abwesenheit eingeschränkt)
|
|
129
|
+
|
|
130
|
+
| Variable | Funktion |
|
|
131
|
+
| :------------------------------------------------------- | :------------------------------------------------------------------- |
|
|
132
|
+
| `OPENAI_API_KEY` | KI-gestützte Übersetzung und Inhaltsprüfung |
|
|
133
|
+
| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Abrechnung und Abonnementverwaltung |
|
|
134
|
+
| `RESEND_API_KEY` | Transaktions-E-Mail über Resend (überschreibt Mailpit, wenn gesetzt) |
|
|
135
|
+
| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuth-Login |
|
|
136
|
+
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth-Login |
|
|
137
|
+
| `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | GitLab OAuth-Login |
|
|
138
|
+
| `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Microsoft OAuth-Login |
|
|
139
|
+
| `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | LinkedIn OAuth-Login |
|
|
140
|
+
| `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Atlassian OAuth-Login |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Ihr Intlayer-Projekt verbinden
|
|
145
|
+
|
|
146
|
+
Sobald der Stack läuft, verweisen Sie Ihr Projekt auf das selbst gehostete Backend und Dashboard anstelle von `intlayer.org`.
|
|
147
|
+
|
|
148
|
+
### Projektkonfiguration
|
|
149
|
+
|
|
150
|
+
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
151
|
+
import type { IntlayerConfig } from "intlayer";
|
|
152
|
+
|
|
153
|
+
const config: IntlayerConfig = {
|
|
154
|
+
editor: {
|
|
155
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
156
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* URL des selbst gehosteten CMS-Dashboards.
|
|
160
|
+
* Standard: https://app.intlayer.org
|
|
161
|
+
*/
|
|
162
|
+
cmsURL: process.env.INTLAYER_CMS_URL, // e.g. http://localhost:3000
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* URL der selbst gehosteten Backend-API.
|
|
166
|
+
* Standard: https://back.intlayer.org
|
|
167
|
+
*/
|
|
168
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // e.g. http://localhost:3100
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export default config;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Setzen Sie die Umgebungsvariablen in der `.env` Ihres Projekts:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
INTLAYER_CMS_URL=http://localhost:3000
|
|
179
|
+
INTLAYER_BACKEND_URL=http://localhost:3100
|
|
180
|
+
INTLAYER_CLIENT_ID=<your-client-id>
|
|
181
|
+
INTLAYER_CLIENT_SECRET=<your-client-secret>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Erstellen Sie Zugangsdaten in Ihrem selbst gehosteten Dashboard unter **Projects → Access keys** unter `http://localhost:3000/projects`.
|
|
185
|
+
|
|
186
|
+
### `@intlayer/api` SDK
|
|
187
|
+
|
|
188
|
+
Wenn Sie das `@intlayer/api` SDK programmatisch verwenden, übergeben Sie `backendURL` explizit:
|
|
189
|
+
|
|
190
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
191
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
192
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
193
|
+
|
|
194
|
+
const cms = createIntlayerCMS({
|
|
195
|
+
editor: {
|
|
196
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
197
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
198
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // http://localhost:3100
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Upgrade
|
|
208
|
+
|
|
209
|
+
Ein erneutes Ausführen des Installers auf einer bestehenden Bereitstellung führt ein Rolling-Upgrade durch:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Dies zieht die neuesten Images und startet Container neu mit `docker compose pull && docker compose up -d`. Bestehende Volumes (`mongo-data`, `redis-data`, `minio-data`) bleiben erhalten – kein Datenverlust.
|
|
216
|
+
|
|
217
|
+
Um manuell aus dem `./intlayer/`-Verzeichnis ein Upgrade durchzuführen:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
docker compose pull
|
|
221
|
+
docker compose up -d
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Backup und Wiederherstellung
|
|
227
|
+
|
|
228
|
+
Alle persistenten Daten befinden sich in drei benannten Docker-Volumes.
|
|
229
|
+
|
|
230
|
+
### Backup
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
docker run --rm \
|
|
234
|
+
-v intlayer_mongo-data:/data \
|
|
235
|
+
-v "$(pwd)":/backup \
|
|
236
|
+
busybox tar czf /backup/mongo-data.tar.gz /data
|
|
237
|
+
|
|
238
|
+
docker run --rm \
|
|
239
|
+
-v intlayer_redis-data:/data \
|
|
240
|
+
-v "$(pwd)":/backup \
|
|
241
|
+
busybox tar czf /backup/redis-data.tar.gz /data
|
|
242
|
+
|
|
243
|
+
docker run --rm \
|
|
244
|
+
-v intlayer_minio-data:/data \
|
|
245
|
+
-v "$(pwd)":/backup \
|
|
246
|
+
busybox tar czf /backup/minio-data.tar.gz /data
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Wiederherstellung
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
docker run --rm \
|
|
253
|
+
-v intlayer_mongo-data:/data \
|
|
254
|
+
-v "$(pwd)":/backup \
|
|
255
|
+
busybox tar xzf /backup/mongo-data.tar.gz -C /
|
|
256
|
+
|
|
257
|
+
# Wiederholen Sie dies für redis-data und minio-data
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Verwendung eines Reverse-Proxys (Nginx / Caddy)
|
|
263
|
+
|
|
264
|
+
Für Produktionsbereitstellungen platzieren Sie einen Reverse-Proxy vor den App- und Backend-Containern, anstatt sie direkt zu exponieren.
|
|
265
|
+
|
|
266
|
+
### Nginx-Beispiel
|
|
267
|
+
|
|
268
|
+
```nginx
|
|
269
|
+
server {
|
|
270
|
+
listen 80;
|
|
271
|
+
server_name cms.example.com;
|
|
272
|
+
|
|
273
|
+
location / {
|
|
274
|
+
proxy_pass http://localhost:3000;
|
|
275
|
+
proxy_set_header Host $host;
|
|
276
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
server {
|
|
281
|
+
listen 80;
|
|
282
|
+
server_name api.example.com;
|
|
283
|
+
|
|
284
|
+
location / {
|
|
285
|
+
proxy_pass http://localhost:3100;
|
|
286
|
+
proxy_set_header Host $host;
|
|
287
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Aktualisieren Sie die folgenden `.env`-Variablen, um sie an Ihre öffentlichen Domains anzupassen:
|
|
293
|
+
|
|
294
|
+
```sh
|
|
295
|
+
BACKEND_URL=https://api.example.com
|
|
296
|
+
APP_URL=https://cms.example.com
|
|
297
|
+
DOMAIN=example.com
|
|
298
|
+
VITE_BACKEND_URL=https://api.example.com
|
|
299
|
+
VITE_DOMAIN=example.com
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
> `VITE_*`-Variablen werden zur Build-Zeit in das Dashboard-Image integriert. Wenn Sie diese nach dem Bau des Images ändern, müssen Sie das `app`-Image neu erstellen (`docker compose build app`) oder die Laufzeitkonfigurationsinjektion verwenden.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Fehlerbehebung
|
|
307
|
+
|
|
308
|
+
### Backend-Absturzschleifen beim ersten Start
|
|
309
|
+
|
|
310
|
+
MongoDB und Redis müssen fehlerfrei sein, bevor das Backend startet. Die Compose-Datei verwendet `depends_on` mit `condition: service_healthy`. Wenn Sie wiederholte Backend-Neustarts sehen, überprüfen Sie, ob die `mongo`- und `redis`-Healthchecks erfolgreich sind:
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
docker compose ps
|
|
314
|
+
docker compose logs mongo
|
|
315
|
+
docker compose logs redis
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Dashboard kann die API nicht erreichen
|
|
319
|
+
|
|
320
|
+
Stellen Sie sicher, dass `VITE_BACKEND_URL` der URL entspricht, unter der das Backend vom **Browser** (nicht vom Docker-Netzwerk) aus erreichbar ist. Wenn Sie den Backend-Port geändert oder einen Reverse-Proxy hinzugefügt haben, erstellen Sie das Dashboard-Image neu:
|
|
321
|
+
|
|
322
|
+
```sh
|
|
323
|
+
docker compose build app
|
|
324
|
+
docker compose up -d app
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### E-Mail wird nicht gesendet
|
|
328
|
+
|
|
329
|
+
Standardmäßig werden alle ausgehenden E-Mails von Mailpit abgefangen. Öffnen Sie `http://localhost:8025`, um gesendete Nachrichten anzuzeigen. Um echte E-Mails zu senden, setzen Sie `MAIL_PROVIDER=resend` und `RESEND_API_KEY=<Ihr-Schlüssel>` in `.env` und starten Sie dann das Backend neu:
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
docker compose restart backend
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### MinIO-Bucket fehlt
|
|
336
|
+
|
|
337
|
+
Wenn der `minio-init`-One-Shot-Service nicht ausgeführt wurde (oder vor der Bereitschaft von MinIO lief), erstellen Sie den Bucket manuell:
|
|
338
|
+
|
|
339
|
+
```sh
|
|
340
|
+
docker compose run --rm minio-init
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Nützliche Links
|
|
346
|
+
|
|
347
|
+
- [Intlayer CMS-Dokumentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/de/intlayer_CMS.md)
|
|
348
|
+
- [Konfigurationsreferenz](https://github.com/aymericzip/intlayer/blob/main/docs/docs/de/configuration.md)
|
|
349
|
+
- [CMS SDK — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/de/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
|
package/docs/en/intlayer_CMS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-29
|
|
4
4
|
title: Intlayer CMS | Externalize your content into the Intlayer CMS
|
|
5
5
|
description: Externalize your content into the Intlayer CMS to delegate the management of your content to your team.
|
|
6
6
|
keywords:
|
|
@@ -18,6 +18,12 @@ slugs:
|
|
|
18
18
|
- cms
|
|
19
19
|
youtubeVideo: https://www.youtube.com/watch?v=UDDTnirwi_4
|
|
20
20
|
history:
|
|
21
|
+
- version: 9.0.0
|
|
22
|
+
date: 2026-06-30
|
|
23
|
+
changes: "Add Self-Hosting section: Docker Compose bootstrap, service inventory, SDK configuration, optional features, and upgrade notes"
|
|
24
|
+
- version: 9.0.0
|
|
25
|
+
date: 2026-06-29
|
|
26
|
+
changes: "Add @intlayer/api SDK (createIntlayerCMS) section for programmatic CMS access"
|
|
21
27
|
- version: 6.0.1
|
|
22
28
|
date: 2025-09-22
|
|
23
29
|
changes: "Add live sync documentation"
|
|
@@ -241,6 +247,158 @@ This command uploads your initial content dictionaries, making them available fo
|
|
|
241
247
|
|
|
242
248
|
Then you will be able to see and manage your dictionary in the [Intlayer CMS](https://app.intlayer.org/content).
|
|
243
249
|
|
|
250
|
+
## Programmatic access with the `@intlayer/api` SDK
|
|
251
|
+
|
|
252
|
+
Beyond the CLI and the visual editor, Intlayer ships a typed SDK in the [`@intlayer/api`](https://www.npmjs.com/package/@intlayer/api) package. It lets you treat the CMS as a **headless content database**: you can fetch projects, fetch dictionaries, and push or update them directly from your own application, scripts, or CI pipeline.
|
|
253
|
+
|
|
254
|
+
The SDK handles authentication for you. As long as your `clientId` and `clientSecret` are available (in your Intlayer configuration or environment), it obtains and refreshes an OAuth2 access token automatically and signs every request.
|
|
255
|
+
|
|
256
|
+
### Installation
|
|
257
|
+
|
|
258
|
+
```bash packageManager="npm"
|
|
259
|
+
npm install @intlayer/api
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```bash packageManager="yarn"
|
|
263
|
+
yarn add @intlayer/api
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash packageManager="pnpm"
|
|
267
|
+
pnpm add @intlayer/api
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="bun"
|
|
271
|
+
bun add @intlayer/api
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### How it works: authenticator + endpoints
|
|
275
|
+
|
|
276
|
+
The SDK is split into **two separate imports** on purpose, to keep your bundle small:
|
|
277
|
+
|
|
278
|
+
1. `createIntlayerCMS` — creates a lightweight **authenticator**. It only carries the credentials and the managed access token; it knows nothing about any specific domain.
|
|
279
|
+
2. `dictionaryEndpoint`, `projectEndpoint`, … — per-domain **endpoint binders**, each imported from its own subpath (`@intlayer/api/dictionary`, `@intlayer/api/project`, …). You pass the authenticator to the endpoint you need.
|
|
280
|
+
|
|
281
|
+
Because each endpoint is imported separately, your bundle includes only the domains you actually use — importing `dictionaryEndpoint` never pulls in the project, AI, or any other domain client.
|
|
282
|
+
|
|
283
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
284
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
285
|
+
|
|
286
|
+
// The configuration is optional: when omitted, the credentials are read from
|
|
287
|
+
// `@intlayer/config/built`, which resolves the INTLAYER_CLIENT_ID and
|
|
288
|
+
// INTLAYER_CLIENT_SECRET environment variables.
|
|
289
|
+
export const cmsAuthenticator = createIntlayerCMS();
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
> [!WARNING]
|
|
293
|
+
> The CMS credentials (`clientId` / `clientSecret`) grant **write access** to your content. Only ever create the authenticator on the **server side** (server actions, route handlers, scripts, CI). Never import it into client-side code or expose your credentials to the browser.
|
|
294
|
+
|
|
295
|
+
If you prefer not to rely on the build-time configuration, pass the credentials explicitly:
|
|
296
|
+
|
|
297
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
298
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
299
|
+
|
|
300
|
+
export const cmsAuthenticator = createIntlayerCMS({
|
|
301
|
+
editor: {
|
|
302
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
303
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
304
|
+
// Optional, for self-hosted backends:
|
|
305
|
+
// backendURL: process.env.INTLAYER_BACKEND_URL,
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
> Get your credentials by creating a new access key in the [Intlayer Dashboard - Projects](https://app.intlayer.org/projects).
|
|
311
|
+
|
|
312
|
+
### Fetch projects
|
|
313
|
+
|
|
314
|
+
```typescript fileName="projects.ts" codeFormat="typescript"
|
|
315
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
316
|
+
import { projectEndpoint } from "@intlayer/api/project";
|
|
317
|
+
|
|
318
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
319
|
+
|
|
320
|
+
// List the projects accessible with your credentials
|
|
321
|
+
const { data: projects } =
|
|
322
|
+
await projectEndpoint(cmsAuthenticator).getProjects();
|
|
323
|
+
|
|
324
|
+
// Read aggregated localization insights of the selected project
|
|
325
|
+
const { data: insights } =
|
|
326
|
+
await projectEndpoint(cmsAuthenticator).getProjectInsights();
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Fetch dictionaries
|
|
330
|
+
|
|
331
|
+
```typescript fileName="read-dictionaries.ts" codeFormat="typescript"
|
|
332
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
333
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
334
|
+
|
|
335
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
336
|
+
|
|
337
|
+
// List every remote dictionary of the project
|
|
338
|
+
const { data: dictionaries } =
|
|
339
|
+
await dictionaryEndpoint(cmsAuthenticator).getDictionaries();
|
|
340
|
+
|
|
341
|
+
// Or get a single dictionary by key
|
|
342
|
+
const { data: dictionary } = await dictionaryEndpoint(
|
|
343
|
+
cmsAuthenticator
|
|
344
|
+
).getDictionary("my-first-dictionary-key");
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Push and update dictionaries
|
|
348
|
+
|
|
349
|
+
Use the CMS as a database to write content back:
|
|
350
|
+
|
|
351
|
+
```typescript fileName="write-dictionaries.ts" codeFormat="typescript"
|
|
352
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
353
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
354
|
+
|
|
355
|
+
const cmsAuthenticator = createIntlayerCMS();
|
|
356
|
+
|
|
357
|
+
// Create a new dictionary
|
|
358
|
+
await dictionaryEndpoint(cmsAuthenticator).addDictionary({
|
|
359
|
+
key: "my-first-dictionary-key",
|
|
360
|
+
content: { title: "Hello world" },
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Upsert a batch of dictionaries (create or update them in one call)
|
|
364
|
+
await dictionaryEndpoint(cmsAuthenticator).pushDictionaries([
|
|
365
|
+
{ key: "home", content: { title: "Home" } },
|
|
366
|
+
{ key: "about", content: { title: "About" } },
|
|
367
|
+
]);
|
|
368
|
+
|
|
369
|
+
// Update an existing dictionary
|
|
370
|
+
await dictionaryEndpoint(cmsAuthenticator).updateDictionary({
|
|
371
|
+
id: "<dictionary-id>",
|
|
372
|
+
key: "home",
|
|
373
|
+
content: { title: "Updated title" },
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
> Tip: reuse the bound endpoint to avoid repeating yourself:
|
|
378
|
+
>
|
|
379
|
+
> ```typescript codeFormat="typescript"
|
|
380
|
+
> const dictionary = dictionaryEndpoint(cmsAuthenticator);
|
|
381
|
+
> await dictionary.pushDictionaries([myDictionary]);
|
|
382
|
+
> const { data } = await dictionary.getDictionaries();
|
|
383
|
+
> ```
|
|
384
|
+
|
|
385
|
+
### Extracting a single method
|
|
386
|
+
|
|
387
|
+
Every endpoint method is already authenticated and standalone (it carries its own token handling), so you can extract one and pass it around — for example to inject it as a dependency:
|
|
388
|
+
|
|
389
|
+
```typescript fileName="push.ts" codeFormat="typescript"
|
|
390
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
391
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
392
|
+
|
|
393
|
+
const dictionary = dictionaryEndpoint(createIntlayerCMS());
|
|
394
|
+
|
|
395
|
+
// Already authenticated — refreshes the token automatically on each call
|
|
396
|
+
export const pushDictionaries = dictionary.pushDictionaries;
|
|
397
|
+
|
|
398
|
+
// Usage
|
|
399
|
+
await pushDictionaries([{ key: "home", content: { title: "Home" } }]);
|
|
400
|
+
```
|
|
401
|
+
|
|
244
402
|
## Live sync
|
|
245
403
|
|
|
246
404
|
Live Sync lets your app reflect CMS content changes at runtime. No rebuild or redeploy required. When enabled, updates are streamed to a Live Sync server that refreshes the dictionaries your application reads.
|
|
@@ -384,6 +542,18 @@ Notes and constraints:
|
|
|
384
542
|
- The `live` flag is evaluated for each dictionary at build time. If remote content wasn't flagged `live=true` during build, you must rebuild to enable Live Sync for that dictionary.
|
|
385
543
|
- The live sync server must be able to write to `.intlayer`. In containers, ensure write access to `/.intlayer`.
|
|
386
544
|
|
|
545
|
+
## Self-Hosting
|
|
546
|
+
|
|
547
|
+
Intlayer can run entirely on your own infrastructure. A one-liner bootstraps the full stack (dashboard, API, database, object storage, and email) with Docker Compose:
|
|
548
|
+
|
|
549
|
+
```sh
|
|
550
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
For the complete setup guide, environment variable reference, upgrade instructions, and backup/restore procedures, see the [Self-Hosting Guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/self_hosting.md).
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
387
557
|
## Debug
|
|
388
558
|
|
|
389
559
|
If you encounter any issues with the CMS, check the following:
|
package/docs/en/releases/v9.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-29
|
|
4
4
|
title: New Intlayer v9 - What's new?
|
|
5
|
-
description: Discover what's new in Intlayer v9. Introducing drop-in compatibility packages for popular i18n libraries
|
|
5
|
+
description: Discover what's new in Intlayer v9. Introducing drop-in compatibility packages for popular i18n libraries, support for Collections and Variants, and self-hosting via Docker Compose.
|
|
6
6
|
keywords:
|
|
7
7
|
- Intlayer
|
|
8
8
|
- Compatibility
|
|
9
9
|
- Migration
|
|
10
10
|
- Collections
|
|
11
11
|
- Variants
|
|
12
|
+
- CMS SDK
|
|
13
|
+
- Self-Hosting
|
|
14
|
+
- Docker
|
|
12
15
|
- i18next
|
|
13
16
|
- next-intl
|
|
14
17
|
- vue-i18n
|
|
@@ -295,6 +298,44 @@ npm install intlayer react-native-intlayer
|
|
|
295
298
|
|
|
296
299
|
---
|
|
297
300
|
|
|
301
|
+
## CMS SDK: use Intlayer as a headless content database
|
|
302
|
+
|
|
303
|
+
Intlayer v9 ships a clean, auto-authenticating SDK in `@intlayer/api` to interact with the CMS programmatically — fetch projects, fetch dictionaries, and push or update them from your own server, scripts, or CI. Authentication (OAuth2 `client_credentials`) is handled and refreshed for you.
|
|
304
|
+
|
|
305
|
+
The SDK is split into **two separate imports** so your bundle includes only the domains you actually use:
|
|
306
|
+
|
|
307
|
+
1. `createIntlayerCMS` — a lightweight **authenticator** holding the credentials and the managed token (no domain client bundled).
|
|
308
|
+
2. `dictionaryEndpoint`, `projectEndpoint`, … — per-domain **endpoint binders**, each imported from its own subpath.
|
|
309
|
+
|
|
310
|
+
```ts fileName="cms.ts"
|
|
311
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
312
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
313
|
+
|
|
314
|
+
const cms = createIntlayerCMS();
|
|
315
|
+
|
|
316
|
+
// Read
|
|
317
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
318
|
+
|
|
319
|
+
// Write — use the CMS like a database
|
|
320
|
+
await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
> Security: the CMS credentials grant write access to your content. Only ever create the authenticator on the **server side** — never ship `clientId` / `clientSecret` to the browser.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Self-Hosting
|
|
328
|
+
|
|
329
|
+
Intlayer v9 ships first-class support for running your own Intlayer instance with a single command — no Intlayer Cloud account required.
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
The installer downloads a `docker-compose.yml` and a `.env`, auto-generates the required secrets, and runs `docker compose up -d`. Everything — the dashboard, the API, the database, object storage, and transactional email — runs locally in containers.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
298
339
|
## Migration notes from v8
|
|
299
340
|
|
|
300
341
|
If you are upgrading from v8, note that the v9 does not include breaking changes. But here are the key changes:
|
|
@@ -313,3 +354,5 @@ If you are upgrading from v8, note that the v9 does not include breaking changes
|
|
|
313
354
|
- [Dynamic Dictionaries - Collections & Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dynamic_dictionaries/index.md)
|
|
314
355
|
- [Configuration Reference](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md)
|
|
315
356
|
- [React Native & Expo Guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_react_native+expo.md)
|
|
357
|
+
- [CMS SDK - Programmatic access with @intlayer/api](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)
|
|
358
|
+
- [Self-Hosting Guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/self_hosting.md)
|