P1: path routing, prerender shells, E2E, and HelmetProvider donate fix.

Replace hash URLs with path-based routing, post-build prerender for money pages, Playwright smoke tests, and wrap the app in HelmetProvider so /donate mounts correctly.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
defiQUG
2026-06-16 11:11:20 -07:00
co-authored by Cursor
parent 6c0de165d3
commit 4e4df13ab1
33 changed files with 2545 additions and 2324 deletions
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env node
/**
* Post-build prerender shells for money/SEO pages (crawlable HTML + meta).
* Usage: node scripts/prerender-money-pages.mjs [--dist=dist]
*/
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const repoRoot = join(__dirname, '..')
const distArg = process.argv.find((a) => a.startsWith('--dist='))
const distDir = distArg ? distArg.split('=')[1] : join(repoRoot, 'dist')
const PAGES = [
{
path: 'donate',
title: 'Donate | Miracles in Motion Foundation',
description:
'Give with confidence to Miracles in Motion Foundation. Secure online donations support outreach and emergency assistance in Los Angeles County.',
h1: 'Donate',
lead: 'Your gift restores hope through outreach, emergency assistance, and compassionate care.',
},
{
path: 'request-assistance',
title: 'Request Assistance | Miracles in Motion Foundation',
description:
'Request non-emergency assistance from Miracles in Motion Foundation. We respond within 24–48 hours. For urgent needs call (818) 491-6884.',
h1: 'Request Assistance',
lead: 'Compassionate support for individuals and families in crisis throughout Los Angeles County.',
},
{
path: 'about',
title: 'About Us | Miracles in Motion Foundation',
description:
'Miracles in Motion Foundation is a California nonprofit serving Los Angeles County with faith, hope, and community restoration.',
h1: 'About Miracles in Motion',
lead: 'Faith • Hope • Community • Restoration',
},
]
const indexPath = join(distDir, 'index.html')
let shell
try {
shell = readFileSync(indexPath, 'utf8')
} catch {
console.error(`prerender: missing ${indexPath} — run vite build first`)
process.exit(1)
}
for (const page of PAGES) {
const dir = join(distDir, page.path)
mkdirSync(dir, { recursive: true })
const noscript = `<noscript data-prerender="${page.path}"><article style="max-width:48rem;margin:2rem auto;padding:0 1rem;font-family:system-ui,sans-serif"><h1>${page.h1}</h1><p>${page.lead}</p><p><a href="/">Home</a> · <a href="/donate">Donate</a> · <a href="/request-assistance">Request assistance</a></p></article></noscript>`
let html = shell
.replace(/<title>[^<]*<\/title>/, `<title>${page.title}</title>`)
.replace(
/<meta name="description" content="[^"]*"/,
`<meta name="description" content="${page.description}"`,
)
.replace(/<meta property="og:title" content="[^"]*"/, `<meta property="og:title" content="${page.title}"`)
.replace(
/<meta property="og:description" content="[^"]*"/,
`<meta property="og:description" content="${page.description}"`,
)
.replace(/<meta property="og:url" content="[^"]*"/, `<meta property="og:url" content="https://mim4u.org/${page.path}"`)
.replace('</body>', `${noscript}\n</body>`)
writeFileSync(join(dir, 'index.html'), html)
console.log(`prerender: ${page.path}/index.html`)
}
console.log('prerender: done')