TheVanillaCoke
TheVanillaCoke

Reputation: 23

Dynamic meta tags in server side rendered React app

I have a React application with server side rendering. I now have to implement Facebook/Google+ share dialog with og:title and og:image being set dynamically to values returned from the API.

I'm using react-helmet to set my default meta tags, however I have troubles making it work dynamically.

I tried using redux-async-connect to prefetch the result, which resulted in meta tags being rendered (I can see them when I look at the source code), however both Facebook and Google+ ignore them.

Do any of you have experience with making this work?

Upvotes: 0

Views: 3647

Answers (2)

justswim
justswim

Reputation: 963

Essentially, in your public/index.html file you want to replace the metadata with an identifiable string:

<!-- in public/index.html -->
<title>$OG_TITLE</title>
<meta name="description"        content="$OG_DESCRIPTION" />
<meta property="og:title"       content="$OG_TITLE" />
<meta property="og:description" content="$OG_DESCRIPTION" />
<meta property="og:image"       content="$OG_IMAGE" />

And then on the server, you want to replace these strings with the dynamically generated information. Here is an example route with Node and Express:

app.get('/about', function(request, response) {
  console.log('About page visited!');
  const filePath = path.resolve(__dirname, './build', 'index.html')
  fs.readFile(filePath, 'utf8', function (err,data) {
    if (err) {
      return console.log(err);
    }
    data = data.replace(/\$OG_TITLE/g, 'About Page');
    data = data.replace(/\$OG_DESCRIPTION/g, "About page description");
    result = data.replace(/\$OG_IMAGE/g, 'https://i.imgur.com/V7irMl8.png');
    response.send(result);
  });
});

Taken from this tutorial here: https://www.kapwing.com/blog/how-to-add-dynamic-meta-tags-server-side-with-create-react-app/

Upvotes: 3

Coldblue
Coldblue

Reputation: 142

You can render the app inside document like this: render(<App/>, document) while App containing all the html you need.

Upvotes: 1

Related Questions