One Work, Two Languages

A content model that keeps the author's original visible while treating every translation as a complete, independent page.

Published
3 Jun 2026
Updated
2 Aug 2026
Reading
2 min
Tags
cms, systems, engineering
阅读中文版本

Start with the work, not the row

A bilingual article is one intellectual work with two complete presentations. The pages share an identity, but neither should become a bag of half-localized fields.

Field Shared or localized Purpose
Slug Shared Stable identity across locales
Language Per page Language of this body
Origin Language Shared Language used by the author
Title and Summary Localized Reader-facing metadata
Status Per page Independent publication control
Other Version Relation Connects the complete pages

The public lookup can stay deliberately strict:

type Locale = 'en' | 'zh'

async function findPublishedArticle(locale: Locale, slug: string) {
  return repository.find({
    language: locale,
    slug,
    status: 'Published',
  })
}

The relation helps the interface offer another language, but it must never redefine the requested page.

Editorial sequence

  • Write the origin page.
  • Create the second page with the same slug.
  • Set the same Origin Language on both pages.
  • Add reciprocal relations.
  • Review title, summary, and links in each language.
  • Publish each page independently.

Writing view

Show only pages where Language equals Origin Language. The author sees one handwritten row per work.

Publishing view

Show every locale page, relation, status, and date so missing or incomplete translations remain visible.


Adding a future Japanese version should create a third complete locale page, not another cluster of language-specific columns squeezed into an existing row.

Bojin Li

Writes about software, systems, and the parts that are still uneven.