sum more SEO changes
This commit is contained in:
+55
-2
@@ -2365,6 +2365,10 @@ function escapeHtml(value) {
|
|||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stripSiteTitle(title) {
|
||||||
|
return String(title || '').replace(/\s+\|\s+Toothless' TSS Bot$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
function decodeRouteSegment(value) {
|
function decodeRouteSegment(value) {
|
||||||
try {
|
try {
|
||||||
return decodeURIComponent(value || '').replace(/\+/g, ' ').trim()
|
return decodeURIComponent(value || '').replace(/\+/g, ' ').trim()
|
||||||
@@ -2617,6 +2621,54 @@ function routeSeo(pathname) {
|
|||||||
return byPath[cleanPath] || notFoundSeo
|
return byPath[cleanPath] || notFoundSeo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function routeFallbackSections(seo) {
|
||||||
|
const sections = [
|
||||||
|
{ href: '/teams', label: 'TSS team leaderboard' },
|
||||||
|
{ href: '/players', label: 'TSS player leaderboard' },
|
||||||
|
{ href: '/battle-logs', label: 'Battle logs' },
|
||||||
|
{ href: '/tournaments', label: 'Tournaments' },
|
||||||
|
{ href: '/blog', label: 'Blog' },
|
||||||
|
]
|
||||||
|
|
||||||
|
if (seo.status === 404) {
|
||||||
|
return [
|
||||||
|
'<p>Use the links below to browse the live War Thunder Tournament Service leaderboards, battle logs, tournament brackets, and updates.</p>',
|
||||||
|
`<nav aria-label="Main sections"><ul>${sections.map((section) => `<li><a href="${section.href}">${escapeHtml(section.label)}</a></li>`).join('')}</ul></nav>`,
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seo.type === 'BlogPosting') {
|
||||||
|
const published = seo.publishedAt ? `<p>Published ${escapeHtml(seo.publishedAt)} by ${escapeHtml(seo.author || "Toothless' TSS Bot")}.</p>` : ''
|
||||||
|
return [
|
||||||
|
published,
|
||||||
|
'<p>Read more War Thunder TSS Bot news, feature updates, tournament tracking notes, and community announcements.</p>',
|
||||||
|
'<p><a href="/blog">Browse all blog posts</a></p>',
|
||||||
|
].filter(Boolean).join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seo.path === '/') {
|
||||||
|
return [
|
||||||
|
'<p>Toothless TSS Bot tracks War Thunder Tournament Service activity across teams, players, battle logs, tournaments, and squadron profiles.</p>',
|
||||||
|
`<nav aria-label="Main sections"><ul>${sections.map((section) => `<li><a href="${section.href}">${escapeHtml(section.label)}</a></li>`).join('')}</ul></nav>`,
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'<p>This page is part of Toothless TSS Bot, a War Thunder Tournament Service tracker for leaderboards, squadron profiles, battle logs, player stats, and tournament brackets.</p>',
|
||||||
|
`<nav aria-label="Related sections"><ul>${sections.filter((section) => section.href !== seo.path).map((section) => `<li><a href="${section.href}">${escapeHtml(section.label)}</a></li>`).join('')}</ul></nav>`,
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeFallbackHtml(seo) {
|
||||||
|
return [
|
||||||
|
'<main id="seo-fallback">',
|
||||||
|
`<h1>${escapeHtml(stripSiteTitle(seo.title))}</h1>`,
|
||||||
|
`<p>${escapeHtml(seo.description)}</p>`,
|
||||||
|
routeFallbackSections(seo),
|
||||||
|
'</main>',
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
function routeStructuredData(origin, seo, canonicalUrl) {
|
function routeStructuredData(origin, seo, canonicalUrl) {
|
||||||
const siteId = `${origin}/#website`
|
const siteId = `${origin}/#website`
|
||||||
const pageId = `${canonicalUrl}#webpage`
|
const pageId = `${canonicalUrl}#webpage`
|
||||||
@@ -2661,7 +2713,7 @@ function routeStructuredData(origin, seo, canonicalUrl) {
|
|||||||
...(seo.path === '/' ? [] : [{
|
...(seo.path === '/' ? [] : [{
|
||||||
'@type': 'ListItem',
|
'@type': 'ListItem',
|
||||||
position: 2,
|
position: 2,
|
||||||
name: seo.title.replace(/\s+\|\s+Toothless' TSS Bot$/, ''),
|
name: stripSiteTitle(seo.title),
|
||||||
item: canonicalUrl,
|
item: canonicalUrl,
|
||||||
}]),
|
}]),
|
||||||
],
|
],
|
||||||
@@ -2672,7 +2724,7 @@ function routeStructuredData(origin, seo, canonicalUrl) {
|
|||||||
items.push({
|
items.push({
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'BlogPosting',
|
'@type': 'BlogPosting',
|
||||||
headline: seo.title.replace(/\s+\|\s+Toothless' TSS Bot$/, ''),
|
headline: stripSiteTitle(seo.title),
|
||||||
description: seo.description,
|
description: seo.description,
|
||||||
url: canonicalUrl,
|
url: canonicalUrl,
|
||||||
image: imageUrl,
|
image: imageUrl,
|
||||||
@@ -2725,6 +2777,7 @@ function htmlWithSeo(req, data) {
|
|||||||
.replaceAll('__SEO_MODIFIED_TIME__', escapeHtml(seo.publishedAt || ''))
|
.replaceAll('__SEO_MODIFIED_TIME__', escapeHtml(seo.publishedAt || ''))
|
||||||
.replaceAll('__SEO_JSON_LD__', routeStructuredData(origin, seo, canonicalUrl).replace(/</g, '\\u003c'))
|
.replaceAll('__SEO_JSON_LD__', routeStructuredData(origin, seo, canonicalUrl).replace(/</g, '\\u003c'))
|
||||||
.replaceAll('__TURNSTILE_SESSION__', isTurnstileSessionVerified(req) ? 'verified' : 'required')
|
.replaceAll('__TURNSTILE_SESSION__', isTurnstileSessionVerified(req) ? 'verified' : 'required')
|
||||||
|
.replace('<div id="root"></div>', `<div id="root">\n${routeFallbackHtml(seo)}\n</div>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestPathname(req) {
|
function requestPathname(req) {
|
||||||
|
|||||||
Reference in New Issue
Block a user