Files
SweetHome/app/property/[id]/page.js
Claw AI d56b4d2a11
All checks were successful
Build frontend / build (push) Successful in 41s
Fix Facebook share: server-side OG metadata via generateMetadata
- Split page.js into server component + PropertyDetail client component
- Server component exports generateMetadata that fetches property data
- OG tags now rendered in initial HTML (visible to Facebook/Twitter crawlers)
- Removes client-side useEffect OG tag injection (crawlers don't execute JS)
2026-03-30 13:44:52 +00:00

91 lines
3.0 KiB
JavaScript

import PropertyDetail from './PropertyDetail';
// Server-side API fetch for metadata (runs at request time on server)
async function fetchPropertyForMeta(id) {
try {
const res = await fetch(`http://45.93.137.91/api/RentProperties/GetRentProperties`, {
next: { revalidate: 60 },
});
if (!res.ok) return null;
const text = await res.text();
const json = JSON.parse(text);
const items = Array.isArray(json?.data) ? json.data : Array.isArray(json) ? json : [];
return items.find(p => p.id == id) || items[0] || null;
} catch {
return null;
}
}
function mapProperty(item) {
const info = item.propertyInformation || item.PropertyInformation || {};
let details = {};
try { details = JSON.parse(info.detailsJSON || info.DetailsJSON || '{}'); } catch {}
const price = item.monthlyRent || item.MonthlyRent || item.dailyRent || item.DailyRent || 0;
const priceUnit = item.monthlyRent || item.MonthlyRent ? 'monthly' : 'daily';
const buildingType = info.buildingType ?? info.BuildingType ?? 0;
const type = { 0: 'apartment', 1: 'villa', 2: 'house' }[buildingType] || 'apartment';
const typeLabel = { 0: 'شقة', 1: 'فيلا', 2: 'بيت' }[buildingType] || 'عقار';
const address = info.address || info.Address || '';
const bedrooms = info.numberOfBedRooms || info.NumberOfBedRooms || 0;
const bathrooms = info.numberOfBathRooms || info.NumberOfBathRooms || 0;
const area = info.space || info.Space || 0;
const desc = info.description || info.Description || '';
const images = info.images || info.Images || [];
const firstImage = Array.isArray(images) && images[0] ? images[0] : '';
return {
title: `${typeLabel} في ${address}`,
description: desc || `${typeLabel} في ${address} · ${bedrooms} غرف نوم · ${bathrooms} حمامات · ${area} م²`,
price,
priceUnit,
typeLabel,
address,
bedrooms,
bathrooms,
area,
image: firstImage,
};
}
export async function generateMetadata({ params }) {
const { id } = await params;
const raw = await fetchPropertyForMeta(id);
if (!raw) {
return {
title: 'SweetHome - عقار',
description: 'اكتشف أفضل العقارات للإيجار',
};
}
const p = mapProperty(raw);
const priceStr = `${p.price.toLocaleString()} ل.س / ${p.priceUnit === 'daily' ? 'يوم' : 'شهر'}`;
const imageUrl = p.image
? (p.image.startsWith('http') ? p.image : `http://45.93.137.91${p.image}`)
: '';
return {
title: `${p.title} - ${priceStr}`,
description: p.description,
openGraph: {
title: `${p.title} - ${priceStr}`,
description: p.description,
images: imageUrl ? [imageUrl] : [],
url: `https://sweethome.example/property/${id}`,
type: 'website',
siteName: 'SweetHome',
},
twitter: {
card: 'summary_large_image',
title: `${p.title} - ${priceStr}`,
description: p.description,
images: imageUrl ? [imageUrl] : [],
},
};
}
export default function PropertyPage({ params }) {
return <PropertyDetail params={params} />;
}