I’m having an issue with dynamic og meta tags in my React/Next application with LinkedIn post inspector and Facebook debugger. The issue is that the metatags are being generated, but after the load and the crawlers don’t find them.
This is the Chrome Elements TAB with og

This is the Network TAB -> Response without og

This is my current code src/pages/share-property/index.tsx
import React from "react";
import Property from "components/Sharing/Property";
import { GetServerSideProps } from "next";
import { Buffer } from 'buffer';
import { NextPage } from 'next';
import Head from 'next/head'; // Import Head
interface PropertyData {
companyName: string;
tenantId: string;
stage: string;
firstName: string;
imageUrl: string;
headerText?: string;
resolvedImageUrl: string;
fullUrl: string;
}
interface Props {
propertyData: PropertyData | null;
}
const IndexPage: NextPage<Props> = ({ propertyData }) => {
const shareTitle = propertyData ? `${propertyData.companyName} - ${propertyData.headerText}` : 'Loading...';
const shareDescription = propertyData ? `Check out this property update from ${propertyData.companyName}` : '';
return (
<>
<Head>
{/* Primary Meta Tags */}
<title>{shareTitle}</title>
<meta name="description" content={shareDescription} />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>
{propertyData && (
<>
{/* Open Graph / Facebook */}
<meta property="og:title" content={shareTitle} />
<meta property="og:description" content={shareDescription} />
<meta property="og:image" content={propertyData.resolvedImageUrl} />
<meta property="og:url" content={propertyData.fullUrl} />
<meta property="og:type" content="website" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content={`Property image from ${propertyData.companyName}`} />
<meta property="og:site_name" content={propertyData.companyName} />
{/* Twitter */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={shareTitle} />
<meta name="twitter:description" content={shareDescription} />
<meta name="twitter:image" content={propertyData.resolvedImageUrl} />
</>
)}
</Head>
{propertyData ? (
<Property
companyName={propertyData.companyName}
tenantId={propertyData.tenantId}
stage={propertyData.stage}
firstName={propertyData.firstName}
imageUrl={propertyData.imageUrl}
headerText={propertyData.headerText}
resolvedImageUrl={propertyData.resolvedImageUrl}
fullUrl={propertyData.fullUrl}
/>
) : (
<div>Loading property data...</div>
)}
</>
);
};
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const { query, req } = context;
const data = query.data as string;
console.log("getServerSideProps is running");
if (!data) {
console.log("No data query parameter");
return {
props: { propertyData: null },
};
}
try {
const decodedData = JSON.parse(Buffer.from(data, 'base64').toString('utf-8'));
const { companyName, stage, imageUrl, firstName = "", tenantId = "", headerText = "Property Update" } = decodedData;
const origin = req ? `${req.headers['x-forwarded-proto'] || 'http'}://${req.headers.host}` : '';
const fullUrl = `${origin}${context.resolvedUrl}`;
const getAbsoluteImageUrlServerSide = (url: string) => {
if (!url) return '';
if (url.startsWith('http')) return url;
if (url.startsWith('//')) return `https:${url}`;
return `${origin}${url.startsWith('/') ? '' : '/'}${url}`;
};
const resolvedImageUrl = getAbsoluteImageUrlServerSide(imageUrl);
console.log("Property Data:", {
companyName,
tenantId,
stage,
firstName,
imageUrl,
headerText,
resolvedImageUrl,
fullUrl,
});
return {
props: {
propertyData: {
companyName,
tenantId,
stage,
firstName,
imageUrl,
headerText,
resolvedImageUrl,
fullUrl,
},
},
};
} catch (error) {
console.error('Error processing data in getServerSideProps:', error);
return {
props: { propertyData: null },
};
}
};
export default IndexPage;
src/components/Sharing/Property.tsx
import React from 'react';
import { Box, Typography, Button, Card, CardMedia, CardContent } from '@mui/material';
import Link from 'next/link';
import Head from 'next/head';
import styles from 'styles/ShareButton.module.scss';
interface PropertyProps {
companyName: string;
tenantId: string;
stage: string;
firstName: string;
imageUrl: string;
headerText?: string;
resolvedImageUrl: string;
fullUrl: string;
}
const Property = ({
companyName,
tenantId,
stage,
firstName,
imageUrl,
headerText = "Property Update",
resolvedImageUrl,
fullUrl,
}: PropertyProps) => {
const getStageMessage = () => {
switch(stage.toLowerCase()) {
case 'under contract':
return (
<Typography variant="body1" sx={{ mb: 2 }}>
This home was just placed under contract using{' '}
<Link href={new URL('/', fullUrl).origin} passHref>
<a target="_blank" className={styles.Link}>{companyName}</a>
</Link>
</Typography>
);
case 'under construction':
return (
<Typography variant="body1" sx={{ mb: 2 }}>
This house is beginning its renovations using{' '}
<Link href={new URL('/', fullUrl).origin} passHref>
<a target="_blank" className={styles.Link}>{companyName}</a>
</Link>
</Typography>
);
case 'sold':
return (
<Typography variant="body1" sx={{ mb: 2 }}>
This home has just been sold using{' '}
<Link href={new URL('/', fullUrl).origin} passHref>
<a target="_blank" className={styles.Link}>{companyName}</a>
</Link>
</Typography>
);
default:
return null;
}
};
return (
<>
{/* Rest of your Property component UI */}
<Box className={styles.PropertyContainer}>
<Card sx={{ mb: 3 }}>
{resolvedImageUrl && (
<CardMedia
component="img"
height="400"
image={resolvedImageUrl}
alt="Property image"
sx={{ objectFit: 'cover' }}
/>
)}
<CardContent>
{getStageMessage()}
<Box className={styles.CTASection}>
<Typography variant="body1" paragraph>
If you want to invest in real estate, click here to learn more
</Typography>
<Button
variant="contained"
size="large"
href={new URL('/', fullUrl).origin}
target="_blank"
sx={{ mt: 2 }}
>
Learn More
</Button>
</Box>
</CardContent>
</Card>
</Box>
</>
);
};
export default Property;
I have read many posts about this, but none resolve my issue. Any observation about what I’m doing wrong. Thanks.
