React Helmet is great. It's also too much for a SPA with twelve dynamic blog routes. Here's what I shipped instead. I run Inithouse , a portfolio of about 14 web products. All built as React SPAs. Every single one needs proper meta tags for SEO: title, description, Open Graph, Twitter cards, JSON-LD. The usual stuff. I started with React Helmet. Worked fine for the first app. By app three, I was copy-pasting the same boilerplate helmet component across repos, fighting with nested helmet instances, and wondering why my bundle had an extra 12KB just to set a page title. So I wrote a hook. About 20 lines. It replaced Helmet across every project. The hook import { useEffect } from ' react ' ; interface SEOProps { title : string ; description ?: string ; image ?: string ; url ?: string ; type ?: string ; jsonLd ?: Record < string , unknown > ; } export function useSEO ({ title , description , image , url , type = ' website ' , jsonLd }: SEOProps ) { useEffect (() => { document .…