SEO optimization with React Helmet

Maya Patel Jan 2026
2 tabs
import { Helmet } from 'react-helmet-async'

interface SEOProps {
  title: string
  description: string
  image?: string
  url?: string
  type?: string
}

export function SEO({ title, description, image, url, type = 'website' }: SEOProps) {
  const siteUrl = import.meta.env.VITE_SITE_URL || 'https://example.com'
  const fullUrl = url ? `${siteUrl}${url}` : siteUrl
  const imageUrl = image ? `${siteUrl}${image}` : `${siteUrl}/default-og-image.jpg`

  return (
    <Helmet>
      <title>{title} | MyApp</title>
      <meta name="description" content={description} />

      {/* Open Graph */}
      <meta property="og:type" content={type} />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={imageUrl} />
      <meta property="og:url" content={fullUrl} />

      {/* Twitter Card */}
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={title} />
      <meta name="twitter:description" content={description} />
      <meta name="twitter:image" content={imageUrl} />

      {/* Canonical URL */}
      <link rel="canonical" href={fullUrl} />
    </Helmet>
  )
}
2 files · typescript Explain with highlit

SPAs struggle with SEO because content loads via JavaScript after the initial HTML. React Helmet manages document head tags like title, meta descriptions, and Open Graph tags per route. Each page component declares its own metadata, and Helmet ensures only the most recent values render. I create a reusable SEO component that accepts title, description, and image props. For serious SEO needs, I add server-side rendering, but Helmet alone helps with social sharing and user bookmarks. The library prevents duplicate tags and properly escapes content. Combined with React Router, every route can have custom metadata that updates as users navigate.