@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: Self-Hosting Intlayer
|
|
5
|
+
description: Run a complete Intlayer instance on your own infrastructure with a single command. No Intlayer Cloud account required.
|
|
6
|
+
keywords:
|
|
7
|
+
- Self-Hosting
|
|
8
|
+
- Docker
|
|
9
|
+
- Docker Compose
|
|
10
|
+
- Intlayer
|
|
11
|
+
- CMS
|
|
12
|
+
- Installation
|
|
13
|
+
- Infrastructure
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- self-hosting
|
|
17
|
+
author: aymericzip
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Self-Hosting Intlayer
|
|
21
|
+
|
|
22
|
+
Intlayer can run entirely on your own infrastructure — no Intlayer Cloud account required. A single command boots a production-ready stack:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The installer downloads a `docker-compose.yml` and a `.env`, auto-generates the required secrets, and starts all containers with `docker compose up -d`.
|
|
29
|
+
|
|
30
|
+
## Table of Contents
|
|
31
|
+
|
|
32
|
+
<TOC/>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
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 (used for Puppeteer screenshot generation) is bundled inside the backend image — no separate container is needed.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Prerequisites
|
|
58
|
+
|
|
59
|
+
- **Docker** ≥ 24 and **Docker Compose** ≥ v2. If either is missing, the installer prints the install link and exits.
|
|
60
|
+
- Ports `3000`, `3100`, `8025`, `9000`, and `9001` available on the host.
|
|
61
|
+
- A Linux or macOS host (or WSL2 on Windows).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
What the installer does:
|
|
72
|
+
|
|
73
|
+
1. Checks that `docker` and `docker compose` are present.
|
|
74
|
+
2. Downloads `docker-compose.yml` and `.env.example` into `./intlayer/`.
|
|
75
|
+
3. If no `.env` exists, copies the example and generates random secrets for `BETTER_AUTH_SECRET`, `S3_ACCESS_KEY_ID`, and `S3_SECRET_ACCESS_KEY` via `openssl rand`.
|
|
76
|
+
4. Runs `docker compose pull` + `docker compose up -d`.
|
|
77
|
+
5. Prints the URLs: dashboard `:3000`, API `:3100`, email UI `:8025`, MinIO console `:9001`.
|
|
78
|
+
|
|
79
|
+
After the stack is up, open **http://localhost:3000** and create your first account.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Services
|
|
84
|
+
|
|
85
|
+
| Service | Image | Host port(s) | Purpose |
|
|
86
|
+
| ----------- | ------------------------------------ | ------------------------------ | -------------------------------------------------------- |
|
|
87
|
+
| **app** | built from `apps/app/Dockerfile` | `3000` | TanStack Start dashboard (CMS UI) |
|
|
88
|
+
| **backend** | built from `apps/backend/Dockerfile` | `3100` | Fastify REST API (`/health` endpoint) |
|
|
89
|
+
| **mongo** | `mongo:7` | internal | Single-node replica set (`rs0`) |
|
|
90
|
+
| **redis** | `redis:7-alpine` | internal | Job queues (BullMQ) and caching (ioredis) |
|
|
91
|
+
| **minio** | `minio/minio` | `9000` (S3), `9001` (console) | S3-compatible object storage for avatars and screenshots |
|
|
92
|
+
| **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (web UI) | Local transactional email sink |
|
|
93
|
+
|
|
94
|
+
Internal ports (mongo, redis) are not exposed to the host by default.
|
|
95
|
+
|
|
96
|
+
> MinIO port `9000` must be reachable by the browser because uploaded assets (avatars, screenshots) are loaded directly from `S3_PUBLIC_URL=http://localhost:9000/intlayer`.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Environment variables
|
|
101
|
+
|
|
102
|
+
The installer generates a ready-to-use `.env`. The table below describes every variable.
|
|
103
|
+
|
|
104
|
+
### Required (auto-generated or prompted)
|
|
105
|
+
|
|
106
|
+
| Variable | Example | Description |
|
|
107
|
+
| ---------------------- | ----------------------------------------------- | -------------------------------------------------- |
|
|
108
|
+
| `NODE_ENV` | `production` | Runtime environment |
|
|
109
|
+
| `PORT` | `3100` | Backend listening port |
|
|
110
|
+
| `BACKEND_URL` | `http://localhost:3100` | Public URL of the backend API |
|
|
111
|
+
| `APP_URL` | `http://localhost:3000` | Public URL of the dashboard |
|
|
112
|
+
| `DOMAIN` | `localhost` | Cookie domain |
|
|
113
|
+
| `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | Full MongoDB connection URI |
|
|
114
|
+
| `REDIS_URL` | `redis://redis:6379` | Redis connection URL |
|
|
115
|
+
| `BETTER_AUTH_SECRET` | _(generated)_ | 32-byte secret for session signing |
|
|
116
|
+
| `MAIL_PROVIDER` | `smtp` | Mail transport: `smtp` or `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>` | Sender address |
|
|
120
|
+
| `S3_ENDPOINT` | `http://minio:9000` | S3-compatible endpoint |
|
|
121
|
+
| `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | Public URL for browser asset loading |
|
|
122
|
+
| `S3_BUCKET_NAME` | `intlayer` | Bucket name |
|
|
123
|
+
| `S3_ACCESS_KEY_ID` | _(generated)_ | MinIO access key |
|
|
124
|
+
| `S3_SECRET_ACCESS_KEY` | _(generated)_ | MinIO secret key |
|
|
125
|
+
| `VITE_BACKEND_URL` | `http://localhost:3100` | Backend URL baked into the dashboard at build time |
|
|
126
|
+
| `VITE_DOMAIN` | `localhost` | Domain baked into the dashboard at build time |
|
|
127
|
+
|
|
128
|
+
### Optional (features degrade gracefully when absent)
|
|
129
|
+
|
|
130
|
+
| Variable | Feature |
|
|
131
|
+
| -------------------------------------------------------- | ----------------------------------------------------------- |
|
|
132
|
+
| `OPENAI_API_KEY` | AI-assisted translation and content audit |
|
|
133
|
+
| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Billing and subscription management |
|
|
134
|
+
| `RESEND_API_KEY` | Transactional email via Resend (overrides Mailpit when set) |
|
|
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
|
+
## Connecting your Intlayer project
|
|
145
|
+
|
|
146
|
+
Once the stack is running, point your project at the self-hosted backend and dashboard instead of `intlayer.org`.
|
|
147
|
+
|
|
148
|
+
### Project configuration
|
|
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 of the self-hosted CMS dashboard.
|
|
160
|
+
* Default: https://app.intlayer.org
|
|
161
|
+
*/
|
|
162
|
+
cmsURL: process.env.INTLAYER_CMS_URL, // e.g. http://localhost:3000
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* URL of the self-hosted backend API.
|
|
166
|
+
* Default: 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
|
+
Set the environment variables in your project's `.env`:
|
|
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
|
+
Create access credentials in your self-hosted dashboard under **Projects → Access keys** at `http://localhost:3000/projects`.
|
|
185
|
+
|
|
186
|
+
### `@intlayer/api` SDK
|
|
187
|
+
|
|
188
|
+
When using the `@intlayer/api` SDK programmatically, pass `backendURL` explicitly:
|
|
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
|
+
## Upgrading
|
|
208
|
+
|
|
209
|
+
Re-running the installer on an existing deployment performs a rolling upgrade:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
This pulls the latest images and restarts containers with `docker compose pull && docker compose up -d`. Existing volumes (`mongo-data`, `redis-data`, `minio-data`) are preserved — no data loss.
|
|
216
|
+
|
|
217
|
+
To upgrade manually from inside the `./intlayer/` directory:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
docker compose pull
|
|
221
|
+
docker compose up -d
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Backup and restore
|
|
227
|
+
|
|
228
|
+
All persistent data lives in three named 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
|
+
### Restore
|
|
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
|
+
# Repeat for redis-data and minio-data
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Using a reverse proxy (Nginx / Caddy)
|
|
263
|
+
|
|
264
|
+
For production deployments, place a reverse proxy in front of the app and backend containers instead of exposing them directly.
|
|
265
|
+
|
|
266
|
+
### Nginx example
|
|
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
|
+
Update the following `.env` variables to match your public domains:
|
|
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_*` variables are baked into the dashboard image at build time. If you change them after the image is built, you need to rebuild the `app` image (`docker compose build app`) or use runtime config injection.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Troubleshooting
|
|
307
|
+
|
|
308
|
+
### Backend crash-loops on first start
|
|
309
|
+
|
|
310
|
+
MongoDB and Redis must be healthy before the backend starts. The compose file uses `depends_on` with `condition: service_healthy`. If you see repeated backend restarts, check that the `mongo` and `redis` healthchecks pass:
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
docker compose ps
|
|
314
|
+
docker compose logs mongo
|
|
315
|
+
docker compose logs redis
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Dashboard cannot reach the API
|
|
319
|
+
|
|
320
|
+
Verify that `VITE_BACKEND_URL` matches the URL where the backend is reachable from the **browser** (not the Docker network). If you changed the backend port or added a reverse proxy, rebuild the dashboard image:
|
|
321
|
+
|
|
322
|
+
```sh
|
|
323
|
+
docker compose build app
|
|
324
|
+
docker compose up -d app
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Email not sending
|
|
328
|
+
|
|
329
|
+
By default, all outbound email is captured by Mailpit. Open `http://localhost:8025` to see sent messages. To send real email, set `MAIL_PROVIDER=resend` and `RESEND_API_KEY=<your-key>` in `.env`, then restart the backend:
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
docker compose restart backend
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### MinIO bucket missing
|
|
336
|
+
|
|
337
|
+
If the `minio-init` one-shot service didn't run (or ran before MinIO was ready), create the bucket manually:
|
|
338
|
+
|
|
339
|
+
```sh
|
|
340
|
+
docker compose run --rm minio-init
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Useful links
|
|
346
|
+
|
|
347
|
+
- [Intlayer CMS documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_CMS.md)
|
|
348
|
+
- [Configuration reference](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/configuration.md)
|
|
349
|
+
- [CMS SDK — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_CMS.md#programmatic-access-with-the-intlayerapi-sdk)
|
package/docs/es/intlayer_CMS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-06-30
|
|
4
4
|
title: Intlayer CMS | Externaliza tu contenido en el Intlayer CMS
|
|
5
5
|
description: Externaliza tu contenido en el Intlayer CMS para delegar la gestión de tu contenido a tu equipo.
|
|
6
6
|
keywords:
|
|
@@ -18,6 +18,9 @@ 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: "Añadida sección de Auto-alojamiento: bootstrap Docker Compose, inventario de servicios, configuración SDK, características opcionales y notas de actualización"
|
|
21
24
|
- version: 6.0.1
|
|
22
25
|
date: 2025-09-22
|
|
23
26
|
changes: "Añadida documentación de sincronización en vivo"
|
|
@@ -385,6 +388,119 @@ Notas y restricciones:
|
|
|
385
388
|
|
|
386
389
|
- El editor visual utiliza un iframe para mostrar tu sitio web. Asegúrate de que la Política de Seguridad de Contenidos (CSP) de tu sitio web permita la URL del CMS como `frame-ancestors` ('https://app.intlayer.org' por defecto). Revisa la consola del editor para cualquier error.
|
|
387
390
|
|
|
391
|
+
## Auto-alojamiento
|
|
392
|
+
|
|
393
|
+
Intlayer puede ejecutarse completamente en tu propia infraestructura — no se requiere cuenta de Intlayer Cloud. Un solo comando arranca toda la pila (panel de control, API, base de datos, almacenamiento de objetos y correo electrónico) mediante Docker Compose:
|
|
394
|
+
|
|
395
|
+
```sh
|
|
396
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Esto descarga un `docker-compose.yml` y un `.env`, genera automáticamente los secretos necesarios (`BETTER_AUTH_SECRET`, credenciales de MinIO) y arranca todos los contenedores con `docker compose up -d`. Volver a ejecutar el mismo comando en una instalación existente realiza una actualización progresiva sin pérdida de datos.
|
|
400
|
+
|
|
401
|
+
### Servicios iniciados
|
|
402
|
+
|
|
403
|
+
| Servicio | Puerto(s) | Propósito |
|
|
404
|
+
| -------------------------- | ------------------------------------ | ----------------------------------------------------- |
|
|
405
|
+
| **app** (panel de control) | `3000` | Interfaz CMS TanStack Start |
|
|
406
|
+
| **backend** (API) | `3100` | API REST Fastify |
|
|
407
|
+
| **MongoDB 7** | interno | Base de datos principal (replica set de un solo nodo) |
|
|
408
|
+
| **Redis 7** | interno | Colas de trabajos y caché |
|
|
409
|
+
| **MinIO** | `9000` (S3), `9001` (consola) | Almacenamiento de objetos compatible con S3 |
|
|
410
|
+
| **Mailpit** | `1025` (SMTP), `8025` (interfaz web) | Sumidero local de correo transaccional |
|
|
411
|
+
|
|
412
|
+
Chromium (para la generación de capturas de pantalla con Puppeteer) está incluido en la imagen del backend — no se necesita ningún contenedor adicional.
|
|
413
|
+
|
|
414
|
+
### Conectar tu proyecto a una instancia auto-alojada
|
|
415
|
+
|
|
416
|
+
Apunta tu configuración de Intlayer a tu propio backend y panel de control en lugar de `intlayer.org`:
|
|
417
|
+
|
|
418
|
+
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
419
|
+
import type { IntlayerConfig } from "intlayer";
|
|
420
|
+
|
|
421
|
+
const config: IntlayerConfig = {
|
|
422
|
+
editor: {
|
|
423
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
424
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* URL del panel de control CMS auto-alojado.
|
|
428
|
+
* Por defecto: https://app.intlayer.org
|
|
429
|
+
*/
|
|
430
|
+
cmsURL: process.env.INTLAYER_CMS_URL, // ej. http://localhost:3000
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* URL de la API backend auto-alojada.
|
|
434
|
+
* Por defecto: https://back.intlayer.org
|
|
435
|
+
*/
|
|
436
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // ej. http://localhost:3100
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
export default config;
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Establece las variables de entorno correspondientes en tu proyecto:
|
|
444
|
+
|
|
445
|
+
```sh
|
|
446
|
+
INTLAYER_CMS_URL=http://localhost:3000
|
|
447
|
+
INTLAYER_BACKEND_URL=http://localhost:3100
|
|
448
|
+
INTLAYER_CLIENT_ID=<your-client-id>
|
|
449
|
+
INTLAYER_CLIENT_SECRET=<your-client-secret>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Crea credenciales de acceso en tu panel de control auto-alojado en `http://localhost:3000/projects`.
|
|
453
|
+
|
|
454
|
+
### SDK `@intlayer/api`: apuntar a un backend auto-alojado
|
|
455
|
+
|
|
456
|
+
Al usar el SDK de forma programática, pasa `backendURL` explícitamente a `createIntlayerCMS`:
|
|
457
|
+
|
|
458
|
+
```typescript fileName="cms.ts" codeFormat="typescript"
|
|
459
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
460
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
461
|
+
|
|
462
|
+
const cms = createIntlayerCMS({
|
|
463
|
+
editor: {
|
|
464
|
+
clientId: process.env.INTLAYER_CLIENT_ID,
|
|
465
|
+
clientSecret: process.env.INTLAYER_CLIENT_SECRET,
|
|
466
|
+
backendURL: process.env.INTLAYER_BACKEND_URL, // http://localhost:3100
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### Características opcionales
|
|
474
|
+
|
|
475
|
+
Estas características requieren cuentas externas y funcionan correctamente cuando sus claves no están presentes en el `.env` auto-alojado:
|
|
476
|
+
|
|
477
|
+
| Característica | Variable(s) de entorno |
|
|
478
|
+
| -------------------------------------- | ----------------------------------------------- |
|
|
479
|
+
| Traducción / auditoría con IA | `OPENAI_API_KEY` |
|
|
480
|
+
| Facturación | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, … |
|
|
481
|
+
| OAuth de GitHub | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` |
|
|
482
|
+
| OAuth de Google | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` |
|
|
483
|
+
| OAuth de GitLab / Microsoft / LinkedIn | `GITLAB_*`, `MICROSOFT_*`, `LINKEDIN_*` |
|
|
484
|
+
| Correo transaccional via Resend | `RESEND_API_KEY` (por defecto: Mailpit SMTP) |
|
|
485
|
+
|
|
486
|
+
### Persistencia de datos y actualizaciones
|
|
487
|
+
|
|
488
|
+
Tres volúmenes de Docker contienen todo el estado persistente: `mongo-data`, `redis-data` y `minio-data`. Sobreviven a los reinicios y actualizaciones de contenedores. Volver a ejecutar el instalador descarga las últimas imágenes y realiza un `docker compose up -d` progresivo.
|
|
489
|
+
|
|
490
|
+
Puertos expuestos en el host:
|
|
491
|
+
|
|
492
|
+
| Puerto | Servicio |
|
|
493
|
+
| ------ | ------------------------------------------------------------------- |
|
|
494
|
+
| `3000` | Panel de control |
|
|
495
|
+
| `3100` | API Backend |
|
|
496
|
+
| `8025` | Interfaz web de correo Mailpit |
|
|
497
|
+
| `9000` | API S3 de MinIO (necesaria para la carga de assets en el navegador) |
|
|
498
|
+
| `9001` | Consola de MinIO |
|
|
499
|
+
|
|
500
|
+
Para una referencia completa de todas las variables de entorno disponibles y opciones avanzadas (proxy inverso, dominios personalizados, respaldo/restauración), consulta la [Guía de Auto-alojamiento](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/self_hosting.md).
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
388
504
|
## Depuración
|
|
389
505
|
|
|
390
506
|
Si encuentras problemas con el CMS, verifica lo siguiente:
|
package/docs/es/releases/v9.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-30
|
|
4
4
|
title: Nuevo Intlayer v9 - ¿Qué hay de nuevo?
|
|
5
5
|
description: Descubre las novedades de Intlayer v9. Presentamos paquetes de compatibilidad directos para librerías i18n populares y soporte para Colecciones y Variantes.
|
|
6
6
|
keywords:
|
|
@@ -9,6 +9,9 @@ keywords:
|
|
|
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,13 +298,68 @@ npm install intlayer react-native-intlayer
|
|
|
295
298
|
|
|
296
299
|
---
|
|
297
300
|
|
|
301
|
+
## SDK de CMS: usa Intlayer como una base de datos de contenido headless
|
|
302
|
+
|
|
303
|
+
Intlayer v9 incluye un SDK limpio y con autenticación automática en `@intlayer/api` para interactuar con el CMS de forma programática: obtener proyectos, obtener diccionarios y enviarlos o actualizarlos desde tu propio servidor, scripts o CI. La autenticación (OAuth2 `client_credentials`) se gestiona y renueva por ti.
|
|
304
|
+
|
|
305
|
+
El SDK se divide en **dos importaciones separadas** para que tu bundle incluya solo los dominios que realmente usas:
|
|
306
|
+
|
|
307
|
+
1. `createIntlayerCMS` — un **autenticador** ligero que contiene las credenciales y el token gestionado (sin ningún cliente de dominio incluido).
|
|
308
|
+
2. `dictionaryEndpoint`, `projectEndpoint`, … — **enlazadores de endpoint** por dominio, cada uno importado desde su propia subruta.
|
|
309
|
+
|
|
310
|
+
```ts fileName="cms.ts"
|
|
311
|
+
import { createIntlayerCMS } from "@intlayer/api";
|
|
312
|
+
import { dictionaryEndpoint } from "@intlayer/api/dictionary";
|
|
313
|
+
|
|
314
|
+
// La configuración es opcional: las credenciales recurren a INTLAYER_CLIENT_ID /
|
|
315
|
+
// INTLAYER_CLIENT_SECRET resueltos por `@intlayer/config/built`.
|
|
316
|
+
const cms = createIntlayerCMS();
|
|
317
|
+
|
|
318
|
+
// Lectura
|
|
319
|
+
const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
|
|
320
|
+
|
|
321
|
+
// Escritura — usa el CMS como una base de datos
|
|
322
|
+
await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
> Seguridad: las credenciales del CMS otorgan acceso de escritura a tu contenido. Crea el autenticador siempre **en el lado del servidor** — nunca envíes `clientId` / `clientSecret` al navegador.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Auto-alojamiento
|
|
330
|
+
|
|
331
|
+
Intlayer v9 incluye soporte de primera clase para ejecutar tu propia instancia de Intlayer con un solo comando — sin necesidad de cuenta en Intlayer Cloud.
|
|
332
|
+
|
|
333
|
+
```sh
|
|
334
|
+
curl -fsSL https://intlayer.org/install.sh | sh
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
El instalador descarga un `docker-compose.yml` y un `.env`, genera automáticamente los secretos necesarios y ejecuta `docker compose up -d`. Todo — el panel de control, la API, la base de datos, el almacenamiento de objetos y el correo electrónico transaccional — se ejecuta localmente en contenedores.
|
|
338
|
+
|
|
339
|
+
### Servicios incluidos
|
|
340
|
+
|
|
341
|
+
| Servicio | Propósito |
|
|
342
|
+
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
|
343
|
+
| **app** (TanStack Start) | Interfaz del panel de control en el puerto `3000` |
|
|
344
|
+
| **backend** (Fastify/Bun) | API REST en el puerto `3100` |
|
|
345
|
+
| **MongoDB 7** (single-node replica set) | Base de datos principal |
|
|
346
|
+
| **Redis 7** | Colas de trabajos y caché |
|
|
347
|
+
| **MinIO** | Almacenamiento de objetos compatible con S3 (avatares, capturas de pantalla) |
|
|
348
|
+
| **Mailpit** | Sumidero SMTP local + interfaz web para correo transaccional en el puerto `8025` |
|
|
349
|
+
|
|
350
|
+
Chromium (usado para la generación de capturas de pantalla con Puppeteer) está incluido dentro de la imagen del backend — no se necesita ningún contenedor adicional.
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
298
354
|
## Notas de migración desde v8
|
|
299
355
|
|
|
300
356
|
Si estás actualizando desde v8, ten en cuenta que la v9 no incluye cambios disruptivos. Pero aquí están los cambios clave:
|
|
301
357
|
|
|
302
358
|
- **Compilador deshabilitado por defecto**: `compiler.enabled` ahora tiene el valor predeterminado `false`. Si dependes de la extracción de tus archivos `.content.ts` en tiempo de compilación, establece `compiler.enabled: true` en tu `intlayer.config.ts`.
|
|
359
|
+
- **Plugin de Vite**: El compilador y el proxy de enrutamiento de locales ahora están integrados en `intlayer()`. Si previamente registraste `intlayerCompiler()` o `intlayerProxy()` manualmente, puedes eliminarlos — se deduplicanautomáticamente, por lo que mantenerlos es inofensivo. Usa `routing.enableProxy: false` para desactivar el proxy.
|
|
303
360
|
- **Locales y Dialectos**: Si utilizas dependencias i18n externas, añade sus respectivos plugins adaptadores de compatibilidad en tu configuración o setup del bundler para reescribir automáticamente los imports.
|
|
304
361
|
- **Selectores Personalizados**: Al llamar a `useIntlayer`, el segundo parámetro ahora está reservado para un objeto de opciones que contiene `{ locale, item, variant }`. Si anteriormente pasabas una cadena de locale directamente, aún puedes hacerlo, pero se recomienda usar el objeto de opciones para selecciones avanzadas.
|
|
362
|
+
- **React Native**: `react-native-intlayer` ahora reexporta toda la API de `react-intlayer`. En una aplicación React Native, importa todo desde `react-native-intlayer` y elimina la dependencia directa a `react-intlayer`. Los imports existentes de `react-intlayer` siguen funcionando.
|
|
305
363
|
|
|
306
364
|
---
|
|
307
365
|
|
|
@@ -310,3 +368,5 @@ Si estás actualizando desde v8, ten en cuenta que la v9 no incluye cambios disr
|
|
|
310
368
|
- [Guía de Paquetes Adaptadores de Compatibilidad](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/compat/index.md)
|
|
311
369
|
- [Diccionarios Dinámicos - Colecciones y Variantes](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/index.md)
|
|
312
370
|
- [Referencia de Configuración](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/configuration.md)
|
|
371
|
+
- [SDK de CMS - Acceso programático con @intlayer/api](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/intlayer_CMS.md)
|
|
372
|
+
- [Guía de Auto-alojamiento](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/self_hosting.md)
|