diff --git a/README.md b/README.md
index bb20dd6..9011220 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,14 @@ Jekyll, is built and verified by GitHub Actions, and is deployed to GitHub Pages
The project documentation remains in the
[OpenTaberna wiki](https://wiki.opentaberna.de).
+## Languages
+
+`index.md` is the English page at `/`, `de/index.md` the German page at `/de/`.
+Both carry `hreflang` alternates and a language switch; the layout picks its few
+interface strings from the page's `lang`. A content change to one page belongs in
+the other in the same change. `check_site.rb` fails if the German page, its
+alternates or its search terms go missing.
+
## Local verification
Install Ruby 3.3 and Bundler, then run:
diff --git a/_includes/head.html b/_includes/head.html
index 2ae8ef5..b59c431 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -9,6 +9,9 @@
+
+
+
@@ -17,7 +20,13 @@
+ {%- if page.lang == "de" %}
+
+
+ {%- else %}
+
+ {%- endif %}
diff --git a/_layouts/default.html b/_layouts/default.html
index 0b9c220..23bdf99 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,18 +1,26 @@
-
+{%- assign de = page.lang == "de" -%}
+
{%- include head.html -%}
- Skip to content
+ {% if de %}Zum Inhalt springen{% else %}Skip to content{% endif %}
-
+ OpenTaberna
- Open-source commerce
+ {% if de %}Open-Source-E-Commerce{% else %}Open-source commerce{% endif %}
- GitHub
+
@@ -22,14 +30,14 @@
diff --git a/assets/css/site.css b/assets/css/site.css
index a4343cd..bf4d949 100644
--- a/assets/css/site.css
+++ b/assets/css/site.css
@@ -93,6 +93,7 @@ a:hover { text-decoration-thickness: 2px; }
.brand > span { display: grid; }
.brand-name { font-weight: 720; letter-spacing: -0.02em; line-height: 1.2; }
.brand-note { color: var(--fg-muted); font-family: var(--mono); font-size: 0.7rem; }
+.header-nav { display: flex; gap: 1.25rem; }
.header-link { color: var(--fg-muted); font-size: 0.92rem; text-decoration: none; }
.header-link:hover { color: var(--fg); }
diff --git a/de/index.md b/de/index.md
new file mode 100644
index 0000000..9ffbf2e
--- /dev/null
+++ b/de/index.md
@@ -0,0 +1,89 @@
+---
+layout: default
+lang: de
+title: Open-Source-Shopsystem, headless und selbst gehostet
+permalink: /de/
+description: >-
+ OpenTaberna ist ein Open-Source-Shopsystem, headless und selbst gehostet: Baue
+ deinen eigenen modernen Webshop und automatisiere dein E-Commerce von Anfang bis
+ Ende. Eine freie Shopware-Alternative.
+---
+
+
+
+
Open-Source-E-Commerce, selbst gehostet
+
Das Open-Source-Shopsystem, das wirklich dir gehört.
+
OpenTaberna ist eine moderne, selbst gehostete Webshop-Plattform: Headless-E-Commerce, durchgehend Open Source, das den Ablauf im Onlinehandel von Anfang bis Ende automatisiert.
+
+
+
+
+## Was OpenTaberna ist
+
+Wir haben OpenTaberna gestartet, weil Shopware teuer ist und sich mit kaum etwas
+verbinden ließ, das wir anbinden mussten. Also haben wir eine Open-Source-Alternative
+zu Shopware gebaut. OpenTaberna trennt Storefront, Verwaltung und Backend und stellt
+die Automatisierung in den Mittelpunkt: vom Katalog über Checkout und Lagerbestand bis
+zu Zahlung und Versand.
+
+Es ist ein Headless-Shop von Grund auf und standardmäßig selbst gehostet. Du betreibst
+ihn auf deinen eigenen Servern, wählst Schnittstellen, Dienste und Deployment selbst
+und baust den individuellen Webshop, den dein Geschäft braucht, statt deinen Betrieb
+an ein geschlossenes Produkt anzupassen.
+
+## Woraus es besteht
+
+
Die Einrichtungsanleitung steht dort und nicht hier, damit das Wiki die eine aktuelle Quelle bleibt.
+
+
+## Lizenz und Absicht
+
+OpenTaberna ist vollständig Open Source. Wir wollen mit dem Projekt kein Geld verdienen:
+Du darfst es betreiben, forken, für deine eigenen Zwecke pflegen oder weiterverkaufen,
+im Rahmen der Lizenzen in den jeweiligen Repositories.
+
+## Gründer
+
+
+
+## Kontakt
+
+Fragen, Zusammenarbeit und Anfragen zum Projekt gern an
+[root@vaultops.de](mailto:root@vaultops.de).
diff --git a/llms.txt b/llms.txt
index 900ba19..96edea4 100644
--- a/llms.txt
+++ b/llms.txt
@@ -7,6 +7,8 @@ sitemap: false
> OpenTaberna is an open-source, self-hosted headless shop system: build a modern, custom web shop and automate e-commerce end to end. A free Shopware alternative. The project exists as an open alternative to expensive, hard-to-integrate commerce platforms such as Shopware.
+A German version of the website is at {{ site.url }}/de/.
+
## Project repositories
- [fastapi](https://github.com/OpenTaberna/fastapi): Python backend for the API, commerce domain, integrations and automated order workflow.
diff --git a/scripts/check_site.rb b/scripts/check_site.rb
index e7caf3e..7a4327c 100755
--- a/scripts/check_site.rb
+++ b/scripts/check_site.rb
@@ -40,7 +40,7 @@ def internal_target(reference)
end
required = %w[
- index.html robots.txt llms.txt sitemap.xml CNAME
+ index.html de/index.html robots.txt llms.txt sitemap.xml CNAME
assets/css/site.css wiki/taberna_logo.png
]
required.each do |path|
@@ -62,6 +62,37 @@ def internal_target(reference)
if sitemap && !sitemap.include?("https://#{DOMAIN}/")
fail!("sitemap.xml: does not contain the canonical site URL")
end
+if sitemap && !sitemap.include?("https://#{DOMAIN}/de/")
+ fail!("sitemap.xml: does not contain the German page")
+end
+
+languages = {
+ "index.html" => { lang: "en", locale: "en_GB", switch: "/de/" },
+ "de/index.html" => { lang: "de", locale: "de_DE", switch: "/" },
+}
+languages.each do |path, expected|
+ html = read(path)
+ next unless html
+
+ fail!("#{path}: is not lang=\"#{expected[:lang]}\"") unless html.include?(%())
+ fail!("#{path}: og:locale is not #{expected[:locale]}") unless html.include?(%())
+ { "en" => "https://#{DOMAIN}/", "de" => "https://#{DOMAIN}/de/", "x-default" => "https://#{DOMAIN}/" }.each do |hreflang, href|
+ unless html.include?(%())
+ fail!("#{path}: has lost the hreflang=#{hreflang} alternate")
+ end
+ end
+ fail!("#{path}: has lost the language switch to #{expected[:switch]}") unless html.match?(/]*href="#{Regexp.escape(expected[:switch])}"/)
+end
+
+german = read("de/index.html")
+if german
+ h1 = german[%r{