feat(Sitemap, SEO): update sitemap generation and SEO configurations

- Enhanced update-sitemap.sh to generate a new sitemap structure with lastmod dates for additional URLs.
- Updated SEO configurations in server.js and seo.js to allow indexing for impressum and datenschutz pages.
- Introduced a list of noindex prefixes to manage SEO settings dynamically based on route paths.
- Added structured FAQ schema in index.html to improve search engine visibility and user engagement.
This commit is contained in:
Torsten Schulz (local)
2026-03-27 11:22:55 +01:00
parent ddb3025b84
commit a7d3e5b094
5 changed files with 162 additions and 15 deletions

View File

@@ -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 = '') {