Files
Anelia-Wolf/src/app/sitemap.ts
T
knsoandClaude Opus 5 33ec0df7e3 Messe-Landingpage /her-career/ zur herCAREER Expo 2026
Ziel des QR-Codes auf der Rückwandgrafik. Der gedruckte Code zeigt auf
https://her-career.anelia-wolf.com – die Adresse ist damit unveränderlich.
Die Seite liegt als /her-career/ im normalen Export, die Subdomain liefert
dieselbe Datei aus demselben Docroot aus; DNS, Zertifikat, Vhosts für nginx
und Apache und die Prüfbefehle stehen in docs/SUBDOMAIN-HERCAREER.md.

Aufbau in beiden Sprachen: Hero (ink) → 01 Messe-Special → 02 Themen →
03 Auf der Messe → 04 Kontakt mit dem Formular. Die vier Themenblöcke der
Rückwand liegen auf den drei Leistungsseiten, wie in der Navigation; jede
Zeile verlinkt absolut auf die Hauptdomain.

Der Wortlaut des Messe-Specials fehlt noch und steht sichtbar als „[…]“ auf
der Seite. Der Build-Guard hält den Launch-Flip an, bis er da ist
(CONTENT_TODO in src/lib/legal.ts, docs/OFFENE-DATEN.md Punkte 2.7–2.9).
Deadline ist nicht der Livegang, sondern der 22.10.2026.

- Canonical auf anelia-wolf.com/her-career/, damit die Subdomain-Kopie nicht
  ein zweites Mal im Index steht
- flags.showHerCareer trägt Termine-Ledger, Sitemap-Eintrag und die
  Meta-Beschreibung mit Stand und Uhrzeit. Ab dem 24.10.2026 auf false
- ServiceHero: facts und cta sind optional – ohne beides und ohne Foto
  entfällt die rechte Spalte
- ProcessContact: optionaler Zähler, die Messeseite nummeriert ihre Abschnitte
- Kopf-CTA auf dieser Seite ausgeblendet. Das macht eine Regel in globals.css,
  weil der Kopf außerhalb von <main> liegt und auf der Subdomain der Pfad
  ohnehin „/“ ist

Enthält außerdem die bis dahin nicht committeten Änderungen an Header,
LangSwitch, OverlayMenu, Wordmark und globals.css.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 22:39:32 +02:00

53 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { MetadataRoute } from "next";
import { LANGS, routesByLang, type Lang, type PageKey } from "@/lib/i18n";
import { flags, site } from "@/lib/site";
/** Static export: metadata routes are prerendered; mark explicitly (Next static-exports guide). */
export const dynamic = "force-static";
type ChangeFrequency = NonNullable<MetadataRoute.Sitemap[number]["changeFrequency"]>;
type PageEntry = { page: PageKey; changeFrequency: ChangeFrequency; priority: number };
/* Die Messe-Landingpage steht nur in der Sitemap, solange die Messe bevorsteht.
Gefunden wird sie ohnehin über den gedruckten QR-Code, nicht über die Suche –
nach dem Event wäre sie ein Eintrag, der auf ein vergangenes Datum zeigt. */
const herCareerPages: ReadonlyArray<PageEntry> = flags.showHerCareer
? [{ page: "herCareer", changeFrequency: "monthly", priority: 0.5 }]
: [];
const pages: ReadonlyArray<PageEntry> = [
{ page: "home", changeFrequency: "monthly", priority: 1 },
{ page: "coaching", changeFrequency: "monthly", priority: 0.8 },
{ page: "trainings", changeFrequency: "monthly", priority: 0.8 },
{ page: "keynotes", changeFrequency: "monthly", priority: 0.8 },
...herCareerPages,
{ page: "impressum", changeFrequency: "yearly", priority: 0.2 },
{ page: "datenschutz", changeFrequency: "yearly", priority: 0.2 },
];
/* Die englische Fassung ist eine Übersetzung, keine eigenständige Seite: gleiche
Änderungsfrequenz, aber niedrigere Priorität, damit Deutsch die Originalfassung bleibt.
Jeder Eintrag nennt über `alternates.languages` beide Fassungen – dasselbe hreflang,
das die Seiten im <head> tragen. */
const PRIORITY_FACTOR: Record<Lang, number> = { de: 1, en: 0.9 };
export default function sitemap(): MetadataRoute.Sitemap {
// Evaluated at build time (no request time in a static export): "last modified" = last build.
const lastModified = new Date();
return LANGS.flatMap((lang) =>
pages.map(({ page, changeFrequency, priority }) => ({
url: `${site.url}${routesByLang[lang][page]}`,
lastModified,
changeFrequency,
priority: Number((priority * PRIORITY_FACTOR[lang]).toFixed(2)),
alternates: {
languages: {
de: `${site.url}${routesByLang.de[page]}`,
en: `${site.url}${routesByLang.en[page]}`,
},
},
})),
);
}