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

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