feat: setup dynamic document metadata bindings for SEO SPA crawling

This commit is contained in:
Shekhar 2026-04-10 22:56:34 +05:30
parent f7052ee539
commit 089662d1f3
3 changed files with 36 additions and 15 deletions

View file

@ -1,4 +1,5 @@
import { useNavigate } from 'react-router-dom'
import { useEffect } from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { motion } from 'motion/react'
import { ArrowRight } from 'lucide-react'
import ProductCard from '../components/ProductCard'
@ -59,6 +60,14 @@ const cardVariant = {
export default function HomePage() {
const navigate = useNavigate()
useEffect(() => {
document.title = "Windows ISO Downloader | Official Microsoft Images"
const metaDesc = document.querySelector('meta[name="description"]')
if (metaDesc) {
metaDesc.setAttribute('content', "Download official Microsoft Windows ISO files. Fast, free, no registration required.")
}
}, [])
return (
<div className="max-w-4xl mx-auto px-5 pt-20 pb-16 relative" style={{ overflowX: 'hidden' }}>
@ -79,7 +88,7 @@ export default function HomePage() {
className="font-bold text-white tracking-tight leading-tight mb-4"
style={{ fontSize: 'clamp(1.6rem, 7.5vw, 3.75rem)' }}
>
Windows ISO <span className="text-white/25">Downloader</span>
Windows ISO <span className="text-white/50">Downloader</span>
</h1>
<p className="text-zinc-400 text-base max-w-sm mx-auto mb-6 leading-relaxed">
Direct links from Microsoft's CDN. No ads. No registration.
@ -116,10 +125,11 @@ export default function HomePage() {
>
{featured.map(product => (
<motion.div key={product.id} variants={cardVariant}>
<ProductCard
{...product}
onClick={() => navigate(`/product/${product.id}`)}
/>
<Link to={`/product/${product.id}`} className="block outline-none">
<ProductCard
{...product}
/>
</Link>
</motion.div>
))}
</motion.div>
@ -131,13 +141,13 @@ export default function HomePage() {
animate={{ opacity: 1 }}
transition={{ delay: 0.5 }}
>
<button
onClick={() => navigate('/products')}
<Link
to="/products"
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-xl border border-white/8 bg-white/4 text-sm text-zinc-400 hover:text-white hover:border-white/15 hover:bg-white/7 transition-all duration-200"
>
Browse all {featured.length > 0 ? '17' : ''} releases
Browse all {featured.length > 0 ? '16' : ''} releases
<ArrowRight size={14} />
</button>
</Link>
</motion.div>
{/* How it works */}

View file

@ -113,6 +113,14 @@ export default function ProductDetailPage() {
.then((data: Record<string, string>) => {
const name = data[productId!] ?? `Product ${productId}`
setProductName(name)
// Dynamic SEO injection
document.title = `${name} ISO Download | Windows ISO Downloader`
const descMeta = document.querySelector('meta[name="description"]')
if (descMeta) {
descMeta.setAttribute('content', `Download official ISO image for ${name}. Direct links pulled securely from Microsoft CDN servers.`)
}
// Extract build from parentheses e.g. "(26200.6584)"
const match = name.match(/\(([^)]+)\)/)
if (match) setBuildStr(match[1])

View file

@ -1,5 +1,5 @@
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useNavigate, Link } from 'react-router-dom'
import { motion } from 'motion/react'
import { Search, ArrowRight } from 'lucide-react'
import type { Product } from '../types'
@ -16,8 +16,11 @@ export default function ProductsPage() {
const [products, setProducts] = useState<Product[]>([])
const [isLoading, setIsLoading] = useState(true)
const [query, setQuery] = useState('')
useEffect(() => {
document.title = "All Windows Releases | Windows ISO Downloader"
const metaDesc = document.querySelector('meta[name="description"]')
if (metaDesc) metaDesc.setAttribute('content', "Browse all official Microsoft Windows ISO releases available for direct download.")
fetch('/data/products.json')
.then(r => r.json())
.then((data: Record<string, string>) => {
@ -99,8 +102,8 @@ export default function ProductsPage() {
show: { opacity: 1, x: 0, transition: { type: 'spring', stiffness: 300, damping: 28 } },
}}
>
<button
onClick={() => navigate(`/product/${product.id}`)}
<Link
to={`/product/${product.id}`}
className="group w-full flex items-center justify-between px-4 py-3.5 rounded-xl border border-white/6 bg-white/3 hover:bg-white/6 hover:border-white/12 transition-all text-left"
>
<div className="flex items-center gap-3">
@ -112,7 +115,7 @@ export default function ProductsPage() {
</span>
</div>
<ArrowRight size={14} className="text-white/20 group-hover:text-white/50 group-hover:translate-x-0.5 transition-all" />
</button>
</Link>
</motion.div>
))}
</motion.div>