Skip to content

feat(i18n): multi-language proof-of-concept (ru, de, zh-cn, hi)#593

Open
Timur Tukaev (tym83) wants to merge 17 commits into
mainfrom
poc/i18n-multilang
Open

feat(i18n): multi-language proof-of-concept (ru, de, zh-cn, hi)#593
Timur Tukaev (tym83) wants to merge 17 commits into
mainfrom
poc/i18n-multilang

Conversation

@tym83

@tym83 Timur Tukaev (tym83) commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Proof-of-concept for website localization. Adds Russian, German, Simplified Chinese, and Hindi versions of a representative set of pages so reviewers can see all four writing systems on the real layout (typography, CJK/Devanagari rendering, the navbar language switcher) and evaluate quality.

Machine-translated and cross-checked with a second model; pending native-speaker review. This is a PoC to validate the approach end-to-end before committing to the full pipeline — a design proposal/discussion accompanies it.

Live preview

https://deploy-preview-593--cozystack.netlify.app — use the navbar language dropdown, or jump straight in:

Each language has: landing, Getting Started, Support, and the "Introducing Cozystack Wizard" blog post.

What

  • Hugo languages: config for ru / de / zh-cn (zh-Hans) / hi, plus per-language content mounts (base + production override). English stays at the root (defaultContentLanguageInSubdir: false) — no existing URLs change; other languages live under /de/, /ru/, /zh-cn/, /hi/.
  • Translated pages under content/<lang>/:
    • Landing (_index.html) — transcreated, with keyword-localized SEO front matter
    • Getting Started (docs/v1.4/getting-started/_index.md)
    • Support (support.md)
    • Blog: "Introducing Cozystack Wizard"
  • Shortcodes, code blocks, CLI commands, URLs, taxonomy terms, and brand names (Kubernetes, Talos, FluxCD, AWS, VMware) preserved; image bundles copied per language.

Why

Validate localization on the live layout before building the full automated pipeline: confirm the structure (content/<lang>/ siblings, mirroring kubernetes/website), the Docsy language dropdown, and translation/terminology quality across very different writing systems.

Notes & open items

  • PoC, not production: translations are machine-translated + automated checks, not yet native-reviewed. Terminology choices (e.g. RU dashboard rendering, DE/ZH conventions) follow the CNCF Cloud Native Glossary + kubernetes.io localization and are pending native ratification.
  • Only the latest docs version (v1.4) is in scope for translation; older versions stay English.
  • Getting Started links point to the English sub-pages for now (only _index is translated in this PoC) — honest behavior for a partially-translated section.
  • hreflang / <html lang> / self-canonical wiring and the automated translation pipeline come as follow-ups (covered in the design proposal).
  • Looking for native-speaker reviewers/owners per language (Kubernetes localization model).

Summary by CodeRabbit

  • New Features
    • Added localized homepages, “Getting Started”, support, and docs landing pages for German, Hindi, Russian, and Chinese.
    • Published the “Cozystack Wizard” announcement in these languages, including the plugin consolidation breaking-change notice.
  • Documentation
    • Improved localized headings and docs landing table/callouts using translation strings.
    • Standardized the “Documentation” menu item across languages.
  • Chores
    • Added an i18n lint check to keep translations complete and fresh.

Timur Tukaev (tym83) and others added 4 commits June 30, 2026 13:38
Add Hugo languages config and per-language content mounts (base + production
override) for German, Russian, Simplified Chinese, Hindi. English stays at
root (defaultContentLanguageInSubdir: false). Includes translated
getting-started/_index.md for all four as the first PoC page.

Verified: Hugo registers all languages and resolves all content mounts; the
four language getting-started pages appear in the site model with correct URLs.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
…de/zh-cn/hi

Cross-vendor validation pass: accepted Codex's accuracy/structure/fluency fixes
(DE missing 'on your machine'; ZH/HI merged-line split; HI deployment-term
consistency; several fluency edits). Rejected Codex's removal of source_digest/
translation_status/l10n — those are intentional pipeline metadata. Terminology
decisions recorded in the glossaries.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
…d SEO blocks

Transcreated _index.html (hero, taglines, benefits, features, community) for all
four languages. Shortcodes, icons, URLs, code, and brand names (AWS, VMware,
Kubernetes, FluxCD) preserved. Each carries an Ahrefs-derived seo: block
(keyword-localized title/description/keywords — English terms kept where the
data favors them) plus pipeline metadata. Terminology follows the seeded glossaries.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
…n/hi

