Search code examples
reactjsmetadatareact-helmet

How to set dynamic og meta tags?


I've been trying to use react-helmet-async in order to create custom URL thumbnails for blog posts for posting on social media.

I've set the provider in the index.js

import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-tooltip/dist/react-tooltip.css';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { HelmetProvider } from 'react-helmet-async';
import store from './redux/store';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <Provider store={store}>
    <HelmetProvider>
      <App />
    </HelmetProvider>
  </Provider>
);

I've created an Seo component that takes in the data:

import React from 'react';
import { Helmet } from 'react-helmet-async';

export default function SEO({ title, description, imageUrl }) {
  return (
    <Helmet>
      <title>{title}</title>
      <meta property='og:type' content='artical' />
      <meta property='og:title' content={title} />
      <meta property='og:description' content={description} />
      <meta property='og:image' content={imageUrl} />
    </Helmet>
  );
}

rendering the component here

import React from "react";
import { useDispatch } from "react-redux";
import { Container } from "react-bootstrap";
import { setVisitedRoot } from "../../redux/visitedSlice";
import { useParams } from "react-router-dom";
import useScrollAndDispatch from '../Tools/useScrollAndDispatch';
import posts from "./posts"; 
import  Seo  from '../Tools/Seo.jsx'
import { toKebabCase } from "../Tools/toKebabCase";


const BlogPost = () => {
  const dispatch = useDispatch();
  useScrollAndDispatch(dispatch, setVisitedRoot(true));

  const { id } = useParams();
  const kebabCaseId = toKebabCase(id);
  let post = posts.find((post) => toKebabCase(post.id) === kebabCaseId);

  if (!post) {
    return <div>Post not found!</div>;
  }

  const renderHTMLContent = () => {
    return { __html: post.content };
  };

  return (
    <Container style={{ maxWidth: "500px" }}>
      <Seo
      title={post.title}
      description={post.description}
      name={post.name}
      type={post.type}
      imageUrl={post.imageUrl}
    
      />
      <img src={post.image} alt={post.title} style={{ width: "70px", height: "70px" }} />
      <h1 style={{ paddingTop: "20px", paddingBottom: "20px"}}>{post.title}</h1>
      <div
        dangerouslySetInnerHTML={renderHTMLContent()}
      />
    </Container>
  );
};

export default BlogPost;

Title actually seems to work fine, and I'm finding all the correct info in the elements section of chrome dev tools, along with the the metadata I've written in the index.html file. However, when checking my links on Facebook's sharing debugger, it shows me the metadata from my index.html file. I've tried removing the meta tags from the index.html, but then it shows no info at all on the debugger. Any advice?


Solution

  • One thing to note is that dynamic updates might not be reflected when sharing the link on Facebook's Sharing Debugger immediately, as Facebook may cache information.

    import React, { useEffect } from 'react';
    import { Helmet } from 'react-helmet-async';
    
    const SEO = ({ title, description, imageUrl }) => {
      useEffect(() => {
        // Use Helmet here if you need to dynamically update meta tags after the initial load
      }, [title, description, imageUrl]);
    
      return (
        <Helmet>
          <title>{title}</title>
          <meta property='og:type' content='article' />
          <meta property='og:title' content={title} />
          <meta property='og:description' content={description} />
          <meta property='og:image' content={imageUrl} />
        </Helmet>
      );
    };
    
    export default SEO;
    
    

    Important Notes

    1. Make sure your React app is rendering on the server side. React Helmet, by default, works on the client side, and social media crawlers might not execute JavaScript. To handle this, you can use server-side rendering (SSR) with a framework like Next.js or Gatsby.
    2. Facebook caches information about shared links. If you've changed the meta tags, try fetching the URL in the Facebook Sharing Debugger again. You might need to use the "Scrape Again" button to force Facebook to update its cache.