On this page
Wire supports multi-language sites where each language is an independent content site sharing a domain. This guide explains the architecture, what Wire does and does not do, and why.
Architecture: Parallel Sites, Not Translations
Traditional CMS i18n assumes pages are 1:1 translations. Wire rejects this assumption.
When Chief writes a German page about "Bundesanzeiger," that page has no English equivalent. The AI authored it for a German audience with German-specific regulatory context. The English site might cover "SEC Filings" instead. These are parallel content sites that happen to share a domain, not translations with drift.
This is a deliberate design choice:
- Pages are authored independently per language by Chief
- Each language has its own topics, slugs, and editorial direction
- A page in one language may have no counterpart in another
- Pages that started as translations may diverge completely over time
Configuration
Each language gets its own docs directory. Wire builds them as independent sub-sites under language prefixes.
# wire.yml
languages:
- code: en
name: English
docs_dir: docs/en
- code: de
name: Deutsch
docs_dir: docs/de
- code: es
name: "Espa\xF1ol"
docs_dir: docs/es
Mark one language as default: true to set the root redirect target. Without it, the first entry is used.
languages:
- code: de
name: Deutsch
docs_dir: docs/de
default: true
- code: en
name: English
docs_dir: docs/en
Output structure:
site/
index.html # Root redirect to /de/ (default language)
en/ # English sub-site
index.html
search/index.html
search_index.json
sitemap.xml
de/ # German sub-site
index.html
search/index.html
search_index.json
sitemap.xml
Each language gets its own search page, search index, sitemap, RSS feed, and llms.txt. Search only returns results from the current language. Sitemap URLs include the language prefix (e.g., https://example.com/de/guides/).
Language Switcher
The header renders a dropdown with all configured languages. Clicking a language redirects to that language's homepage (/de/, /en/).
Wire does not attempt to link to the "same page" in another language because:
- The page may not exist in the target language
- Even if a page with the same slug exists, it may cover different content
- False cross-links are worse than no cross-links
If you need explicit page-to-page links between languages, add them manually in your content.
No hreflang Tags
Wire does not generate <link rel="alternate" hreflang="..."> tags. This is intentional.
hreflang tells Google that two pages are translations of each other. When pages drift apart (and they will), false hreflang signals confuse Google's ranking more than missing signals. Google already detects page language from <html lang="">, content analysis, and URL structure (/de/, /en/).
If you need hreflang for pages that truly are translations, add them manually in frontmatter:
---
title: Getting Started
hreflang:
de: /de/guides/erste-schritte/
es: /es/guides/primeros-pasos/
---
Wire will render these as <link rel="alternate"> tags when present. But it will never guess.
Chief and Multi-Language
Chief operates independently per language. When running Chief commands, specify the language:
python -m wire.chief audit --lang de
python -m wire.chief news --lang en
python -m wire.chief refine --lang es --topic guides
Each language has its own:
- GSC database (
.wire/en/gsc.db,.wire/de/gsc.db) with language-specific search data - Progress tracking (
.wire/en/progress-*.json) - Content analysis scoped to that language's pages only
- Link context generated from that language's site directory
Chief does not cross-reference between languages. The German audit does not know about English pages, and it should not. Each language competes in its own search market.
What Wire Handles Automatically
| Feature | Scope | Notes |
|---|---|---|
<html lang=""> | Per language | From languages[].code |
| Search index | Per language | Only indexes that language's pages |
| Sitemap | Per language | Submitted separately to GSC |
| RSS feed | Per language | Separate feed per language |
| Navigation | Per language | Built from that language's docs |
| Language dropdown | Shared | Links to each language's homepage |
| 404 page | Shared | One 404, language-neutral |
What Wire Does Not Do
- No automatic translation. Write content per language or use external translation tools before importing.
- No page mapping. Wire does not track which pages are "the same" across languages.
- No hreflang generation. Declare explicitly in frontmatter when pages truly correspond.
- No shared content. Each language is fully independent. No template inheritance across languages.
- No fallback language. If a page does not exist in German, Wire does not serve the English version.
Directory Structure
docs/
en/
index.md
guides/
getting-started/index.md
seo-reference/index.md
vendors/
acme/index.md
de/
index.md
guides/
erste-schritte/index.md
seo-referenz/index.md
anbieter/
bundesanzeiger/index.md # No English equivalent
Topics and slugs can differ between languages. The German site might have "anbieter" where English has "vendors." Chief treats each as a separate topic namespace.
GSC Setup
Each language sub-site needs its own GSC property or URL prefix:
https://example.com/en/(English)https://example.com/de/(German)
Run data separately per language so each GSC database captures the right search performance data:
python -m wire.chief data --lang en
python -m wire.chief data --lang de
Trade-offs
What you gain:
- Simple, honest architecture with no false signals to Google
- Each language evolves independently based on its own search data
- Chief makes optimal decisions per market, not compromises across markets
- No complexity from page mapping, sync status, or translation tracking
What you give up:
- No automatic "view in English" links on German pages
- No hreflang SEO signals (but false signals are worse)
- Content teams must manage each language independently
- Duplicate editorial effort for truly shared content
This trade-off is correct for content sites where quality and market fit matter more than translation coverage.