Completes the PoC-1 page set (landing + getting-started + support + blog) across
four writing systems. Code blocks, slugs, taxonomy terms, commands, and URLs
preserved; image bundles copied per language. Pipeline metadata + glossary terms applied.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
@netlify

netlify Bot commented Jun 30, 2026

Copy link
Copy Markdown

Deploy Preview for cozystack ready!

Name Link
🔨 Latest commit 9d660b6
🔍 Latest deploy log https://app.netlify.com/projects/cozystack/deploys/6a5a607e946a5d0008fabc0d
😎 Deploy Preview https://deploy-preview-593--cozystack.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds German, Hindi, Russian, and Chinese website content, configures Hugo multilingual mounts and translations, localizes homepage and documentation labels, and introduces automated i18n key and translation freshness checks in CI.

Changes

Multilingual website localization

Layer / File(s) Summary
i18n validation and CI
.github/workflows/i18n-lint.yml, hack/check-i18n.sh
Adds key-parity and translation-digest validation with update support, and runs the checks on relevant pull requests, pushes, and manual workflow dispatches.
Hugo language and translation wiring
hugo.yaml, config/production/hugo.yaml, i18n/*.toml, layouts/partials/hooks/head-end.html, layouts/shortcodes/home/*, layouts/docs/docs-landing.html, content/en/docs/_index.md
Configures localized mounts and language metadata, adds locale translations, localizes homepage and documentation labels, and documents multilingual navigation and canonicalization behavior.
Localized homepages
content/{de,hi,ru,zh-cn}/_index.html
Adds localized homepage metadata, hero content, feature sections, community links, and CNCF sections.
Localized documentation and announcements
content/{de,hi,ru,zh-cn}/blog/..., content/{de,hi,ru,zh-cn}/docs/..., content/{de,hi,ru,zh-cn}/support.md, content/en/support.md
Adds translated wizard announcements, v1.4 getting-started pages, enterprise support pages, and support table formatting.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

Suggested reviewers: lllamnyp

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the PR’s main change: a multi-language i18n proof of concept for ru, de, zh-cn, and hi.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch poc/i18n-multilang

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces localization support for German, Russian, Simplified Chinese, and Hindi by adding translated homepages, blog posts, getting started guides, and support pages, alongside configuring Hugo mounts and language settings in hugo.yaml and config/production/hugo.yaml. The review feedback correctly identifies that the "Get Started" buttons on the localized homepages still point to the hardcoded English documentation path (/docs/get-started/) instead of their respective localized paths, which should be updated to ensure a consistent user experience.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread content/de/_index.html Outdated

<div class="hero-gitops">
{{% blocks/hero title="Cozystack: Kostenlose Cloud-Plattform auf Basis von Kubernetes" color="primary"
height="auto" link_title="Erste Schritte" link_url="/docs/get-started/" %}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The link_url for the "Erste Schritte" (Get Started) button is hardcoded to the root English path /docs/get-started/. Since this is the German localized homepage, it should point to the German version of the documentation to ensure a consistent localized user experience.

  height="auto" link_title="Erste Schritte" link_url="/de/docs/get-started/" %}}

Comment thread content/hi/_index.html Outdated

<div class="hero-gitops">
{{% blocks/hero title="Cozystack: Kubernetes पर आधारित मुफ़्त क्लाउड प्लेटफ़ॉर्म" color="primary"
height="auto" link_title="शुरुआत करें" link_url="/docs/get-started/" %}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The link_url for the "शुरुआत करें" (Get Started) button is hardcoded to the root English path /docs/get-started/. Since this is the Hindi localized homepage, it should point to the Hindi version of the documentation to ensure a consistent localized user experience.

  height="auto" link_title="शुरुआत करें" link_url="/hi/docs/get-started/" %}}

Comment thread content/ru/_index.html Outdated

<div class="hero-gitops">
{{% blocks/hero title="Cozystack: бесплатная облачная платформа на базе Kubernetes" color="primary"
height="auto" link_title="Начать" link_url="/docs/get-started/" %}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The link_url for the "Начать" (Get Started) button is hardcoded to the root English path /docs/get-started/. Since this is the Russian localized homepage, it should point to the Russian version of the documentation to ensure a consistent localized user experience.

  height="auto" link_title="Начать" link_url="/ru/docs/get-started/" %}}

Comment thread content/zh-cn/_index.html Outdated

<div class="hero-gitops">
{{% blocks/hero title="Cozystack:基于 Kubernetes 的免费云平台" color="primary"
height="auto" link_title="开始使用" link_url="/docs/get-started/" %}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The link_url for the "开始使用" (Get Started) button is hardcoded to the root English path /docs/get-started/. Since this is the Simplified Chinese localized homepage, it should point to the Simplified Chinese version of the documentation to ensure a consistent localized user experience.

  height="auto" link_title="开始使用" link_url="/zh-cn/docs/get-started/" %}}

Timur Tukaev (tym83) and others added 5 commits June 30, 2026 17:57
…l translation)

The translated getting-started/_index.md linked to sibling pages via
{{% ref %}}, but those siblings exist only in English (only _index is
translated in the PoC). Hugo resolves ref within the current language, so the
build failed with REF_NOT_FOUND. Point the links at the canonical English
pages instead — correct behavior for a partially-translated section and the
build passes. Verified with pinned Hugo 0.160.1 (HUGO_ENV=preview): all four
languages and all PoC pages render, navbar language switcher lists all five.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
The landing section headings (Benefits, Features, Screenshots) and the CNCF
sandbox line were hardcoded English in the home shortcodes, so they stayed
English on translated pages even though the cards (from front matter) were
translated. Externalize them to i18n strings (T "home_*") with en/de/ru/zh-cn/hi
values. This is the correct Hugo-native way to localize layout strings, and it
demonstrates UI-string localization alongside content translation. English
output is unchanged; verified on pinned Hugo 0.160.1.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
The de/ru/zh-cn/hi translation files defined only the four new home_*
keys, while i18n/en.toml also defines the repo-local theme keys used by
layouts/ (note, warning, caution, join_community, outdated_blog__message,
docs_*, ui_*). Because hugo.yaml sets enableMissingTranslationPlaceholders:
true, a key missing from a language file renders a visible '[i18n] <key>'
placeholder on the translated page instead of falling back to English.
Add every en.toml key, translated, to all four language files so
translated pages render clean.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
The four language trees are machine-translated and awaiting native-speaker
ratification. Extend the existing noindex head-end hook (already used for
legacy doc versions) to emit '<meta name="robots" content="noindex,
follow">' for de/ru/zh-cn/hi pages, keeping them live for review and
link-following users but out of search indexes until ratified. Remove a
language from the list once a native owner ratifies it.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Add hack/check-i18n.sh plus an i18n-lint workflow that runs on PRs
touching i18n/ or content/. Two guards, no Hugo/Node needed:

1. key parity: every i18n/<lang>.toml must define exactly the same keys
   as i18n/en.toml, catching the missing-key -> placeholder class before
   it ships.
2. translation freshness: every translated page's source_digest front
   matter must equal the current sha256 of its English source, flagging
   translations that went stale after the English page changed.

Populate the previously-placeholder source_digest field in all 16
translated pages with the real English-source hash (computed by the same
script via 'update-digests'), so the freshness guard has a baseline.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
@IvanHunters
IvanHunters marked this pull request as ready for review July 14, 2026 06:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
.github/workflows/i18n-lint.yml (1)

31-32: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Disable credential persistence in checkout.

To improve security hygiene and prevent accidental token leakage (e.g., if artifact uploads or untrusted scripts are added later), consider explicitly disabling credential persistence for the checkout action, as this workflow does not push changes back to the repository.

♻️ Proposed fix
       - name: Checkout
         uses: actions/checkout@v4
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/i18n-lint.yml around lines 31 - 32, Update the Checkout
step using actions/checkout@v4 to explicitly disable credential persistence by
setting persist-credentials to false, while leaving the rest of the workflow
unchanged.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@content/de/_index.html`:
- Around line 69-70: The hero CTA uses a root-relative URL that bypasses Hugo
language routing. Update the link_url in the blocks/hero invocation for
content/de/_index.html lines 69-70, content/hi/_index.html lines 69-70,
content/ru/_index.html lines 69-70, and content/zh-cn/_index.html lines 69-70 to
target each locale’s Getting Started overview, preserving the existing hero
configuration.

In `@content/de/support.md`:
- Around line 13-14: Align the support table separator rows with their
three-column headers by removing the extra delimiter cell in
content/de/support.md lines 13-14 and content/hi/support.md lines 13-14. Do not
change the table headers or data rows.
- Line 15: Replace the invalid image alt text with a concise meaningful
description such as “Aenix logo” in the image markup at content/de/support.md
lines 15-15 and content/hi/support.md lines 15-15.

In `@content/ru/support.md`:
- Line 14: Remove the extra delimiter cell from the support-table separator in
content/ru/support.md at line 14 and content/zh-cn/support.md at line 14, so
each separator contains three cells matching the tables’ three-column headers
and rows.
- Line 15: Replace the literal Markdown expression in the logo image alt text
with meaningful provider-name text, or use an empty alt value if the logo is
decorative. Apply the same correction in content/ru/support.md at lines 15-15
and content/zh-cn/support.md at lines 15-15; no other table content needs
changing.

---

Nitpick comments:
In @.github/workflows/i18n-lint.yml:
- Around line 31-32: Update the Checkout step using actions/checkout@v4 to
explicitly disable credential persistence by setting persist-credentials to
false, while leaving the rest of the workflow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 877b3b6f-62dd-452b-b29a-88ab4f9ae413

📥 Commits

Reviewing files that changed from the base of the PR and between 3af9c1b and aaa909c.

⛔ Files ignored due to path filters (4)
  • content/de/blog/2026-05-19-introducing-cozystack-wizard/cozystack-wizard.png is excluded by !**/*.png
  • content/hi/blog/2026-05-19-introducing-cozystack-wizard/cozystack-wizard.png is excluded by !**/*.png
  • content/ru/blog/2026-05-19-introducing-cozystack-wizard/cozystack-wizard.png is excluded by !**/*.png
  • content/zh-cn/blog/2026-05-19-introducing-cozystack-wizard/cozystack-wizard.png is excluded by !**/*.png
📒 Files selected for processing (30)
  • .github/workflows/i18n-lint.yml
  • config/production/hugo.yaml
  • content/de/_index.html
  • content/de/blog/2026-05-19-introducing-cozystack-wizard/index.md
  • content/de/docs/v1.4/getting-started/_index.md
  • content/de/support.md
  • content/hi/_index.html
  • content/hi/blog/2026-05-19-introducing-cozystack-wizard/index.md
  • content/hi/docs/v1.4/getting-started/_index.md
  • content/hi/support.md
  • content/ru/_index.html
  • content/ru/blog/2026-05-19-introducing-cozystack-wizard/index.md
  • content/ru/docs/v1.4/getting-started/_index.md
  • content/ru/support.md
  • content/zh-cn/_index.html
  • content/zh-cn/blog/2026-05-19-introducing-cozystack-wizard/index.md
  • content/zh-cn/docs/v1.4/getting-started/_index.md
  • content/zh-cn/support.md
  • hack/check-i18n.sh
  • hugo.yaml
  • i18n/de.toml
  • i18n/en.toml
  • i18n/hi.toml
  • i18n/ru.toml
  • i18n/zh-cn.toml
  • layouts/partials/hooks/head-end.html
  • layouts/shortcodes/home/benefits.html
  • layouts/shortcodes/home/cncf.html
  • layouts/shortcodes/home/features.html
  • layouts/shortcodes/home/screenshot-gallery.html

Comment thread content/de/_index.html Outdated
Comment on lines +69 to +70
{{% blocks/hero title="Cozystack: Kostenlose Cloud-Plattform auf Basis von Kubernetes" color="primary"
height="auto" link_title="Erste Schritte" link_url="/docs/get-started/" %}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

The CTA button links back to the English site.

Since English is configured at the site root, the absolute path /docs/get-started/ bypasses Hugo's language routing and will immediately navigate users away from the translated site back to the English site.

To ensure users reach the translated Getting Started overview, please update this path to use a localized path or a relative path, or update the upstream blocks/hero shortcode to process link_url with relLangURL.

  • content/de/_index.html#L69-L70: Update link_url to remain within the German locale (e.g., /de/docs/get-started/).
  • content/hi/_index.html#L69-L70: Update link_url to remain within the Hindi locale.
  • content/ru/_index.html#L69-L70: Update link_url to remain within the Russian locale.
  • content/zh-cn/_index.html#L69-L70: Update link_url to remain within the Chinese locale.
📍 Affects 4 files
  • content/de/_index.html#L69-L70 (this comment)
  • content/hi/_index.html#L69-L70
  • content/ru/_index.html#L69-L70
  • content/zh-cn/_index.html#L69-L70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/de/_index.html` around lines 69 - 70, The hero CTA uses a
root-relative URL that bypasses Hugo language routing. Update the link_url in
the blocks/hero invocation for content/de/_index.html lines 69-70,
content/hi/_index.html lines 69-70, content/ru/_index.html lines 69-70, and
content/zh-cn/_index.html lines 69-70 to target each locale’s Getting Started
overview, preserving the existing hero configuration.

Comment thread content/de/support.md Outdated
Comment thread content/de/support.md Outdated

| Organisation | Kontakt | Leistungsbeschreibung |
| ------------ | ------- | ---- | ------------------ |
| <img src="/img/logo.png" alt="[drawing](https://aenix.io/contact/)" width="200"/> | [Website](https://aenix.io/contact/) [LinkedIn](https://www.linkedin.com/company/aenix-io)| Wir bieten jede Art von Unterstützung: Beratung, Entwicklung fehlender Funktionen, Design sowie Hilfe bei Installation und Integration. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the invalid Aenix alt text with a meaningful description.

  • content/de/support.md#L15: change the alt text to a concise description such as Aenix logo.
  • content/hi/support.md#L15: change the alt text to a concise description such as Aenix logo.
📍 Affects 2 files
  • content/de/support.md#L15-L15 (this comment)
  • content/hi/support.md#L15-L15
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/de/support.md` at line 15, Replace the invalid image alt text with a
concise meaningful description such as “Aenix logo” in the image markup at
content/de/support.md lines 15-15 and content/hi/support.md lines 15-15.

Comment thread content/ru/support.md Outdated
## Эти компании предоставляют корпоративную поддержку Cozystack.

| Организация | Контакт | Описание услуг |
| ------------ | ------- | ---- | ------------------ |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the support-table delimiter with the three-column table.

Both translations declare four delimiter cells for a table whose header and rows contain three columns.

  • content/ru/support.md#L14: remove the extra delimiter cell.
  • content/zh-cn/support.md#L14: remove the extra delimiter cell.
📍 Affects 2 files
  • content/ru/support.md#L14-L14 (this comment)
  • content/zh-cn/support.md#L14-L14
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/ru/support.md` at line 14, Remove the extra delimiter cell from the
support-table separator in content/ru/support.md at line 14 and
content/zh-cn/support.md at line 14, so each separator contains three cells
matching the tables’ three-column headers and rows.

Comment thread content/ru/support.md Outdated

| Организация | Контакт | Описание услуг |
| ------------ | ------- | ---- | ------------------ |
| <img src="/img/logo.png" alt="[drawing](https://aenix.io/contact/)" width="200"/> | [Сайт](https://aenix.io/contact/) [LinkedIn](https://www.linkedin.com/company/aenix-io)| Мы оказываем все виды помощи: консультации, разработку недостающих функций, проектирование, помощь с установкой и интеграцией. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the literal Markdown syntax in the logo alt text.

The first logo uses alt="[drawing](...)", which is not meaningful accessible text.

  • content/ru/support.md#L15: use a meaningful provider name or alt="" if decorative.
  • content/zh-cn/support.md#L15: use a meaningful provider name or alt="" if decorative.
📍 Affects 2 files
  • content/ru/support.md#L15-L15 (this comment)
  • content/zh-cn/support.md#L15-L15
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/ru/support.md` at line 15, Replace the literal Markdown expression in
the logo image alt text with meaningful provider-name text, or use an empty alt
value if the logo is decorative. Apply the same correction in
content/ru/support.md at lines 15-15 and content/zh-cn/support.md at lines
15-15; no other table content needs changing.

IvanHunters and others added 4 commits July 14, 2026 09:56
…d page

The hero "Get started" button on the de/ru/zh-cn/hi landing pages used the
absolute path /docs/get-started/. With English served at the site root, that
path leaves the localized site and lands on the English v0 getting-started
alias — the one translated getting-started page (/<lang>/docs/v1.4/getting-started/)
was never where the button pointed. Target each locale's own translated page so
the primary call to action keeps users in their language.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The support table declared four delimiter cells for a three-column header, and
the Aenix logo carried literal Markdown link syntax as its alt text, which
screen readers announce verbatim. Both originated in the English page and were
mirrored into every translation, so fix the source and all translated copies
together and refresh the recorded source digests.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — the localization approach is sound, English is unaffected, and the one open question is a product decision rather than a code defect.

Business context: Proof-of-concept for website localization (ru/de/zh-cn/hi) to validate the structure, the language switcher, and translation quality on the real layout before committing to a full pipeline.

I pushed two fixes to this branch rather than leaving them as review notes:

  • 7cf0c24 — the hero CTA on all four localized landings pointed at /docs/get-started/. With English served at the site root that absolute path leaves the localized site, and it resolves via the alias declared only in content/en/docs/v0/getting-started/_index.md, so the button landed on English v0 — not the one getting-started page that is actually translated. Each locale now targets /<lang>/docs/v1.4/getting-started/. Worth noting that /<lang>/docs/get-started/ would have 404'd: that alias exists only in the English v0 tree.
  • e81cb12 — the support table declared four delimiter cells for a three-column header, and the Aenix logo carried literal Markdown link syntax as its alt text. Both originated in the English source and were mirrored into all four translations, so I fixed content/en/support.md and every translated copy, then refreshed the recorded digests.

What I verified:

  • No regression to English: the section headings now resolve through en.toml, which defines every key, so they render exactly as before; the canonical/noindex branch is unchanged for en; root URLs are untouched.
  • The noindex guard for unratified languages keys off .Language.Lang, which matches the language keys in hugo.yaml — correct for zh-cn, since zh-Hans is the languageCode, not Lang.
  • The getting-started cross-links pointing at English sub-pages are intended per the PR description, not an oversight — only _index is translated in this PoC.
  • Code blocks, CLI commands, and brand names are preserved across all four translations.

Non-blocking: the second paragraph in home/cncf.html (terms of use and trademark policy) stays hardcoded English while the first is localized. I left that deliberately — it is legal boilerplate, and a machine translation of it should not ship ahead of native ratification. Worth confirming as an intentional choice rather than a gap.

One decision before merge, and it is not a code question: merging publishes machine-translated, not-yet-ratified content on the production domain. The mitigations are good — noindex on unratified languages, freshness digests, honest English links for untranslated sub-pages — but the language switcher still surfaces this content to real users. Confirm that shipping unratified translations to production is intended, versus keeping them preview-only until native owners ratify.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
content/hi/_index.html (1)

106-118: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Consider adding rel="noopener noreferrer" to external links.

When opening external links in a new tab using target="_blank", it's a good practice to include rel="noopener noreferrer". This enhances privacy by dropping the HTTP referer header and provides a safeguard against reverse tabnabbing, even though most modern browsers implicitly apply noopener by default.

  • content/hi/_index.html#L106-L118: add rel="noopener noreferrer" to the external target="_blank" anchor tags.
  • content/ru/_index.html#L106-L118: add rel="noopener noreferrer" to the external target="_blank" anchor tags.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/hi/_index.html` around lines 106 - 118, Add rel="noopener noreferrer"
to every external target="_blank" anchor in the community sections of
content/hi/_index.html lines 106-118 and content/ru/_index.html lines 106-118,
including the GitHub Discussions, Slack invitation, and Kubernetes Slack links;
make no other changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@content/hi/_index.html`:
- Around line 106-118: Add rel="noopener noreferrer" to every external
target="_blank" anchor in the community sections of content/hi/_index.html lines
106-118 and content/ru/_index.html lines 106-118, including the GitHub
Discussions, Slack invitation, and Kubernetes Slack links; make no other
changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 716c7387-75e4-46d7-8229-25803e75d55a

📥 Commits

Reviewing files that changed from the base of the PR and between aaa909c and e81cb12.

📒 Files selected for processing (6)
  • content/de/_index.html
  • content/de/support.md
  • content/en/support.md
  • content/hi/_index.html
  • content/hi/support.md
  • content/ru/_index.html
🚧 Files skipped from review as they are similar to previous changes (3)
  • content/de/support.md
  • content/hi/support.md
  • content/de/_index.html

Ship localized (de/ru/zh-cn/hi) trees to production and let search engines
and AI crawlers index them immediately, instead of gating discovery on
native ratification. Native review runs in parallel (publish-then-review);
users need the localized docs and site now.

Drop the unratified-language noindex branch; localized pages now emit a
self-canonical so each language ranks independently. Legacy-doc-version
noindex (dedup of old English versions) is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <timur.tukaev@aenix.io>
@tym83

Copy link
Copy Markdown
Contributor Author

Thanks for the review, Aleksei Sviridkin (@lexfrei) — and for pushing the two fixes directly rather than leaving them as notes; both are in the branch.

On the one open decision — yes, shipping the unratified translations to production is intended. Native ratification can take a while, and adopters need the localized docs and site now, so we're going with a publish-then-review model rather than gating discovery on ratification.

I've taken it one step further in 32f42cf: dropped the noindex guard for the localized trees so search engines and AI crawlers index de/ru/zh-cn/hi from day one. Each localized page now emits a self-canonical, so the languages rank independently. The legacy-doc-version noindex (dedup of old English versions) is unchanged. Rationale: keeping accurate-enough machine translations out of the index would mostly hurt the people who need them, and the freshness digests + completeness checks in CI already flag drift for native reviewers.

The home/cncf.html legal boilerplate staying English is an intentional choice — confirmed, not a gap.

Next steps beyond this PoC: add Spanish and Portuguese, expand page coverage methodically via the automated translation pipeline from the design proposal, and recruit native-speaker owners per language for ratification (Kubernetes localization model). Thanks again for the thorough pass.

@kvaps Andrei Kvapil (kvaps) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation link is missing on translated pages, we need to keep it at least with fallback to english version

Timur Tukaev (tym83) and others added 2 commits July 17, 2026 16:40
The navbar Documentation item came from content/en/docs/_index.md front matter
(menu: main), so it rendered only on languages where that page exists — i.e.
English only. On translated pages the link disappeared.

Move it to hugo.yaml menus.main, which renders on every language. Hugo prefixes
the URL per language (/ru/docs/, /de/docs/ …), each of which resolves to that
language's docs section; the English site keeps /docs/. The front-matter menu
entry is removed so English does not show it twice.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <timur.tukaev@aenix.io>
…language

Commit 9040ace moved the navbar "Documentation" item to hugo.yaml with a
hardcoded url: /docs/. Because the navbar runs menu URLs through relLangURL,
that produced /ru/docs/, /de/docs/ … on translated pages — links to pages
that did not exist, so the version-picker landing rendered as an empty Hugo
section instead of the fallback kvaps asked for.

Add a translated docs landing (content/<lang>/docs/_index.md) for de, ru,
zh-cn, hi and switch the menu entry to pageRef: /docs/. Hugo now resolves the
entry per language: each site links to its own docs landing and takes the
label from that page's linkTitle; the version links inside still point at the
English version trees (honest fallback, as stated in the PR).

Move the hardcoded strings in the docs-landing layout (intro sentence, table
headers, status labels) into i18n keys defined for every language, so the
version picker itself renders in-language.

Register source_digest on the new pages so the freshness lint tracks drift.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <6355522@gmail.com>
@tym83

Copy link
Copy Markdown
Contributor Author

Andrei Kvapil (@kvaps) fixed in 460c671.

The earlier fix moved the Documentation menu item to hugo.yaml with a hardcoded url: /docs/, but the navbar runs menu URLs through relLangURL, so on translated pages it became /ru/docs/, /de/docs/ … — links to pages that didn't exist, rendering as an empty Hugo section rather than the English fallback you asked for.

Now the entry uses pageRef: /docs/, which Hugo resolves per language, and each language gets a translated docs landing at content/<lang>/docs/_index.md. So the Documentation link renders on all languages with an in-language label, and clicking it lands on that language's version picker. The version links inside the picker still point at the English docs trees — the honest fallback until those versions are translated.

I also moved the docs-landing layout strings (intro line, table headers, status labels) into i18n keys per language, so the version picker itself renders in-language, and registered source_digest on the new pages so the freshness lint tracks drift. Ready for another look.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
layouts/docs/docs-landing.html (1)

23-23: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use an <h2> heading for proper document hierarchy.

The layout uses an <h3> tag here, skipping the <h2> level (since the page title naturally renders as <h1>). Using an <h2> ensures a logical document outline and aligns with accessibility best practices.

♻️ Proposed refactor
-  <h3>{{ T "docs_landing_available_versions" }}</h3>
+  <h2>{{ T "docs_landing_available_versions" }}</h2>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/docs/docs-landing.html` at line 23, Update the docs landing page
heading that renders the docs_landing_available_versions translation from h3 to
h2, preserving its existing text and placement so the document hierarchy follows
the page title’s h1.
content/de/docs/_index.md (1)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fix the heading level to properly increment structure and resolve markdownlint warnings.

These headings skip a level (H2) and directly use H3, which triggers a markdownlint warning (MD001: heading-increment) and violates accessibility guidelines. Update the heading to ## to ensure a logical document outline.

  • content/de/docs/_index.md#L14-L14: Change ### to ## for the Ihre aktuelle Version ermitteln heading.
  • content/hi/docs/_index.md#L14-L14: Change ### to ## for the अपना मौजूदा संस्करण जाँचें heading.
  • content/ru/docs/_index.md#L14-L14: Change ### to ## for the Как узнать текущую версию heading.
  • content/zh-cn/docs/_index.md#L14-L14: Change ### to ## for the 查看当前版本 heading.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/de/docs/_index.md` at line 14, Update the heading level from ### to
## for “Ihre aktuelle Version ermitteln” in content/de/docs/_index.md:14-14,
“अपना मौजूदा संस्करण जाँचें” in content/hi/docs/_index.md:14-14, “Как узнать
текущую версию” in content/ru/docs/_index.md:14-14, and “查看当前版本” in
content/zh-cn/docs/_index.md:14-14, preserving the heading text.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@content/de/docs/_index.md`:
- Line 14: Update the heading level from ### to ## for “Ihre aktuelle Version
ermitteln” in content/de/docs/_index.md:14-14, “अपना मौजूदा संस्करण जाँचें” in
content/hi/docs/_index.md:14-14, “Как узнать текущую версию” in
content/ru/docs/_index.md:14-14, and “查看当前版本” in
content/zh-cn/docs/_index.md:14-14, preserving the heading text.

In `@layouts/docs/docs-landing.html`:
- Line 23: Update the docs landing page heading that renders the
docs_landing_available_versions translation from h3 to h2, preserving its
existing text and placement so the document hierarchy follows the page title’s
h1.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1b4e895b-674c-485b-979a-b12ce8b4e311

📥 Commits

Reviewing files that changed from the base of the PR and between 9040ace and 460c671.

📒 Files selected for processing (11)
  • content/de/docs/_index.md
  • content/hi/docs/_index.md
  • content/ru/docs/_index.md
  • content/zh-cn/docs/_index.md
  • hugo.yaml
  • i18n/de.toml
  • i18n/en.toml
  • i18n/hi.toml
  • i18n/ru.toml
  • i18n/zh-cn.toml
  • layouts/docs/docs-landing.html
🚧 Files skipped from review as they are similar to previous changes (5)
  • i18n/ru.toml
  • i18n/de.toml
  • i18n/zh-cn.toml
  • i18n/hi.toml
  • hugo.yaml

Add rel="noopener noreferrer" to the external target="_blank" community
links (GitHub Discussions, Slack, Telegram) on the four localized homepages,
and disable credential persistence on the i18n-lint checkout since the job
never pushes. Both from the CodeRabbit pass on #593.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <6355522@gmail.com>
Timur Tukaev (tym83) added a commit that referenced this pull request Jul 17, 2026
…rklist

_docs_out_of_scope excluded every docs page not under docs/<latest>/, which
also dropped docs/_index.md — the version-picker landing that #593 translates
per language and records a source_digest for. The freshness lint would then
flag drift on that page with no pipeline path to refresh it.

Narrow only the versioned subtrees (docs/<ver>/...) to the latest version;
pages directly under docs/ are version-agnostic and stay in scope. Adjust the
leak-in guard test accordingly and cover the landing explicitly.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <6355522@gmail.com>
Timur Tukaev (tym83) added a commit that referenced this pull request Jul 17, 2026
…rklist

_docs_out_of_scope excluded every docs page not under docs/<latest>/, which
also dropped docs/_index.md — the version-picker landing that #593 translates
per language and records a source_digest for. The freshness lint would then
flag drift on that page with no pipeline path to refresh it.

Narrow only the versioned subtrees (docs/<ver>/...) to the latest version;
pages directly under docs/ are version-agnostic and stay in scope. Adjust the
leak-in guard test accordingly and cover the landing explicitly.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <6355522@gmail.com>
Timur Tukaev (tym83) added a commit that referenced this pull request Jul 17, 2026
The docs version-picker landing strings were added to the active-language
i18n files on poc/i18n-multilang (#593). es and pt-br live only on this
pipeline branch, so the rebase onto that work left them without those keys —
the parity lint flags them as missing. Add the Spanish and Portuguese
translations so all seven language files stay in parity.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: tym83 <6355522@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants