Files
WooNooW/customer-spa/src/components/SEOHead.tsx
Dwindi Ramadhana 75a82cf16c feat: add dynamic meta tags for social sharing (Phase 4-5)
Phase 4: Dynamic Meta Tags
- Added react-helmet-async dependency
- Created SEOHead component with Open Graph and Twitter Card support
- Added HelmetProvider wrapper to App.tsx
- Integrated SEOHead in Product page (title, description, image, product info)
- Integrated SEOHead in Shop page (basic meta tags)

Phase 5: Auto-Flush Permalinks
- Enhanced settings change handler to only flush when spa_mode,
  spa_page, or use_browser_router changes
- Plugin already flushes on activation (Installer.php)

This enables proper link previews when sharing product URLs
on Facebook, Twitter, Slack, etc.
2026-01-04 10:40:10 +07:00

69 lines
2.3 KiB
TypeScript

import { Helmet } from 'react-helmet-async';
interface SEOHeadProps {
title?: string;
description?: string;
image?: string;
url?: string;
type?: 'website' | 'product' | 'article';
product?: {
price?: string;
currency?: string;
availability?: 'in stock' | 'out of stock';
};
}
/**
* SEOHead Component
* Adds dynamic meta tags for social media sharing (Open Graph, Twitter Cards)
* Used for link previews on Facebook, Twitter, Slack, etc.
*/
export function SEOHead({
title,
description,
image,
url,
type = 'website',
product,
}: SEOHeadProps) {
const config = (window as any).woonoowCustomer;
const siteName = config?.siteName || 'Store';
const siteUrl = config?.siteUrl || '';
const fullTitle = title ? `${title} | ${siteName}` : siteName;
const fullUrl = url || (typeof window !== 'undefined' ? window.location.href : '');
return (
<Helmet>
{/* Basic Meta Tags */}
<title>{fullTitle}</title>
{description && <meta name="description" content={description} />}
{/* Open Graph (Facebook, LinkedIn, etc.) */}
<meta property="og:site_name" content={siteName} />
<meta property="og:title" content={title || siteName} />
{description && <meta property="og:description" content={description} />}
<meta property="og:type" content={type} />
<meta property="og:url" content={fullUrl} />
{image && <meta property="og:image" content={image} />}
{/* Twitter Card */}
<meta name="twitter:card" content={image ? 'summary_large_image' : 'summary'} />
<meta name="twitter:title" content={title || siteName} />
{description && <meta name="twitter:description" content={description} />}
{image && <meta name="twitter:image" content={image} />}
{/* Product-specific meta tags */}
{type === 'product' && product && (
<>
<meta property="product:price:amount" content={product.price} />
<meta property="product:price:currency" content={product.currency} />
<meta property="product:availability" content={product.availability} />
</>
)}
</Helmet>
);
}
export default SEOHead;