@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.
Files changed (63) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +20 -0
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +20 -0
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +1 -0
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/intlayer_CMS.md +16 -1
  8. package/docs/ar/releases/v9.md +58 -1
  9. package/docs/ar/self_hosting.md +349 -0
  10. package/docs/bn/intlayer_CMS.md +570 -0
  11. package/docs/bn/releases/v9.md +358 -0
  12. package/docs/cs/releases/v9.md +358 -0
  13. package/docs/de/intlayer_CMS.md +117 -1
  14. package/docs/de/releases/v9.md +61 -1
  15. package/docs/de/self_hosting.md +349 -0
  16. package/docs/en/intlayer_CMS.md +171 -1
  17. package/docs/en/releases/v9.md +45 -2
  18. package/docs/en/self_hosting.md +349 -0
  19. package/docs/en-GB/intlayer_CMS.md +16 -1
  20. package/docs/en-GB/releases/v9.md +47 -2
  21. package/docs/en-GB/self_hosting.md +349 -0
  22. package/docs/es/intlayer_CMS.md +117 -1
  23. package/docs/es/releases/v9.md +61 -1
  24. package/docs/es/self_hosting.md +349 -0
  25. package/docs/fr/intlayer_CMS.md +117 -1
  26. package/docs/fr/releases/v9.md +61 -1
  27. package/docs/fr/self_hosting.md +349 -0
  28. package/docs/hi/intlayer_CMS.md +16 -1
  29. package/docs/hi/releases/v9.md +59 -1
  30. package/docs/hi/self_hosting.md +349 -0
  31. package/docs/id/releases/v9.md +31 -1
  32. package/docs/id/self_hosting.md +349 -0
  33. package/docs/it/intlayer_CMS.md +117 -1
  34. package/docs/it/releases/v9.md +61 -1
  35. package/docs/it/self_hosting.md +349 -0
  36. package/docs/ja/intlayer_CMS.md +191 -10
  37. package/docs/ja/releases/v9.md +31 -1
  38. package/docs/ja/self_hosting.md +349 -0
  39. package/docs/ko/intlayer_CMS.md +189 -6
  40. package/docs/ko/releases/v9.md +30 -1
  41. package/docs/ko/self_hosting.md +349 -0
  42. package/docs/nl/releases/v9.md +358 -0
  43. package/docs/pl/intlayer_CMS.md +16 -1
  44. package/docs/pl/releases/v9.md +58 -1
  45. package/docs/pl/self_hosting.md +349 -0
  46. package/docs/pt/intlayer_CMS.md +117 -1
  47. package/docs/pt/releases/v9.md +61 -1
  48. package/docs/pt/self_hosting.md +349 -0
  49. package/docs/ru/intlayer_CMS.md +196 -15
  50. package/docs/ru/releases/v9.md +59 -1
  51. package/docs/ru/self_hosting.md +349 -0
  52. package/docs/tr/intlayer_CMS.md +16 -1
  53. package/docs/tr/releases/v9.md +46 -1
  54. package/docs/tr/self_hosting.md +349 -0
  55. package/docs/uk/intlayer_CMS.md +16 -1
  56. package/docs/uk/releases/v9.md +58 -1
  57. package/docs/uk/self_hosting.md +349 -0
  58. package/docs/vi/releases/v9.md +31 -1
  59. package/docs/vi/self_hosting.md +349 -0
  60. package/docs/zh/releases/v9.md +31 -1
  61. package/docs/zh/self_hosting.md +349 -0
  62. package/package.json +6 -6
  63. 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 на власному сервері
