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.
This commit is contained in:
@@ -10,6 +10,7 @@ import { ProductCard } from '@/components/ProductCard';
|
||||
import { toast } from 'sonner';
|
||||
import { useTheme, useLayout } from '@/contexts/ThemeContext';
|
||||
import { useShopSettings } from '@/hooks/useAppearanceSettings';
|
||||
import SEOHead from '@/components/SEOHead';
|
||||
import type { ProductsResponse, ProductCategory, Product } from '@/types/product';
|
||||
|
||||
export default function Shop() {
|
||||
@@ -22,25 +23,25 @@ export default function Shop() {
|
||||
const [category, setCategory] = useState('');
|
||||
const [sortBy, setSortBy] = useState('');
|
||||
const { addItem } = useCartStore();
|
||||
|
||||
|
||||
// Map grid columns setting to Tailwind classes (responsive)
|
||||
const gridCols = typeof shopLayout.grid_columns === 'object'
|
||||
? shopLayout.grid_columns
|
||||
const gridCols = typeof shopLayout.grid_columns === 'object'
|
||||
? shopLayout.grid_columns
|
||||
: { mobile: '2', tablet: '3', desktop: '4' };
|
||||
|
||||
|
||||
// Map to actual Tailwind classes (can't use template literals due to purging)
|
||||
const mobileClass = {
|
||||
'1': 'grid-cols-1',
|
||||
'2': 'grid-cols-2',
|
||||
'3': 'grid-cols-3',
|
||||
}[gridCols.mobile] || 'grid-cols-2';
|
||||
|
||||
|
||||
const tabletClass = {
|
||||
'2': 'md:grid-cols-2',
|
||||
'3': 'md:grid-cols-3',
|
||||
'4': 'md:grid-cols-4',
|
||||
}[gridCols.tablet] || 'md:grid-cols-3';
|
||||
|
||||
|
||||
const desktopClass = {
|
||||
'2': 'lg:grid-cols-2',
|
||||
'3': 'lg:grid-cols-3',
|
||||
@@ -48,22 +49,22 @@ export default function Shop() {
|
||||
'5': 'lg:grid-cols-5',
|
||||
'6': 'lg:grid-cols-6',
|
||||
}[gridCols.desktop] || 'lg:grid-cols-4';
|
||||
|
||||
|
||||
const gridColsClass = `${mobileClass} ${tabletClass} ${desktopClass}`;
|
||||
|
||||
|
||||
// Masonry column classes
|
||||
const masonryMobileClass = {
|
||||
'1': 'columns-1',
|
||||
'2': 'columns-2',
|
||||
'3': 'columns-3',
|
||||
}[gridCols.mobile] || 'columns-2';
|
||||
|
||||
|
||||
const masonryTabletClass = {
|
||||
'2': 'md:columns-2',
|
||||
'3': 'md:columns-3',
|
||||
'4': 'md:columns-4',
|
||||
}[gridCols.tablet] || 'md:columns-3';
|
||||
|
||||
|
||||
const masonryDesktopClass = {
|
||||
'2': 'lg:columns-2',
|
||||
'3': 'lg:columns-3',
|
||||
@@ -71,9 +72,9 @@ export default function Shop() {
|
||||
'5': 'lg:columns-5',
|
||||
'6': 'lg:columns-6',
|
||||
}[gridCols.desktop] || 'lg:columns-4';
|
||||
|
||||
|
||||
const masonryColsClass = `${masonryMobileClass} ${masonryTabletClass} ${masonryDesktopClass}`;
|
||||
|
||||
|
||||
const isMasonry = shopLayout.grid_style === 'masonry';
|
||||
|
||||
// Fetch products
|
||||
@@ -99,7 +100,7 @@ export default function Shop() {
|
||||
product_id: product.id,
|
||||
quantity: 1,
|
||||
});
|
||||
|
||||
|
||||
// Add to local cart store
|
||||
addItem({
|
||||
key: `${product.id}`,
|
||||
@@ -111,7 +112,7 @@ export default function Shop() {
|
||||
virtual: product.virtual,
|
||||
downloadable: product.downloadable,
|
||||
});
|
||||
|
||||
|
||||
toast.success(`${product.name} added to cart!`, {
|
||||
action: {
|
||||
label: 'View Cart',
|
||||
@@ -126,6 +127,11 @@ export default function Shop() {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{/* SEO Meta Tags for Social Sharing */}
|
||||
<SEOHead
|
||||
title="Shop"
|
||||
description="Browse our collection of products"
|
||||
/>
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-bold mb-2">Shop</h1>
|
||||
|
||||
Reference in New Issue
Block a user