Timmy Lee
Timmy Lee

Reputation: 795

React Helmet: Facebook Open Graph

So I've got react helmet working on my client-side app to re-render facebook og tags into the head depending on which page is active in the app.

however the facebook debugger and facebook itself don't pick any of this up. am i missing something ? is this only possible with server-side rendered pages?

i hope not as i'll have to learn node.js!

 <Helmet>
    <title>{props.title}</title>
    <meta property="og:url" content={ogUrl} />
    <meta property="og:type" content={props.type} />
    <meta property="og:title" content={props.title} />
    <meta property="og:description" content={props.desc} />
    <meta property="og:image" content={ogImg} />
 </Helmet>

Upvotes: 31

Views: 28080

Answers (3)

Jeremy Thompson
Jeremy Thompson

Reputation: 65594

If you're hosting your React website statically for example on AWS S3 then you probably don't want Server Side Rendering.

An alternative is using a Lambda Function and returning Pre-rendered HTML to Bots and a dynamic experience to users:

const fs = require('fs');
const path = require('path');

const isBot = (userAgent) => {
  return /bot|googlebot|crawler|spider|robot|crawling/i.test(userAgent);
};

exports.handler = async (event, context) => {
  const userAgent = event.headers['user-agent'];
  const isSearchEngineCrawler = isBot(userAgent);

  if (isSearchEngineCrawler) {
    const preRenderedPath = path.join(__dirname, 'pre-rendered', event.path, 'index.html');
    if (fs.existsSync(preRenderedPath)) {
      const preRenderedHtml = fs.readFileSync(preRenderedPath, 'utf8');
      return {
        statusCode: 200,
        headers: {
          'Content-Type': 'text/html',
        },
        body: preRenderedHtml,
      };
    } else {
      return {
        statusCode: 404,
        body: 'Page not found',
      };
    }
  } else {
    const indexHtml = fs.readFileSync(path.join(__dirname, 'build', 'index.html'), 'utf8');
    return {
      statusCode: 200,
      headers: {
        'Content-Type': 'text/html',
      },
      body: indexHtml,
    };
  }
};

Beware every request will go through the lambda.

*Also note you can put static html files in the "public" folder in a React website and these can contain the og:image and etc tags and redirect to a dynamic page, eg /shopping/coffee/morroco redirects to /shopping/coffee/#morroco. Unfortunately each time you post a link to FB, the crawler will check/update its cache so you do need something static at the endpoint (you can't upload the html files, force a batch FB link/cache update, then delete the html files).

Upvotes: 0

Jeremy Dain
Jeremy Dain

Reputation: 1

Alternatively you can use the ogtag.me API to send data and create shorten links dynamically with previews and then share this shorten link rather than the link of the actual page.

Upvotes: -1

Gokhan Sari
Gokhan Sari

Reputation: 7944

Most search engines and crawlers use server's response directly, not allowing you to alter it with javascript. So yes, what you need is server-side rendering.

Or, you can use tools like gatsbyjs, react-static. Basically, they render your components into HTML files beforehand.

Upvotes: 31

Related Questions