{
  "slug": "side-by-side-editing",
  "title": "Side-by-Side Translation Editing",
  "description": "Edit source and translation simultaneously in a split-screen editor — the killer feature for multilingual content.",
  "category": "guides",
  "order": 13,
  "locale": "en",
  "translationGroup": "c06d4468-937b-4811-b98c-8672b8a76ecb",
  "helpCardId": null,
  "content": "## The problem with traditional translation workflows\n\nMost CMS platforms treat translation as an afterthought. You write content in one language, export it, send it to a translator (or an AI), import the result, and hope nothing breaks. You can't see source and translation together. You can't compare paragraph by paragraph. And when you update the source, you have no idea which translations are stale.\n\n## Side-by-side editing\n\n![Side-by-side translation editing](/screenshots/side-by-side-full.png)\n\n@webhouse/cms solves this with a built-in split-screen editor. Open any document that has translations, click **Side-by-side**, and you see source and translation side by side — field by field, paragraph by paragraph.\n\n### What you see\n\nThe editor splits into two panels:\n\n- **Left panel** — the translation you're editing (e.g. Danish)\n- **Right panel** — the source document (e.g. English), read-only for reference\n\nBoth panels show the same fields in the same order: title, description, content, and all custom fields. You scroll them together. You compare them line by line.\n\n### How to use it\n\n1. Open any document in the editor\n2. If translations exist, you'll see a **TRANSLATIONS** bar at the top showing linked locale versions\n3. Click **Side-by-side** to enter split-screen mode\n4. The source language appears on the right, your translation on the left\n5. Edit the translation while reading the source — no tab switching, no copy-pasting\n\n### Translation groups make it work\n\nThe magic behind side-by-side editing is the `translationGroup` field. Every document that is a translation of another shares the same UUID:\n\n```json\n// English source\n{\n  \"slug\": \"getting-started\",\n  \"locale\": \"en\",\n  \"translationGroup\": \"a1b2c3d4-...\"\n}\n\n// Danish translation\n{\n  \"slug\": \"getting-started-da\",\n  \"locale\": \"da\",\n  \"translationGroup\": \"a1b2c3d4-...\"\n}\n```\n\nCMS admin reads the `translationGroup` and finds all documents that share it. That's how it knows which documents are translations of each other — and how it can show them side by side.\n\n## Creating translations\n\n### From the editor\n\n1. Open a document\n2. Click **+ Add translation** in the translations bar\n3. Choose the target locale (e.g. Danish)\n4. The CMS creates a new document with:\n   - A slug based on the source (e.g. `getting-started-da`)\n   - The same `translationGroup` UUID\n   - AI-translated content (if an AI provider is configured)\n5. The new translation opens in the editor, ready for review\n\n### From a script\n\n```typescript\nimport { randomUUID } from 'crypto';\n\n// Create the source document\nconst sourceDoc = {\n  slug: \"my-page\",\n  locale: \"en\",\n  translationGroup: randomUUID(),\n  status: \"published\",\n  data: { title: \"My Page\", content: \"Hello world\" },\n};\n\n// Create the translation with the SAME translationGroup\nconst translationDoc = {\n  slug: \"my-page-da\",\n  locale: \"da\",\n  translationGroup: sourceDoc.translationGroup, // ← same UUID!\n  status: \"published\",\n  data: { title: \"Min side\", content: \"Hej verden\" },\n};\n```\n\n### Via AI\n\n```bash\n# The CMS AI agent can translate documents automatically\nnpx cms ai rewrite posts/hello-world \"Translate to Danish\"\n```\n\nOr use the built-in translation agent from the admin UI — it respects field types, preserves markdown formatting, and links the new document with the correct `translationGroup`.\n\n## Locale strategy\n\nHow locales appear in URLs depends on your site's `localeStrategy` setting:\n\n| Strategy | English URL | Danish URL | Best for |\n|----------|-------------|------------|----------|\n| `prefix-other` | `/blog/my-post` | `/da/blog/my-post` | Most sites |\n| `prefix-all` | `/en/blog/my-post` | `/da/blog/my-post` | Explicit locale |\n| `none` | `/blog/my-post` | `/blog/my-post-da` | Locale in slug |\n\nConfigure in CMS admin → Site Settings → Language.\n\n## Why this matters\n\n### For content teams\n- No context switching between tabs or windows\n- See exactly what the source says while you translate\n- Catch mismatches instantly (missing paragraphs, wrong tone, outdated sections)\n\n### For developers\n- `translationGroup` is a simple UUID — no complex relational schema\n- Documents are independent files — no parent/child coupling\n- Works with any storage adapter (filesystem, GitHub, SQLite, Supabase)\n- Easy to script: just share the UUID between documents\n\n### For AI agents\n- AI translation agents create properly linked documents automatically\n- The translation agent reads the source via `translationGroup`, translates field by field\n- AI Lock ensures human-edited translations are never overwritten by AI\n\n## Configuration\n\n### cms.config.ts\n\n```typescript\ndefineCollection({\n  name: 'posts',\n  label: 'Blog Posts',\n  sourceLocale: 'en',\n  locales: ['en', 'da'],\n  fields: [\n    { name: 'title', type: 'text', required: true },\n    { name: 'content', type: 'richtext' },\n  ],\n})\n```\n\n### Site settings\n\n- **Default language**: English (en)\n- **Supported languages**: add Danish (da), or any BCP 47 locale\n- **Locale strategy**: choose how URLs are structured\n\nThat's it. No plugins, no third-party translation management. Just `translationGroup` and the built-in editor.",
  "excerpt": "The problem with traditional translation workflows\n\nMost CMS platforms treat translation as an afterthought. You write content in one language, export it, send it to a translator (or an AI), import the result, and hope nothing breaks. You can't see source and translation together. You can't compare ",
  "seo": {
    "metaTitle": "Side-by-Side Translation Editing — webhouse.app Docs",
    "metaDescription": "Edit source and translation simultaneously in a split-screen editor — the killer feature for multilingual content."
  },
  "createdAt": "2026-03-30T19:08:49.344Z",
  "updatedAt": "2026-03-30T19:08:49.345Z"
}