I'm using MERN stack and building production for the website server but the meta is captured from my index.js only. I'm using REACT-HELMET for each and every page but the metadata,it does not capture. I have read a lot of articles that say SSR and CSR

I'm not sure MERN belongs to which one. cause I am using express for API is SSR or CSR? I'm a bit confused.

and how could I make my share link from a subpage e.g:www.test.com/product/x123123*id (mapping data from API server) e.g. product Catfood, title and image can be showing displayed on Social like Facebook metadata: og:image and the title will change accordingly.

i have tested react-snap but it does not work.

import React, { useEffect, useState } from 'react';
import {
    addViewAction,
    getlistingAction,
    likeListingAction,
    unLikeListingAction,
} from '../../redux/slices/listingSlices';
import { getUserProfileAction } from '../../redux/slices/userSlices';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import ErrorMsg from '../../components/ErrorMsg/ErrorMsg';
import LoadingComponent from '../../components/LoadingComponent/loadingComponent';
import ReactImageGallery from 'react-image-gallery';
import 'react-image-gallery/styles/css/image-gallery.css';
import BackButton from '../../components/Backbutton';
import {
    FaBed,
    FaRulerCombined,
    FaBath,
    FaRegHeart,
    FaHeart,
    FaFacebook,
    FaWhatsapp,
    FaEnvelope,
    FaViber,
    FaTwitter,
    FaLine,
    FaTelegram,
    FaShareAlt,
    FaPhone,
    FaMap,
    FaMailBulk,
    FaEye,
} from 'react-icons/fa';
import { LuLampFloor } from 'react-icons/lu';
import SuccesMsg from '../../components/SuccessMsg/SuccessMsg';
import MortgageCalculator from '../../components/MorgageCalculator';
import {
    FacebookShareButton,
    EmailShareButton,
    ViberShareButton,
    TwitterShareButton,
    LineShareButton,
    TelegramShareButton,
    WhatsappShareButton,
} from 'react-share';
import ReactPlayer from 'react-player';
import { Helmet } from 'react-helmet';

