diff --git a/tools/sprachseiten/build.js b/tools/sprachseiten/build.js index 39b93be..3d77c5e 100644 --- a/tools/sprachseiten/build.js +++ b/tools/sprachseiten/build.js @@ -57,6 +57,60 @@ const WAEHLER_CSS = ` max-width: 220px; cursor: pointer; }`; +/** + * Strukturierte Daten je Sprachseite. Beschreibung und Sprache kommen aus + * texte.js, damit Google die Seite in der jeweiligen Sprache einordnet — + * ein deutscher Block auf der tuerkischen Seite waere widerspruechlich. + */ +function schemaBlock(s, t) { + const daten = { + '@context': 'https://schema.org', + '@type': 'SoftwareApplication', + name: 'BehördenKlar', + description: t.beschreibung, + applicationCategory: 'AccessibilityApplication', + operatingSystem: 'iOS, Web', + inLanguage: ALLE.map((x) => x.code), + offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' }, + author: { '@type': 'Organization', name: 'Webklar GbR', url: BASIS }, + }; + return JSON.stringify(daten, null, 2) + .split('\n').map((z) => ' ' + z).join('\n'); +} + +/** + * Sitemap mit Sprach-Angaben (xhtml:link). Google erkennt die Alternativen + * dadurch auch ohne die HTML-Tags — doppelt haelt besser, gerade bei 28 Sprachen. + * Die Nicht-Sprachseiten (Demo, Ratgeber) bleiben unveraendert bestehen. + */ +function sitemapSchreiben() { + const pfad = path.join(AUS, 'sitemap.xml'); + const heute = new Date().toISOString().slice(0, 10); + const alt = fs.existsSync(pfad) ? fs.readFileSync(pfad, 'utf8') : ''; + const andere = (alt.match(/.*?<\/url>/gs) || []).filter( + (u) => /\/(demo|ratgeber)/.test(u) + ); + + const sprachLinks = ALLE.map( + (x) => ` ` + ).join('\n') + `\n `; + + const bloecke = ALLE.map( + (x) => ` \n ${BASIS}${x.pfad}\n ${heute}\n${sprachLinks}\n ` + ); + + const xml = [ + '', + '', + ...bloecke, + ...andere.map((u) => ' ' + u.replace(/\s+/g, ' ')), + '', + ].join('\n'); + fs.writeFileSync(pfad, xml + '\n', 'utf8'); + return ALLE.length + andere.length; +} + function seite(s) { const t = TEXTE[s.code]; if (!t) throw new Error('Keine Texte für ' + s.code); @@ -74,6 +128,7 @@ function seite(s) { .replace(/\{\{URL\}\}/g, `${BASIS}/${s.code}`) .replace(/\{\{HREFLANG\}\}/g, hreflangBlock()) .replace(/\{\{WAEHLER_CSS\}\}/g, WAEHLER_CSS) + .replace(/\{\{SCHEMA\}\}/g, schemaBlock(s, t)) .replace(/\{\{WAEHLER\}\}/g, waehlerBlock(s.code, t.navLabel)) .replace(/\{\{H1_A\}\}/g, t.h1a) .replace(/\{\{H1_B\}\}/g, t.h1b) @@ -126,4 +181,5 @@ if (!idx.includes('.sprachwahl {')) { } fs.writeFileSync(idxPfad, idx, 'utf8'); -console.log(`${n} Sprachseiten erzeugt + index.html aktualisiert (${ALLE.length} Sprachen gesamt)`); +const urls = sitemapSchreiben(); +console.log(`${n} Sprachseiten erzeugt + index.html aktualisiert (${ALLE.length} Sprachen) + sitemap.xml mit ${urls} URLs`); diff --git a/tools/sprachseiten/vorlage.html b/tools/sprachseiten/vorlage.html index eeb5838..ad180e4 100644 --- a/tools/sprachseiten/vorlage.html +++ b/tools/sprachseiten/vorlage.html @@ -116,6 +116,9 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ar.html b/webseite/ar.html index d53d076..2bd8960 100644 --- a/webseite/ar.html +++ b/webseite/ar.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/bg.html b/webseite/bg.html index 57fec23..e5e454c 100644 --- a/webseite/bg.html +++ b/webseite/bg.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/bs.html b/webseite/bs.html index 0e85201..36de8d1 100644 --- a/webseite/bs.html +++ b/webseite/bs.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/el.html b/webseite/el.html index b33f76c..f51d935 100644 --- a/webseite/el.html +++ b/webseite/el.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/en.html b/webseite/en.html index 29db1a9..0316a3a 100644 --- a/webseite/en.html +++ b/webseite/en.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/es.html b/webseite/es.html index 56ce719..f6ec371 100644 --- a/webseite/es.html +++ b/webseite/es.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/fa.html b/webseite/fa.html index 5896e2f..8b37c1b 100644 --- a/webseite/fa.html +++ b/webseite/fa.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/fr.html b/webseite/fr.html index 060da81..3719ec0 100644 --- a/webseite/fr.html +++ b/webseite/fr.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/hi.html b/webseite/hi.html index c033039..f28f292 100644 --- a/webseite/hi.html +++ b/webseite/hi.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/hr.html b/webseite/hr.html index cfa605c..d42a676 100644 --- a/webseite/hr.html +++ b/webseite/hr.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/hu.html b/webseite/hu.html index 3dd29f2..b576129 100644 --- a/webseite/hu.html +++ b/webseite/hu.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/it.html b/webseite/it.html index e937908..cd1c7bc 100644 --- a/webseite/it.html +++ b/webseite/it.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ku.html b/webseite/ku.html index 659a3c3..22741f8 100644 --- a/webseite/ku.html +++ b/webseite/ku.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/pl.html b/webseite/pl.html index b754e7c..daaf732 100644 --- a/webseite/pl.html +++ b/webseite/pl.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ps.html b/webseite/ps.html index 1adb8a9..cc98377 100644 --- a/webseite/ps.html +++ b/webseite/ps.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/pt.html b/webseite/pt.html index f421ca1..fe65ba8 100644 --- a/webseite/pt.html +++ b/webseite/pt.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ro.html b/webseite/ro.html index 9766ab3..10fdfa1 100644 --- a/webseite/ro.html +++ b/webseite/ro.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ru.html b/webseite/ru.html index c69a397..f5dee65 100644 --- a/webseite/ru.html +++ b/webseite/ru.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/sitemap.xml b/webseite/sitemap.xml index 5d3210c..c92adb2 100644 --- a/webseite/sitemap.xml +++ b/webseite/sitemap.xml @@ -1,33 +1,930 @@ - - https://behoerdenklar.de/2026-09-18 - https://behoerdenklar.de/tr2026-09-18 - https://behoerdenklar.de/ar2026-09-18 - https://behoerdenklar.de/ru2026-09-18 - https://behoerdenklar.de/uk2026-09-18 - https://behoerdenklar.de/pl2026-09-18 - https://behoerdenklar.de/ro2026-09-18 - https://behoerdenklar.de/en2026-09-18 - https://behoerdenklar.de/fa2026-09-18 - https://behoerdenklar.de/ku2026-09-18 - https://behoerdenklar.de/bg2026-09-18 - https://behoerdenklar.de/hr2026-09-18 - https://behoerdenklar.de/sr2026-09-18 - https://behoerdenklar.de/bs2026-09-18 - https://behoerdenklar.de/sq2026-09-18 - https://behoerdenklar.de/it2026-09-18 - https://behoerdenklar.de/el2026-09-18 - https://behoerdenklar.de/es2026-09-18 - https://behoerdenklar.de/pt2026-09-18 - https://behoerdenklar.de/fr2026-09-18 - https://behoerdenklar.de/hu2026-09-18 - https://behoerdenklar.de/vi2026-09-18 - https://behoerdenklar.de/hi2026-09-18 - https://behoerdenklar.de/ur2026-09-18 - https://behoerdenklar.de/ps2026-09-18 - https://behoerdenklar.de/ti2026-09-18 - https://behoerdenklar.de/so2026-09-18 - https://behoerdenklar.de/zh2026-09-18 + + + https://behoerdenklar.de/ + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/tr + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ar + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ru + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/uk + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/pl + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ro + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/en + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/fa + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ku + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/bg + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/hr + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/sr + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/bs + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/sq + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/it + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/el + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/es + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/pt + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/fr + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/hu + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/vi + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/hi + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ur + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ps + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/ti + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/so + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/zh + 2026-09-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://behoerdenklar.de/demo2026-07-24 https://behoerdenklar.de/ratgeber/2026-07-25 https://behoerdenklar.de/ratgeber/jobcenter-mitwirkungsaufforderung2026-07-25 diff --git a/webseite/so.html b/webseite/so.html index e8e0652..bdd3abb 100644 --- a/webseite/so.html +++ b/webseite/so.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/sq.html b/webseite/sq.html index 841c16a..ded2942 100644 --- a/webseite/sq.html +++ b/webseite/sq.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/sr.html b/webseite/sr.html index d902937..8df185e 100644 --- a/webseite/sr.html +++ b/webseite/sr.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ti.html b/webseite/ti.html index 5ccd9d6..811537e 100644 --- a/webseite/ti.html +++ b/webseite/ti.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/tr.html b/webseite/tr.html index d3122c9..93b007c 100644 --- a/webseite/tr.html +++ b/webseite/tr.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/uk.html b/webseite/uk.html index 61422ee..864a005 100644 --- a/webseite/uk.html +++ b/webseite/uk.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/ur.html b/webseite/ur.html index f41df6f..d822d35 100644 --- a/webseite/ur.html +++ b/webseite/ur.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/vi.html b/webseite/vi.html index f1c9406..6ec4c96 100644 --- a/webseite/vi.html +++ b/webseite/vi.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +
diff --git a/webseite/zh.html b/webseite/zh.html index 32f5968..fcd6057 100644 --- a/webseite/zh.html +++ b/webseite/zh.html @@ -149,6 +149,56 @@ .wl-input::placeholder { color: #9a958a; } .wl-btn { width: 100%; cursor: pointer; text-align: center; font-family: inherit; } +