feat: Implement dynamic OG images

This commit is contained in:
gpt-engineer-app[bot]
2025-10-29 16:49:41 +00:00
parent 320df82329
commit ac63e1d2db
9 changed files with 166 additions and 0 deletions

78
src/hooks/useOpenGraph.ts Normal file
View File

@@ -0,0 +1,78 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { getBannerUrls } from '@/lib/cloudflareImageUtils';
interface OpenGraphOptions {
title: string;
description?: string;
imageUrl?: string;
imageId?: string;
type?: 'website' | 'article' | 'profile';
enabled?: boolean;
}
export function useOpenGraph({
title,
description,
imageUrl,
imageId,
type = 'website',
enabled = true
}: OpenGraphOptions) {
const location = useLocation();
const currentUrl = window.location.origin + location.pathname;
useEffect(() => {
if (!enabled || !title) return;
// Determine the image to use
let finalImageUrl = '/og-image.png';
if (imageId) {
const bannerUrls = getBannerUrls(imageId);
finalImageUrl = bannerUrls.desktop || imageUrl || '/og-image.png';
} else if (imageUrl) {
finalImageUrl = imageUrl;
}
// Convert relative URL to absolute for social media
if (finalImageUrl.startsWith('/')) {
finalImageUrl = window.location.origin + finalImageUrl;
}
// Update or create meta tags
updateMetaTag('og:title', title);
updateMetaTag('og:description', description || 'Explore theme parks and roller coasters worldwide with ThrillWiki');
updateMetaTag('og:image', finalImageUrl);
updateMetaTag('og:type', type);
updateMetaTag('og:url', currentUrl);
// Twitter tags
updateMetaTag('twitter:title', title, 'name');
updateMetaTag('twitter:description', description || 'Explore theme parks and roller coasters worldwide with ThrillWiki', 'name');
updateMetaTag('twitter:image', finalImageUrl, 'name');
return () => {
updateMetaTag('og:title', 'ThrillWiki - Theme Park & Roller Coaster Database');
updateMetaTag('og:description', 'Explore theme parks and roller coasters worldwide with ThrillWiki - the comprehensive database for enthusiasts');
updateMetaTag('og:image', window.location.origin + '/og-image.png');
updateMetaTag('og:type', 'website');
updateMetaTag('twitter:title', 'ThrillWiki - Theme Park & Roller Coaster Database', 'name');
updateMetaTag('twitter:description', 'Explore theme parks and roller coasters worldwide with ThrillWiki - the comprehensive database for enthusiasts', 'name');
updateMetaTag('twitter:image', window.location.origin + '/og-image.png', 'name');
};
}, [title, description, imageUrl, imageId, type, currentUrl, enabled]);
}
function updateMetaTag(property: string, content: string, attributeName: 'property' | 'name' = 'property') {
let meta = document.querySelector(`meta[${attributeName}="${property}"]`);
if (!meta) {
meta = document.createElement('meta');
meta.setAttribute(attributeName, property);
document.head.appendChild(meta);
}
meta.setAttribute('content', content);
}