Can't get dynamic <meta> tags working for React routes

What I’m trying to do

I’m trying to get the sharing cards on social media to display the correct titles and images for specific pages on my website, and I’m finding it really difficult to get it working.

It’s a React app using react-router for custom pages and react-helmet for custom meta tags. It’s hosted on Galaxy, but it’s not using server-side rendering right now (as far as I understand).

No matter what I’ve tried so far, I cannot get Facebook or Twitter’s tools to read the correct Open Graph tags from my React routes.

The link previews Facebook and Twitter generate always use the meta tags set in main.html, instead of the ones set using react-helmet, so every link I share on social media generates a card for website.com’s information, when I want it to pull website.com/particular-page’s information).

The correct meta tags show up when I Inspect Element on website.com/particular-page, but the generic website.com meta tags also show up in the <head> tag before them. (Does Open Graph read the first or last meta tags it sees?)

It seems like I should just remove the meta tags from the main.html file and define them inside the React components for each route, but when I try that, the Facebook and Twitter tools just don’t pull anything for the link preview.

What I have / haven’t done so far

  1. I used react-helmet to set custom meta tags for each route

I have set custom meta tags for each route, and they show up fine when I use Inspect Element. Even Google’s bot seems to understand them fine for SEO, but as far as I can tell, Facebook and Twitter’s tools for generating link previews do not execute JavaScript, and are just using the default homepage meta tags set in the project’s main.html file.

  1. Added Prerender.io

I’ve followed the instructions to add Prerender.io to the site, but it doesn’t seem to make any difference on how the meta tags are read. And I think I saw somewhere that it only updates the cache once every 4 days, with no options to manually trigger it more frequently, so maybe it takes awhile to take effect for newly published routes?

  1. I haven’t added server-side rendering yet

From the research I’ve done so far, I can’t see a way to add SSR without doing a big re-write or hardcoding duplicate code for each route. But maybe I’m misunderstanding it, or maybe this is the only way to achieve the functionality I want?


I’m feeling stuck and frustrated, and would love some help or suggestions on the best way to get this working. It seems bizarre to me that Facebook’s tool can’t just treat React routes like regular webpages (being the company behind React and all) and execute the JavaScript to pull the right meta tags for specific pages, even without server-side rendering.

Any help would be hugely appreciated!

you need proper SSR as most crawlers do not execute javascript. Prerender.io would work as well, but the cache delay makes it hard to debug.

implementing SSR is not that hard if you already use react-router. You just have to refactor your entry point a bit, so that your app is wraped by BrowserRouter on client and StaticRouter on server. See https://alligator.io/react/react-router-ssr/ and https://docs.meteor.com/packages/server-render.html

There is neither a need to do big re-writes, nor duplicating code (never duplicate code).

some of your components might throw an error on the server, because they use browser api, but that can be fixed. You only need to make sure that at least your Helmet-components render on the server.

I would try to step-by-step migrate (comment out most routes, but one or so) and check whether the server returns a proper render result and if the browser console gives you warnings or errors. Good luck!

1 Like

Thank you for the reply and the resources! I will have to do some reading and try this.