das marketing frontend wurde auf lokalisierte urls umgestellt.
This commit is contained in:
@@ -3,20 +3,35 @@
|
||||
## Goal
|
||||
Establish a consistent canonical and hreflang setup for the marketing site so search engines can index German and English content without duplicate-content penalties.
|
||||
|
||||
## Status (Stand 17.02.2026)
|
||||
- **Discovery:** Not started.
|
||||
- **Implementation:** Not started.
|
||||
## Status (Stand 18.02.2026)
|
||||
- **Discovery:** In progress (route audit complete).
|
||||
- **Implementation:** In progress (canonical and locale-prefixed routing live).
|
||||
- **Validation:** Not started.
|
||||
|
||||
## Discovery
|
||||
- [ ] Audit current route map and localized content coverage (marketing pages, blog, checkout flow).
|
||||
- [ ] Decide on URL strategy (session-based locale vs. language-prefixed routes) and document migration implications.
|
||||
- [ ] Identify required updates to `MarketingLayout`, sitemap generation, and Inertia responses for localized alternates.
|
||||
- [x] Audit current route map and localized content coverage (marketing pages, blog, checkout flow).
|
||||
- Marketing routes live in `routes/web.php` without locale prefixes. Locale handling is session-based via `LocaleController::set`, `HandleInertiaRequests`, and `useLocalizedRoutes`.
|
||||
- Slug coverage is mixed: `/contact` (EN) and `/kontakt` (DE) coexist, `/how-it-works` vs. `/so-funktionierts`, while other key pages only exist once (e.g. `/packages`, `/demo`, `/blog`, legal pages such as `/impressum` with no EN variant). Occasion detail routes are German-only (`/anlaesse/{type}` with `hochzeit`, `geburtstag`, etc.).
|
||||
- Blog URLs are shared across locales (`/blog`, `/blog/{slug}`), with translated content injected server-side. Checkout surfaces (`/purchase-wizard/{package}`, `/checkout/{package}`) rely on shared slugs and localized copy but no alternate URLs.
|
||||
- `MarketingLayout` currently generates a single canonical URL per request and an `x-default` alternate, but no locale-specific `hreflang` links. Canonical calculation removes a `/de|/en` prefix even though paths are prefix-free, so both locales resolve to the same canonical if we later introduce prefixed URLs.
|
||||
- The sitemap at `public/sitemap.xml` already lists `/de/...` and `/en/...` alternates that the app does not currently serve, causing mismatch risk.
|
||||
- [x] Decide on URL strategy (session-based locale vs. language-prefixed routes) and document migration implications.
|
||||
- Decision: adopt path-prefixed locales (`/{locale}/{slug}`) for all marketing and checkout-facing routes, matching the i18n PRP guidance. Default requests (`/foo`) will 301 to the locale-specific URL using the visitor’s persisted preference or `de` fallback.
|
||||
- Migration outline:
|
||||
1. Introduce a `SetLocaleFromPath` middleware to extract the first segment and share it with Inertia; wire it into a `Route::group` with `prefix('{locale}')` (constrained to `de|en`) in `routes/web.php`.
|
||||
2. Move existing marketing routes into the prefixed group, normalising slugs so EN and DE share identical structures where feasible (e.g. `/de/kontakt` → `/de/contact` or `/de/kontakt` mirrored by `/en/contact`). Keep legacy German-only slugs (`/so-funktionierts`, `/anlaesse/...`) behind per-locale path maps.
|
||||
3. Add legacy fallback routes (without prefix) that permanently redirect to the new prefixed URLs to preserve existing backlinks and sitemap entries.
|
||||
4. Ensure Inertia helpers (`useLocalizedRoutes`) and navigation components build URLs with the active locale segment instead of relying on session posts to `/set-locale`.
|
||||
- Blog slugs remain language-agnostic identifiers under `/de/blog/{slug}` and `/en/blog/{slug}`; content localization continues via translated fields.
|
||||
- [x] Identify required updates to `MarketingLayout`, sitemap generation, and Inertia responses for localized alternates.
|
||||
- `MarketingLayout` needs to accept structured SEO props (canonical URL, title, description, alternates) instead of deriving everything client-side. It should emit `<link rel="alternate" hreflang="">` entries for each supported locale plus `x-default`, set `og:locale`/`og:locale:alternate`, and keep canonical URLs locale-specific (no prefix stripping).
|
||||
- Server responses should standardise SEO data via a helper (e.g. `MarketingPage::make()` or dedicated view model) so each `Inertia::render` call provides `seo` props with `canonical`, `alternates`, and translated meta. `HandleInertiaRequests` can share `supportedLocales` and the resolved host, while a new `LocalizedUrlGenerator` service maps routes/slugs per locale.
|
||||
- The static `public/sitemap.xml` must be regenerated (or replaced with an automated generator/Artisan command) once prefixed URLs exist, ensuring each entry carries self-referential canonicals and paired `xhtml:link` elements. Include blog detail pages and legal pages for both locales.
|
||||
|
||||
## Implementation
|
||||
- [ ] Ensure canonical URLs and hreflang tags are generated per locale with reciprocal references.
|
||||
- [ ] Expose locale-specific URLs in navigation, Open Graph tags, and any structured data.
|
||||
- [ ] Update translation files and config to support the chosen URL strategy.
|
||||
- [x] Ensure canonical URLs and hreflang tags are generated per locale with reciprocal references.
|
||||
- [x] Expose locale-specific URLs in navigation, Open Graph tags, and any structured data.
|
||||
- [x] Update translation files and config to support the chosen URL strategy.
|
||||
|
||||
## Validation
|
||||
- [ ] Add automated checks (feature test or Playwright) verifying hreflang/canonical tags for both locales.
|
||||
@@ -24,6 +39,5 @@ Establish a consistent canonical and hreflang setup for the marketing site so se
|
||||
- [ ] Update docs (PRP + marketing playbooks) with the final hreflang strategy and operational guidance.
|
||||
|
||||
## Open Questions
|
||||
- Should blog posts use language-specific slugs or shared identifiers with query parameters?
|
||||
- How will we handle locale fallbacks for missing translations when hreflang is enforced?
|
||||
- Do we need localized sitemap indexes per language or a unified sitemap with hreflang annotations?
|
||||
|
||||
Reference in New Issue
Block a user