19

We have built a project (Web Application) in React .net core using react in client-side rendering.

We've used react-helmet for dynamically assigning meta tags.

The issue being when the app renders in the browser. The browser gets only the static HTML on initial load which does not include the dynamic meta tags we have set. However on inspecting you get those meta tags under "Elements".

Also, if we use these URL for sharing on any social media, like WhatsApp or Facebook, the URL does not render any metadata as it should.

Tried searching for solutions to our problem, the most obvious answer we came across was to try server-side rendering instead. We get that, but it is not a solution to try out at this juncture when we're ready with app to roll it out.

Others we came across were "react-snap", "react-snapshot", but no luck with react-snap, it requires to upgrade React's version to 16+, which we did but I guess not all dependencies were upgraded, there was an error saying "

hydrate is not a function

(hydrate concerns the react-dom)

With react-snapshot, we could not find the necessary type definition, which is required in react .net core to function properly

Please guide for the next probable step (except the paid ones like prerender, etc)?

Main goal: Social Applications should render the meta data when we paste/share the URL within them.

rahul singh Chauhan
  • 323
  • 1
  • 4
  • 15
Prasaad Patil
  • 447
  • 3
  • 6
  • 20
  • Same issue.. what did you do for this – Burak Kalafat May 27 '20 at 23:06
  • You said you updated react, but did you update the react-dom dependency? I used react-snap on my SPA, and it worked great for me. I wrote a blog post about here: https://romiem.com/blog/opengraph-single-page-app/ – romiem Aug 13 '20 at 20:36

3 Answers3

6

Prerender is the only solution. I used a node dependency called "prerender" -> https://github.com/prerender/prerender

It works enabling a web server wich make http requests. Assigning value to a boolean: window.prerenderReady = true; in your website tells your server when the page is ready to "take the photo" and it returns the Html when so. You need to program an easy script that parses all the site urls and save those html contents to files. Upload them to your server and using .htaccess or similar target the crawlers external-hit-facebook,twitterbot,googlebot, etc.. to show them the prerendered version and 'the real site' to the rest of user-agents.

It worked for me.

Becario Senior
  • 704
  • 10
  • 18
  • This is great..!! Only issue i have to use 'api.prerender.com/render?token=token&url=https://MySPA.com' to render the meta tags. Also the css and logos of my spa are not rendered. What if i just want to use MySPA.com to render these meta tags? – Prasaad Patil Jun 27 '18 at 06:49
  • Notice the variable you have to set in your initial html: window.prerenderReady = false; Then in your JS code, when you are completly sure the JS manipulations are done, set the window.prerenderReady = true. Also you should notice that you can download this service and use it locally with NodeJS instead of using their public test url. – Becario Senior Jun 27 '18 at 07:26
  • I installed prerender using npm command but whenever i use window.prerenderReady = false it gives me a compilation error saying Property prerender does not exist on type window :( Is it because i am using typescript?? – Prasaad Patil Jun 27 '18 at 07:52
  • Ok.... This window.prerenderReady = false needs to go wrapped in in the initial html. Then you set it to true throught your JS code. Read the prerender documentation. – Becario Senior Jun 27 '18 at 08:22
  • does not work for typescript. Need prerender,io for middleware but no type definitions are available for it. Also our app is not an express app so app.use(require('prerender-node')) wont work. – Prasaad Patil Jun 27 '18 at 11:34
3

The meta tags for Open Graph need to be present in the HTML which is sent back to the client when fetching a URL. Browsers or bots will not wait until the app is rendered on the client side to determine what the metatags are - they will only look at the initially loaded HTML.

If you need the content of your Open Graph metadata to be dynamic (showing different content depending on the URL, device, browser etc.) you need to add something like react-meta-tags into your server code.

There are no type definitions available for any of the react meta tags libraries, but you can add your own. It can be a bit tricky, but check out the official documentation and the templates they have provided to get started.

If you don't need it to be dynamic, you could add the tags into the static parts of the <head>-tag in your index.html.

maxpaj
  • 6,029
  • 5
  • 35
  • 56
  • Type definitions are not available for react-meta-tags. we are using visual studio 2017 react template which uses typescript. Also we need the metadata to be dynamic without any server side rendering – Prasaad Patil Jun 26 '18 at 13:04
  • You can't have the metadata be dynamic without server side rendering. Seems like type definitions are missing for all of those react metadata rendering libraries. Maybe you can add your own to any of them? – maxpaj Jun 26 '18 at 13:13
  • Basically what we are doing, is making an api call for a component and assigning it to the state. The state values are then assigned to the content part of the metadata – Prasaad Patil Jun 26 '18 at 13:24
  • I'm assuming the API call is made on the client side. You need to have the meta tags present in the HTML on the first contact between client and server - before the app is rendered on the client side in order for the social applications (Facebook, LinkedIn etc.) to read those tags. – maxpaj Jun 26 '18 at 13:28
  • Yes, the call is made on the client side, and the meta tags are present in the render function of the component. – Prasaad Patil Jun 26 '18 at 13:33
  • I believe the quickest solution for you is to take `react-meta-tags` library and add your own type definitions to that. – maxpaj Jun 26 '18 at 13:36
  • Okay. As we are very new to reactjs and typescript Can you give me a good reference on how to add our own type definitions? Also, the parent component is actually making an api call and then its state is passed to the child component as props. In the render function of this child component, we have assigned this props to the content part of the metadata. I can edit the question with the code if you want. – Prasaad Patil Jun 26 '18 at 13:40
  • 1
    You can check out the [official documentation](https://www.typescriptlang.org/docs/handbook/declaration-files/) on declaration files and [the templates they have provided](https://www.typescriptlang.org/docs/handbook/declaration-files/templates.html) to get started. – maxpaj Jun 26 '18 at 13:50
2

I had the same issue today. I had two React Web applications that need this. Here is how I solved it:

  1. put your preview image in the public folder
  2. still in public folder, Open index.html, add the line <meta property="og:image" content="preview.png"/> or <meta property="og:image" content="%PUBLIC_URL%/preview.png"/>.

Go to https://www.linkedin.com/post-inspector/ to check if it works.

I hope this would help!

yukiyao
  • 61
  • 4