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"
-