5
+ description: Запустіть повний екземпляр Intlayer на власній інфраструктурі за допомогою однієї команди. Обліковий запис Intlayer Cloud не потрібен.
6
+ keywords:
7
+ - Самостійне розгортання
8
+ - Docker
9
+ - Docker Compose
10
+ - Intlayer
11
+ - CMS
12
+ - Встановлення
13
+ - Інфраструктура
14
+ slugs:
15
+ - doc
16
+ - self-hosting
17
+ author: aymericzip
18
+ ---
19
+
20
+ # Розгортання Intlayer на власному сервері
21
+
22
+ Intlayer може повністю працювати на вашій власній інфраструктурі — обліковий запис Intlayer Cloud не потрібен. Одна команда запускає готовий до виробництва стек:
23
+
24
+ ```sh
25
+ curl -fsSL https://intlayer.org/install.sh | sh
26
+ ```
27
+
28
+ Інсталятор завантажує `docker-compose.yml` та `.env`, автоматично генерує необхідні секрети та запускає всі контейнери за допомогою `docker compose up -d`.
29
+
30
+ ## Зміст
31
+
32
+ <TOC/>
33
+
34
+ ---
35
+
36
+ ## Архітектура
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 (використовується для генерації скріншотів Puppeteer) вбудований в образ бекенду — окремий контейнер не потрібен.
54
+
55
+ ---
56
+
57
+ ## Передумови
58
+
59
+ - **Docker** ≥ 24 та **Docker Compose** ≥ v2. Якщо чогось бракує, інсталятор виводить посилання на встановлення та завершує роботу.
60
+ - Порти `3000`, `3100`, `8025`, `9000` та `9001` доступні на хості.
61
+ - Хост Linux або macOS (або WSL2 на Windows).
62
+
63
+ ---
64
+
65
+ ## Швидкий старт
66
+
67
+ ```sh
68
+ curl -fsSL https://intlayer.org/install.sh | sh
69
+ ```
70
+
71
+ Що робить інсталятор:
72
+
73
+ 1. Перевіряє наявність `docker` та `docker compose`.
74
+ 2. Завантажує `docker-compose.yml` та `.env.example` до `./intlayer/`.
75
+ 3. Якщо файл `.env` не існує, копіює приклад та генерує випадкові секрети для `BETTER_AUTH_SECRET`, `S3_ACCESS_KEY_ID` та `S3_SECRET_ACCESS_KEY` за допомогою `openssl rand`.
76
+ 4. Запускає `docker compose pull` + `docker compose up -d`.
77
+ 5. Виводить URL-адреси: дашборд `:3000`, API `:3100`, інтерфейс електронної пошти `:8025`, консоль MinIO `:9001`.
78
+
79
+ Після запуску стека відкрийте **http://localhost:3000** та створіть свій перший обліковий запис.
80
+
81
+ ---
82
+
83
+ ## Сервіси
84
+
85
+ | Сервіс | Образ | Порт(и) хосту | Призначення |
86
+ | ----------- | ----------------------------------- | ------------------------------------- | ---------------------------------------------------------- |
87
+ | **app** | зібрано з `apps/app/Dockerfile` | `3000` | Панель приладів TanStack Start (інтерфейс CMS) |
88
+ | **backend** | зібрано з `apps/backend/Dockerfile` | `3100` | REST API Fastify (кінцева точка `/health`) |
89
+ | **mongo** | `mongo:7` | внутрішній | Однонодовий реплікасет (`rs0`) |
90
+ | **redis** | `redis:7-alpine` | внутрішній | Черги завдань (BullMQ) та кешування (ioredis) |
91
+ | **minio** | `minio/minio` | `9000` (S3), `9001` (консоль) | Об'єктне сховище, сумісне з S3, для аватарів та скріншотів |
92
+ | **mailpit** | `axllent/mailpit` | `1025` (SMTP), `8025` (веб-інтерфейс) | Локальний приймач транзакційних електронних листів |
93
+
94
+ Внутрішні порти (mongo, redis) за замовчуванням не доступні з хосту.
95
+
96
+ > Порт MinIO `9000` має бути доступним для браузера, оскільки завантажені ресурси (аватари, скріншоти) завантажуються безпосередньо з `S3_PUBLIC_URL=http://localhost:9000/intlayer`.
97
+
98
+ ---
99
+
100
+ ## Змінні середовища
101
+
102
+ Інсталятор генерує готовий до використання файл `.env`. Таблиця нижче описує кожну змінну.
103
+
104
+ ### Обов'язкові (автоматично генеруються або запитуються)
105
+
106
+ | Змінна | Приклад | Опис |
107
+ | ---------------------- | ----------------------------------------------- | ------------------------------------------------------- |
108
+ | `NODE_ENV` | `production` | Середовище виконання |
109
+ | `PORT` | `3100` | Порт прослуховування бекенду |
110
+ | `BACKEND_URL` | `http://localhost:3100` | Публічна URL-адреса API бекенду |
111
+ | `APP_URL` | `http://localhost:3000` | Публічна URL-адреса дашборду |
112
+ | `DOMAIN` | `localhost` | Домен для cookie |
113
+ | `MONGODB_URI` | `mongodb://mongo:27017/intlayer?replicaSet=rs0` | Повний URI підключення до MongoDB |
114
+ | `REDIS_URL` | `redis://redis:6379` | URL підключення до Redis |
115
+ | `BETTER_AUTH_SECRET` | _(згенеровано)_ | 32-байтовий секрет для підпису сесії |
116
+ | `MAIL_PROVIDER` | `smtp` | Транспорт пошти: `smtp` або `resend` |
117
+ | `MAIL_SMTP_HOST` | `mailpit` | Ім'я хосту SMTP (ім'я контейнера Mailpit) |
118
+ | `MAIL_SMTP_PORT` | `1025` | Порт SMTP |
119
+ | `MAIL_FROM` | `Intlayer <no-reply@localhost>` | Адреса відправника |
120
+ | `S3_ENDPOINT` | `http://minio:9000` | Кінцева точка, сумісна з S3 |
121
+ | `S3_PUBLIC_URL` | `http://localhost:9000/intlayer` | Публічна URL-адреса для завантаження ресурсів браузером |
122
+ | `S3_BUCKET_NAME` | `intlayer` | Ім'я кошика |
123
+ | `S3_ACCESS_KEY_ID` | _(згенеровано)_ | Ключ доступу MinIO |
124
+ | `S3_SECRET_ACCESS_KEY` | _(згенеровано)_ | Секретний ключ MinIO |
125
+ | `VITE_BACKEND_URL` | `http://localhost:3100` | URL-адреса бекенду, вбудована в дашборд під час збірки |
126
+ | `VITE_DOMAIN` | `localhost` | Домен, вбудований в дашборд під час збірки |
127
+
128
+ ### Необов'язкові (функції погіршуються, якщо відсутні)
129
+
130
+ | Змінна | Функція |
131
+ | -------------------------------------------------------- | ----------------------------------------------------------------------------------- |
132
+ | `OPENAI_API_KEY` | Переклад та аудит контенту за допомогою ШІ |
133
+ | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_*` | Управління рахунками та підписками |
134
+ | `RESEND_API_KEY` | Транзакційна електронна пошта через Resend (перевизначає Mailpit, якщо встановлено) |
135
+ | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | Вхід через GitHub OAuth |
136
+ | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Вхід через Google OAuth |
137
+ | `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` | Вхід через GitLab OAuth |
138
+ | `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` | Вхід через Microsoft OAuth |
139
+ | `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | Вхід через LinkedIn OAuth |
140
+ | `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET` | Вхід через Atlassian OAuth |
141
+
142
+ ---
143
+
144
+ ## Підключення вашого проекту Intlayer
145
+
146
+ Після запуску стека направте свій проект на самостійно розгорнутий бекенд та дашборд замість `intlayer.org`.
147
+
148
+ ### Конфігурація проекту
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 самостійно розгорнутого дашборду CMS.
160
+ * За замовчуванням: https://app.intlayer.org
161
+ */
162
+ cmsURL: process.env.INTLAYER_CMS_URL, // наприклад, http://localhost:3000
163
+
164
+ /**
165
+ * URL самостійно розгорнутого бекенд API.
166
+ * За замовчуванням: https://back.intlayer.org
167
+ */
168
+ backendURL: process.env.INTLAYER_BACKEND_URL, // наприклад, http://localhost:3100
169
+ },
170
+ };
171
+
172
+ export default config;
173
+ ```
174
+
175
+ Встановіть змінні середовища у файлі `.env` вашого проекту:
176
+
177
+ ```sh
178
+ INTLAYER_CMS_URL=http://localhost:3000
179
+ INTLAYER_BACKEND_URL=http://localhost:3100
180
+ INTLAYER_CLIENT_ID=<ваш-client-id>
181
+ INTLAYER_CLIENT_SECRET=<ваш-client-secret>
182
+ ```
183
+
184
+ Створіть облікові дані доступу у вашому самостійно розгорнутому дашборді в розділі **Проекти → Ключі доступу** за адресою `http://localhost:3000/projects`.
185
+
186
+ ### SDK `@intlayer/api`
187
+
188
+ При програмному використанні SDK `@intlayer/api` передайте `backendURL` явно:
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
+ ## Оновлення
208
+
209
+ Повторний запуск інсталятора на існуючому розгортанні виконує послідовне оновлення:
210
+
211
+ ```sh
212
+ curl -fsSL https://intlayer.org/install.sh | sh
213
+ ```
214
+
215
+ Це завантажує останні образи та перезапускає контейнери за допомогою `docker compose pull && docker compose up -d`. Існуючі томи (`mongo-data`, `redis-data`, `minio-data`) зберігаються — без втрати даних.
216
+
217
+ Щоб оновити вручну з каталогу `./intlayer/`:
218
+
219
+ ```sh
220
+ docker compose pull
221
+ docker compose up -d
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Резервне копіювання та відновлення
227
+
228
+ Всі постійні дані зберігаються в трьох іменованих томах Docker.
229
+
230
+ ### Резервне копіювання
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
+ ### Відновлення
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
+ # Повторіть для redis-data та minio-data
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Використання зворотного проксі (Nginx / Caddy)
263
+
264
+ Для виробничих розгортань розмістіть зворотний проксі перед контейнерами застосунку та бекенду замість прямого їх виставлення.
265
+
266
+ ### Приклад Nginx
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
+ Оновіть наступні змінні `.env`, щоб вони відповідали вашим публічним доменам:
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_*` вбудовуються в образ дашборду під час збірки. Якщо ви зміните їх після збірки образу, вам потрібно перезібрати образ `app` (`docker compose build app`) або використовувати ін'єкцію конфігурації під час виконання.
303
+
304
+ ---
305
+
306
+ ## Усунення несправностей
307
+
308
+ ### Бекенд циклічно перезапускається під час першого запуску
309
+
310
+ MongoDB та Redis повинні бути справними, перш ніж бекенд почне працювати. Файл compose використовує `depends_on` з `condition: service_healthy`. Якщо ви бачите багаторазові перезапуски бекенду, перевірте, чи проходять перевірки стану `mongo` та `redis`:
311
+
312
+ ```sh
313
+ docker compose ps
314
+ docker compose logs mongo
315
+ docker compose logs redis
316
+ ```
317
+
318
+ ### Дашборд не може дістатися до API
319
+
320
+ Переконайтеся, що `VITE_BACKEND_URL` відповідає URL-адресі, за якою бекенд доступний з **браузера** (не мережі Docker). Якщо ви змінили порт бекенду або додали зворотний проксі, перезіберіть образ дашборду:
321
+
322
+ ```sh
323
+ docker compose build app
324
+ docker compose up -d app
325
+ ```
326
+
327
+ ### Електронні листи не надсилаються
328
+
329
+ За замовчуванням усі вихідні електронні листи захоплюються Mailpit. Відкрийте `http://localhost:8025`, щоб побачити надіслані повідомлення. Щоб надсилати реальні електронні листи, встановіть `MAIL_PROVIDER=resend` та `RESEND_API_KEY=<ваш-ключ>` у `.env`, а потім перезапустіть бекенд:
330
+
331
+ ```sh
332
+ docker compose restart backend
333
+ ```
334
+
335
+ ### Відсутній кошик MinIO
336
+
337
+ Якщо одноразовий сервіс `minio-init` не запустився (або запустився до того, як MinIO був готовий), створіть кошик вручну:
338
+
339
+ ```sh
340
+ docker compose run --rm minio-init
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Корисні посилання
346
+
347
+ - [Документація Intlayer CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/intlayer_CMS.md)
348
+ - [Довідка щодо конфігурації](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/configuration.md)
349
+ - [CMS SDK — `@intlayer/api`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/uk/intlayer_CMS.md#програмний-доступ-за-допомогою-intlayerapi-sdk)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2026-06-14
3
- updatedAt: 2026-06-26
3
+ updatedAt: 2026-06-29
4
4
  title: Intlayer v9 Mới - Có gì mới?
5
5
  description: Khám phá các tính năng mới trong Intlayer v9. Giới thiệu các package tương thích drop-in cho các thư viện i18n phổ biến và hỗ trợ Collections và Variants.
6
6
  keywords:
@@ -9,6 +9,7 @@ keywords:
9
9
  - Migration
10
10
  - Collections
11
11
  - Variants
12
+ - CMS SDK
12
13
  - i18next
13
14
  - next-intl
14
15
  - vue-i18n
@@ -299,6 +300,34 @@ npm install intlayer react-native-intlayer
299
300
 
300
301
  ---
301
302
 
303
+ ## CMS SDK: dùng Intlayer như một cơ sở dữ liệu nội dung headless
304
+
305
+ Intlayer v9 cung cấp một SDK gọn gàng, tự xác thực trong `@intlayer/api` để tương tác với CMS theo chương trình — lấy dự án, lấy từ điển, cũng như đẩy hoặc cập nhật chúng từ máy chủ, script hoặc CI của bạn. Việc xác thực (OAuth2 `client_credentials`) được xử lý và làm mới tự động cho bạn.
306
+
307
+ SDK được tách thành **hai import riêng biệt** để bundle của bạn chỉ bao gồm những domain bạn thực sự dùng:
308
+
309
+ 1. `createIntlayerCMS` — một **bộ xác thực** nhẹ giữ thông tin đăng nhập và token được quản lý (không đóng gói client domain nào).
310
+ 2. `dictionaryEndpoint`, `projectEndpoint`, … — các **bộ liên kết endpoint** theo từng domain, mỗi cái được import từ subpath riêng.
311
+
312
+ ```ts fileName="cms.ts"
313
+ import { createIntlayerCMS } from "@intlayer/api";
314
+ import { dictionaryEndpoint } from "@intlayer/api/dictionary";
315
+
316
+ // Cấu hình là tùy chọn: thông tin đăng nhập sẽ dùng INTLAYER_CLIENT_ID /
317
+ // INTLAYER_CLIENT_SECRET được phân giải bởi `@intlayer/config/built`.
318
+ const cms = createIntlayerCMS();
319
+
320
+ // Đọc
321
+ const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();
322
+
323
+ // Ghi — dùng CMS như một cơ sở dữ liệu
324
+ await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);
325
+ ```
326
+
327
+ > Bảo mật: thông tin đăng nhập CMS cấp quyền ghi vào nội dung của bạn. Luôn chỉ tạo bộ xác thực ở **phía máy chủ** — không bao giờ gửi `clientId` / `clientSecret` xuống trình duyệt.
328
+
329
+ ---
330
+
302
331
  ## Lưu ý khi migration từ v8
303
332
 
304
333
  Nếu bạn đang nâng cấp từ v8, lưu ý rằng v9 không bao gồm các breaking change. Tuy nhiên, dưới đây là các thay đổi chính:
@@ -314,3 +343,4 @@ Nếu bạn đang nâng cấp từ v8, lưu ý rằng v9 không bao gồm các b
314
343
  - [Hướng dẫn về Compat Adapter Packages](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/compat/index.md)
315
344
  - [Dynamic Dictionaries - Collections & Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/dynamic_dictionaries/index.md)
316
345
  - [Tài liệu tham khảo cấu hình](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/configuration.md)
346
+ - [CMS SDK - Truy cập theo chương trình với @intlayer/api](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/intlayer_CMS.md)