const ListingDetails = ({ color }) => {
    const [myProfile, setMyProfile] = useState(null);
    const [myListing, setMyListing] = useState(null);
    const [isLiked, setIsLiked] = useState(false);
    const [coordinates, setCoordinates] = useState([]);
    const [showShareTooltip, setShowShareTooltip] = useState(false);

    const dispatch = useDispatch();
    const params = useParams();
    const listingId = params.id;

    // eslint-disable-next-line
    const { listing, error, loading, success } = useSelector(
        (state) => state?.listing
    );

    useEffect(() => {
        const fetchData = async () => {
            try {
                await dispatch(addViewAction(listingId));
                const listingResponse = await dispatch(getlistingAction(listingId));
                const listing = listingResponse.payload.listing;
                setMyListing(listing);
                await setCoordinates([listing.coordinateX, listing.coordinateY]);

                // Fetch user profile after fetching the listing
                const profileResponse = await dispatch(getUserProfileAction());
                setMyProfile(profileResponse.payload.myProfile);

                // Fetch liked status after fetching user profile
                const likedUsers = listing?.likes;
                const hasLike = likedUsers?.some((userIds) =>
                    userIds.includes(myProfile?._id)
                );
                setIsLiked(hasLike);
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };

        if (!myListing) {
            fetchData();
        }
    }, [dispatch, listingId, myListing, myProfile]);

    const refreshListing = async () => {
        try {
            const response = await dispatch(getlistingAction(listingId));
            setMyListing(response.payload.listing);
        } catch (error) {
            console.error('Error refreshing listing:', error);
        }
    };

    const likeListingHandler = async () => {
        try {
            await dispatch(likeListingAction(listingId));
            refreshListing();
        } catch (error) {
            console.error('Error liking listing:', error);
        }
    };

    const unListingHandler = async () => {
        try {
            await dispatch(unLikeListingAction(listingId));
            refreshListing();
        } catch (error) {
            console.error('Error unliking listing:', error);
        }
    };

    if (loading || !myListing) {
        return <LoadingComponent />;
    }

    if (error) {
        return <ErrorMsg message={error} />;
    }

    const homevalue = myListing ? myListing.price : 0; // Replace 0 with a default value if needed
    const downpayment = (homevalue * 10) / 100; //

    const images = myListing.images.map((image, index) => ({
        original: image,
        description: `Photo ${index + 1}`,
    }));

    // Assuming myListing.description contains the property description text
    const description = myListing.description;

    // Replace newline characters with <br> tags
    const formattedDescription = description.replace(/\n/g, '<br>');

    const openGoogleMapInNewWindow = (coordinates) => {
        // Define the URL for the new window with coordinates as a query parameter
        const url = `/google-map?lat=${coordinates[0]}&lng=${coordinates[1]}`;
        const newWindow = window.open(url, '_blank', 'width=800,height=600');

        // Handle any pop-up blocker issues
        if (!newWindow) {
            alert('Please allow pop-ups to open the map.');
        }
    };

    //============================================================================================================================
    //====================================================BELOW is RETURN ========================================================
    //============================================================================================================================

    return (
        <div className="dark:bg-gray-900">
            <Helmet>
                <title>{myListing.title}</title>
                <meta property="og:title" content={myListing.title} />
                <meta property="og:image" content={myListing.images[0]} />
                <meta property="og:type" content="website" />
            </Helmet>
            <div className="container mx-auto bg-gray-100 dark:bg-gray-900 h-full ">
                <div className="flex justify-start py-4 pl-5">
                    <BackButton />
                </div>
                <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 bg-gray-100 dark:bg-gray-900 p- h-full pt-5">
                    <div className="">
                        <div className="flex">
                            <ReactImageGallery items={images} />
                        </div>
                        {myListing.videoURL ? (
                            <div className="flex justify-center align-middle p-2 lg:py-16">
                                <ReactPlayer url={myListing.videoURL} />
                            </div>
                        ) : null}
                    </div>

                    <div className="container p-2 mx-auto">
                        <div className="w-auto rounded-xl overflow-hidden shadow-lg dark:bg-gray-800 p-5 text-gray-600">
                            <div className="p-3">
                                <div className="font-bold text-xl mb-2 dark:text-gray-300">
                                    For {myListing.propertyType}
                                </div>
                                <div className="font-bold text-xl mb-2 dark:text-gray-300">
                                    {myListing.title}
                                </div>
                                <div className="mb-2 dark:text-gray-500">
                                    {myListing.address}
                                </div>
                                <div className="grid grid-cols-3 gap-4 text-center">
                                    {myProfile ? (
                                        !isLiked ? (
                                            <button
                                                onClick={likeListingHandler}
                                                className="flex items-center gap-1 m-2 text-2xl text-gray-400"
                                            >
                                                <FaRegHeart />
                                            </button>
                                        ) : (
                                            <button
                                                onClick={unListingHandler}
                                                className="flex items-center gap-1 m-2 text-2xl text-gray-400"
                                            >
                                                <FaHeart className="text-red-700" />
                                            </button>
                                        )
                                    ) : null}{' '}
                                    <div className="p-2">
                                        <button
                                            onClick={() => openGoogleMapInNewWindow(coordinates)}
                                            className="text-2xl text-gray-400 focus:outline-none"
                                        >
                                            <FaMap />
                                        </button>
                                    </div>
                                    <div className="p-2">
                                        <button
                                            type="button"
                                            className="text-2xl text-gray-400 focus:outline-none"
                                            onClick={() => setShowShareTooltip(!showShareTooltip)}
                                        >
                                            <FaShareAlt />
                                        </button>

                                        {showShareTooltip && (
                                            <div className="absolute z-10 mt-2 -ml-2 transform -translate-x-1/2 w-36 p-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5">
                                                <div className="py-1 text-start">
                                                    <FacebookShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaFacebook className="text-xl mr-2" />
                                                            Facebook
                                                        </div>
                                                    </FacebookShareButton>
                                                    <WhatsappShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaWhatsapp className="text-xl mr-2" />
                                                            WhatsApp
                                                        </div>
                                                    </WhatsappShareButton>
                                                    <EmailShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaEnvelope className="text-xl mr-2" />
                                                            Email
                                                        </div>
                                                    </EmailShareButton>
                                                    <ViberShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaViber className="text-xl mr-2" />
                                                            Viber
                                                        </div>
                                                    </ViberShareButton>
                                                    <TwitterShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaTwitter className="text-xl mr-2" />
                                                            Twitter
                                                        </div>
                                                    </TwitterShareButton>
                                                    <LineShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaLine className="text-xl mr-2" />
                                                            Line
                                                        </div>
                                                    </LineShareButton>
                                                    <TelegramShareButton url={window.location.href}>
                                                        <div className="flex items-center">
                                                            <FaTelegram className="text-xl mr-2" />
                                                            Telegram
                                                        </div>
                                                    </TelegramShareButton>
                                                    {/* Add more social media share buttons here */}
                                                </div>
                                            </div>
                                        )}
                                    </div>
                                </div>

                                <div className="grid grid-cols-2 gap-1 px-1 py-3 text-gray-500 dark:text-gray-300">
                                    <div className="flex items-center text-xl">
                                        <FaBed className="mr-2" /> {myListing.beds} Room
                                    </div>
                                    <div className="flex items-center text-xl">
                                        <FaRulerCombined className="mr-2" /> {myListing.sqfeet} Sqft
                                    </div>
                                    <div className="flex items-center text-xl">
                                        <FaBath className="mr-2" /> {myListing.bathroom} Bath
                                    </div>
                                    <div className="flex items-center text-xl">
                                        <LuLampFloor className="mr-2" /> {myListing.furnishing}
                                    </div>
                                </div>
                            </div>
                            <hr />
                            <div className="p-2">
                                {!myListing.propertyType === 'buy' ? (
                                    <div className="font-bold text-xl mb-2 dark:text-gray-300">
                                        Price: {myListing.price} / month
                                    </div>
                                ) : (
                                    <div className="font-bold text-xl mb-2 dark:text-gray-300">
                                        RM {myListing.price.toLocaleString()}
                                        {myListing.propertyType !== 'Rent' ? null : '/ Month'}
                                    </div>
                                )}
                            </div>
                            <div className="p-2">
                                <div className="mb-2 dark:text-gray-300">
                                    RM {myListing.psf} Per Sqft
                                </div>
                                <div className="mb-2 dark:text-gray-300">
                                    {myListing.psf > 43560
                                        ? `${myListing.psf / 43560} Acres`
                                        : `${myListing.psf} Sqft`}
                                </div>
                            </div>

                            <div className="dark:text-gray-300 p-5 col-span-2">
                                <hr />
                                <label className="font-bold">Unit Features</label>
                                <hr />
                                <div className="overflow-auto max-h-40">
                                    {' '}
                                    {/* Add a max-height and overflow property */}
                                    {myListing.unitFeatures}
                                </div>
                            </div>

                            <div className="dark:text-gray-300 p-5 col-span-2">
                                <hr />
                                <label className="font-bold">Facilities</label>
                                <hr />
                                <div className="overflow-auto max-h-40">
                                    {' '}
                                    {/* Add a max-height and overflow property */}
                                    {myListing.facilities}
                                </div>
                            </div>
                            <div className="font-bold text-xl mb-2 dark:text-gray-300 p-3">
                                About This Property <br />
                                <br />
                                <p
                                    className="text-sm font-lite"
                                    dangerouslySetInnerHTML={{ __html: formattedDescription }}
                                ></p>
                            </div>

                            <div className="grid grid-cols-2 gap-4">
                                <div className="text-lg font-bold flex items-center">
                                    <FaEye className="mr-3" />
                                    {myListing.numViews}
                                </div>
                            </div>
                            <div className="pt-4 pb-2 grid grid-cols-3 gap-2 text-center">
                                <a
                                    href={`https://wa.me/${encodeURIComponent(
                                        myListing.user.whatsapp
                                    )}/?text=I%20am%20interested%20in%20${encodeURIComponent(
                                        myListing.title
                                    )}.%20Please%20provide%20me%20more%20information.`}
                                    className="flex flex-col items-center text-gray-800 dark:text-gray-100 bg-gray-200 dark:bg-gray-900 p-3 py-2 rounded-xl text-center"
                                    target="_blank"
                                    rel="noopener noreferrer"
                                >
                                    <FaWhatsapp className="text-2xl mb-1" />
                                    <p className="text-sm">Whatsapp</p>
                                </a>

                                <button
                                    onClick={() =>
                                        (window.location = `mailto:${myListing.user.email}`)
                                    }
                                    className="flex flex-col items-center text-gray-800 dark:text-gray-100 bg-gray-200 dark:bg-gray-900 p-3 py-2 rounded-xl"
                                >
                                    <FaMailBulk className="text-2xl mb-1" />
                                    <p className="text-sm">Email</p>
                                </button>

                                <a
                                    href={`tel:+${myListing.user.contactNumber}`}
                                    className="flex flex-col items-center text-gray-800 dark:text-gray-100 bg-gray-200 dark:bg-gray-900 p-3 py-2 rounded-xl"
                                >
                                    <FaPhone className="text-2xl mb-1" />
                                    <p className="text-sm">Call</p>
                                </a>
                            </div>
                        </div>
                        {success && <SuccesMsg message="Successfully Load" />}
                    </div>
                </div>

                <div className="p-5 lg:p-10">
                    {myListing.propertyType === 'Sale' ? (
                        <MortgageCalculator
                            homevalue={homevalue}
                            downpayment={downpayment}
                        />
                    ) : null}
                </div>
            </div>
        </div>
    );
};

export default ListingDetails;
0

There are 0 answers