diff --git a/src/pages/ParkOwners.tsx b/src/pages/ParkOwners.tsx
index 4e4e3048..e62d6e0f 100644
--- a/src/pages/ParkOwners.tsx
+++ b/src/pages/ParkOwners.tsx
@@ -19,6 +19,7 @@ import { submitCompanyCreation } from '@/lib/companyHelpers';
import { useAuthModal } from '@/hooks/useAuthModal';
import { getErrorMessage } from '@/lib/errorHandler';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
const ParkOwners = () => {
useDocumentTitle('Property Owners');
@@ -119,6 +120,15 @@ const ParkOwners = () => {
return filtered;
}, [parkOwners, searchTerm, sortBy, filterBy]);
+ useOpenGraph({
+ title: 'Property Owners - ThrillWiki',
+ description: `Browse ${filteredAndSortedOwners.length} theme park property owners worldwide`,
+ imageUrl: filteredAndSortedOwners[0]?.banner_image_url,
+ imageId: filteredAndSortedOwners[0]?.banner_image_id,
+ type: 'website',
+ enabled: !isLoading
+ });
+
return (
diff --git a/src/pages/ParkRides.tsx b/src/pages/ParkRides.tsx
index 6bd725b4..792d559a 100644
--- a/src/pages/ParkRides.tsx
+++ b/src/pages/ParkRides.tsx
@@ -17,6 +17,7 @@ import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler';
import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
export default function ParkRides() {
const { parkSlug } = useParams<{ parkSlug: string }>();
@@ -150,6 +151,17 @@ export default function ParkRides() {
ride.manufacturer?.name?.toLowerCase().includes(searchQuery.toLowerCase())
);
+ useOpenGraph({
+ title: park ? `${park.name} - Rides & Attractions` : 'Park Rides',
+ description: park
+ ? `Explore ${filteredRides.length} rides and attractions at ${park.name}`
+ : undefined,
+ imageUrl: park?.banner_image_url || filteredRides[0]?.banner_image_url,
+ imageId: park?.banner_image_id || filteredRides[0]?.banner_image_id,
+ type: 'website',
+ enabled: !!park && !loading
+ });
+
const categories = [
{ value: 'all', label: 'All Categories' },
{ value: 'roller_coaster', label: 'Roller Coasters' },
diff --git a/src/pages/Parks.tsx b/src/pages/Parks.tsx
index 282e949b..dc2783f9 100644
--- a/src/pages/Parks.tsx
+++ b/src/pages/Parks.tsx
@@ -36,6 +36,7 @@ import { ParkForm } from '@/components/admin/ParkForm';
import { useAuth } from '@/hooks/useAuth';
import { useUserRole } from '@/hooks/useUserRole';
import { useAuthModal } from '@/hooks/useAuthModal';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
export interface FilterState {
search: string;
@@ -288,6 +289,30 @@ export default function Parks() {
return filtered;
}, [parks, filters, sort]);
+ const generateDescription = () => {
+ if (!parks.length) return 'Browse theme parks worldwide on ThrillWiki';
+
+ const activeFilters = [];
+ if (filters.country.length === 1) activeFilters.push(`in ${filters.country[0]}`);
+ if (filters.parkType.length > 0) activeFilters.push(filters.parkType.join(', '));
+ if (filters.status.length > 0) activeFilters.push(filters.status.join(', '));
+
+ if (activeFilters.length > 0) {
+ return `Browse ${filteredAndSortedParks.length} ${activeFilters.join(' ')} theme parks`;
+ }
+
+ return `Browse ${parks.length} theme parks worldwide`;
+ };
+
+ useOpenGraph({
+ title: 'Theme Parks - ThrillWiki',
+ description: generateDescription(),
+ imageUrl: filteredAndSortedParks[0]?.banner_image_url,
+ imageId: filteredAndSortedParks[0]?.banner_image_id,
+ type: 'website',
+ enabled: !loading
+ });
+
const activeFilterCount = useMemo(() => {
let count = 0;
if (filters.search) count++;
diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx
index 06c497bf..118d7495 100644
--- a/src/pages/Profile.tsx
+++ b/src/pages/Profile.tsx
@@ -31,6 +31,7 @@ import { UserBlockButton } from '@/components/profile/UserBlockButton';
import { PersonalLocationDisplay } from '@/components/profile/PersonalLocationDisplay';
import { useUserRole } from '@/hooks/useUserRole';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
// Activity type definitions
interface SubmissionActivity {
@@ -160,6 +161,15 @@ export default function Profile() {
// Update document title when profile changes
useDocumentTitle(profile?.username ? `${profile.username}'s Profile` : 'Profile');
+ useOpenGraph({
+ title: profile ? `${profile.display_name || profile.username} - ThrillWiki` : 'User Profile',
+ description: profile?.bio || (profile ? `${profile.display_name || profile.username}'s profile on ThrillWiki` : undefined),
+ imageUrl: profile?.avatar_url,
+ imageId: profile?.avatar_image_id,
+ type: 'profile',
+ enabled: !!profile
+ });
+
// Username validation
const usernameValidation = useUsernameValidation(editForm.username, profile?.username);
useEffect(() => {
diff --git a/src/pages/Rides.tsx b/src/pages/Rides.tsx
index ac5b400e..0c220cb5 100644
--- a/src/pages/Rides.tsx
+++ b/src/pages/Rides.tsx
@@ -23,6 +23,7 @@ import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler';
import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
export default function Rides() {
useDocumentTitle('Rides & Attractions');
@@ -266,6 +267,28 @@ export default function Rides() {
return filtered;
}, [rides, searchQuery, sortBy, filters]);
+ const generateDescription = () => {
+ if (!filteredAndSortedRides.length) return 'Discover thrilling rides and roller coasters worldwide';
+
+ const activeFilters = [];
+ if (filters.categories.length > 0) activeFilters.push(filters.categories.join(', '));
+ if (filters.status !== 'all') activeFilters.push(filters.status);
+
+ if (activeFilters.length > 0) {
+ return `Explore ${filteredAndSortedRides.length} ${activeFilters.join(' ')} rides and attractions`;
+ }
+
+ return `Explore ${filteredAndSortedRides.length} rides and roller coasters worldwide`;
+ };
+
+ useOpenGraph({
+ title: 'Rides & Attractions - ThrillWiki',
+ description: generateDescription(),
+ imageUrl: filteredAndSortedRides[0]?.banner_image_url,
+ imageId: filteredAndSortedRides[0]?.banner_image_id,
+ type: 'website',
+ enabled: !loading
+ });
const categories = [
{ value: 'all', label: 'All Categories' },
diff --git a/src/pages/Search.tsx b/src/pages/Search.tsx
index 45deca27..de7e87e9 100644
--- a/src/pages/Search.tsx
+++ b/src/pages/Search.tsx
@@ -9,6 +9,7 @@ import { SearchFiltersComponent, SearchFilters } from '@/components/search/Searc
import { SearchSortOptions, SortOption } from '@/components/search/SearchSortOptions';
import { EnhancedSearchResults } from '@/components/search/EnhancedSearchResults';
import { useSearch, SearchResult } from '@/hooks/useSearch';
+import { useOpenGraph } from '@/hooks/useOpenGraph';
export default function SearchPage() {
const [searchParams] = useSearchParams();
@@ -121,6 +122,15 @@ export default function SearchPage() {
company: results.filter(r => r.type === 'company').length
};
+ useOpenGraph({
+ title: query ? `Search: "${query}" - ThrillWiki` : 'Search - ThrillWiki',
+ description: query
+ ? `Found ${filteredAndSortedResults.length} results for "${query}"`
+ : 'Search theme parks, rides, and more on ThrillWiki',
+ type: 'website',
+ enabled: !loading
+ });
+
return (