diff --git a/backend/server.js b/backend/server.js index b10592a3..27985cb1 100644 --- a/backend/server.js +++ b/backend/server.js @@ -111,15 +111,38 @@ const SEO_ROUTE_CONFIG = { '/impressum': { title: 'Impressum | Trainingstagebuch', description: 'Impressum von Trainingstagebuch.', - robots: 'noindex,follow', + robots: 'index,follow', }, '/datenschutz': { title: 'Datenschutzerklärung | Trainingstagebuch', description: 'Datenschutzerklärung von Trainingstagebuch.', - robots: 'noindex,follow', + robots: 'index,follow', }, }; +const SEO_NOINDEX_PREFIXES = [ + '/createclub', + '/showclub', + '/members', + '/diary', + '/pending-approvals', + '/schedule', + '/tournaments', + '/tournament-participations', + '/training-stats', + '/club-settings', + '/predefined-activities', + '/mytischtennis-account', + '/clicktt-account', + '/team-management', + '/permissions', + '/logs', + '/clicktt', + '/member-transfer-settings', + '/personal-settings', + '/orders', +]; + function normalizeSeoPath(pathname = '/') { if (!pathname || pathname === '') return '/'; if (pathname === '/') return '/'; @@ -132,9 +155,16 @@ function getSeoConfigForPath(pathname = '/') { .filter((routePath) => routePath !== '/' && normalizedPath.startsWith(routePath)) .sort((a, b) => b.length - a.length)[0]; - return (matchedPrefix && SEO_ROUTE_CONFIG[matchedPrefix]) - || SEO_ROUTE_CONFIG[normalizedPath] - || { ...SEO_DEFAULTS, robots: 'noindex,follow' }; + const configuredSeo = (matchedPrefix && SEO_ROUTE_CONFIG[matchedPrefix]) || SEO_ROUTE_CONFIG[normalizedPath]; + if (configuredSeo) { + return configuredSeo; + } + + const shouldNoindex = SEO_NOINDEX_PREFIXES.some((routePath) => normalizedPath.startsWith(routePath)); + return { + ...SEO_DEFAULTS, + robots: shouldNoindex ? 'noindex,follow' : SEO_DEFAULTS.robots + }; } function escapeHtmlAttribute(value = '') { diff --git a/frontend/index.html b/frontend/index.html index de4df13f..fb162a11 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -72,6 +72,54 @@ "url": "https://tt-tagebuch.de/" } +
diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index 61b7395b..c021c756 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -5,8 +5,20 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://tt-tagebuch.de/ - 2026-03-18 + 2026-03-27 weekly 1.0 + + https://tt-tagebuch.de/impressum + 2026-03-27 + yearly + 0.3 + + + https://tt-tagebuch.de/datenschutz + 2026-03-27 + yearly + 0.3 + diff --git a/frontend/src/utils/seo.js b/frontend/src/utils/seo.js index 1e6028f5..be790ba1 100644 --- a/frontend/src/utils/seo.js +++ b/frontend/src/utils/seo.js @@ -42,15 +42,38 @@ const ROUTE_SEO = { '/impressum': { title: 'Impressum | Trainingstagebuch', description: 'Impressum von Trainingstagebuch.', - robots: 'noindex,follow' + robots: 'index,follow' }, '/datenschutz': { title: 'Datenschutzerklärung | Trainingstagebuch', description: 'Datenschutzerklärung von Trainingstagebuch.', - robots: 'noindex,follow' + robots: 'index,follow' } }; +const NOINDEX_PREFIXES = [ + '/createclub', + '/showclub', + '/members', + '/diary', + '/pending-approvals', + '/schedule', + '/tournaments', + '/tournament-participations', + '/training-stats', + '/club-settings', + '/predefined-activities', + '/mytischtennis-account', + '/clicktt-account', + '/team-management', + '/permissions', + '/logs', + '/clicktt', + '/member-transfer-settings', + '/personal-settings', + '/orders' +]; + function normalizePath(path = '/') { if (!path || path === '') return '/'; if (path === '/') return '/'; @@ -63,13 +86,18 @@ export function getSeoConfigForPath(path) { .filter((routePath) => routePath !== '/' && normalizedPath.startsWith(routePath)) .sort((a, b) => b.length - a.length)[0]; - const routeSeo = (matchedPrefix && ROUTE_SEO[matchedPrefix]) || ROUTE_SEO[normalizedPath] || DEFAULT_SEO; + const routeSeo = (matchedPrefix && ROUTE_SEO[matchedPrefix]) || ROUTE_SEO[normalizedPath]; const canonicalPath = normalizedPath === '/' ? '' : normalizedPath; + const shouldNoindex = !routeSeo && NOINDEX_PREFIXES.some((routePath) => normalizedPath.startsWith(routePath)); + const finalSeo = routeSeo || { + ...DEFAULT_SEO, + robots: shouldNoindex ? 'noindex,follow' : DEFAULT_SEO.robots + }; return { - title: routeSeo.title || DEFAULT_SEO.title, - description: routeSeo.description || DEFAULT_SEO.description, - robots: routeSeo.robots || DEFAULT_SEO.robots, + title: finalSeo.title || DEFAULT_SEO.title, + description: finalSeo.description || DEFAULT_SEO.description, + robots: finalSeo.robots || DEFAULT_SEO.robots, canonical: `${SITE_URL}${canonicalPath}`, url: `${SITE_URL}${canonicalPath}`, image: DEFAULT_IMAGE diff --git a/update-sitemap.sh b/update-sitemap.sh index 3e37f0e0..4d1b5d71 100755 --- a/update-sitemap.sh +++ b/update-sitemap.sh @@ -15,8 +15,38 @@ fi echo "Aktualisiere lastmod-Datum auf: $TODAY" -# Ersetze alle lastmod-Daten mit dem heutigen Datum -sed -i "s/.*<\/lastmod>/${TODAY}<\/lastmod>/g" "$SITEMAP_FILE" +URLS=( + "https://tt-tagebuch.de/" + "https://tt-tagebuch.de/impressum" + "https://tt-tagebuch.de/datenschutz" +) + +cat > "$SITEMAP_FILE" < + + + ${URLS[0]} + ${TODAY} + weekly + 1.0 + + + ${URLS[1]} + ${TODAY} + yearly + 0.3 + + + ${URLS[2]} + ${TODAY} + yearly + 0.3 + + +EOF echo "✓ Sitemap aktualisiert" echo "" @@ -31,4 +61,3 @@ echo " -> URL eingeben: https://tt-tagebuch.de/sitemap.xml" echo "" echo "3. Sitemap testen:" echo " curl https://tt-tagebuch.de/sitemap.xml" -