Make every served byte crawlable without executing JS, remove off-brand copy, and cut third-party requests. - Copy: replace off-brand terms (survival/crisis/collapse) in title, meta, OG/Twitter, JSON-LD and webmanifest with on-brand preparedness copy. Update App.vue i18n page_title/meta_description (EN+DE) too, since the app overwrites the head at runtime. Reconcile area count to the real 6. - Prerender: vite-plugin-seo-snapshot injects a static <noscript> snapshot (real <h1>, content, <a href>) after #app. JS users ignore <noscript>, so the live app/UX is unchanged; curl/no-JS crawlers get real content. - 404: nginx now returns true 404s on unknown paths (no soft-200 SPA fallback) with a branded 404 page. - Sitemap: drop no-op hreflang alternates, add <lastmod>. - Fonts: self-host Space Mono / DM Serif Display / Barlow (woff2, latin + latin-ext, font-display: swap); preload above-the-fold faces. No more fonts.googleapis/gstatic requests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
26 lines
1006 B
JavaScript
26 lines
1006 B
JavaScript
import { readFileSync } from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
// Injects a static, crawlable SEO snapshot into a <noscript> block in the
|
|
// served index.html. Browsers with JS enabled ignore <noscript>, so the live
|
|
// app and its UX are completely unaffected. Non-rendering crawlers and `curl`
|
|
// receive a real <h1>, descriptive content and <a href> links instead of an
|
|
// empty SPA shell.
|
|
export default function seoSnapshot() {
|
|
const snapshotPath = fileURLToPath(new URL('./src/seo-snapshot.html', import.meta.url))
|
|
return {
|
|
name: 'seo-snapshot',
|
|
transformIndexHtml(html) {
|
|
const snapshot = readFileSync(snapshotPath, 'utf8')
|
|
.replace(/<!--[\s\S]*?-->/g, '') // strip authoring comments from served HTML
|
|
.trim()
|
|
const block = `<noscript>\n${snapshot}\n</noscript>`
|
|
// Place it immediately after the app mount point.
|
|
return html.replace(
|
|
'<div id="app"></div>',
|
|
`<div id="app"></div>\n${block}`,
|
|
)
|
|
},
|
|
}
|
|
}
|