How to render Helmet Meta Tags before Styles in Gatsby

Written on

I noticed an issue on my blog posts a few days ago. Whenever I shared them on Twitter, Facebook, LinkedIn or any other social media site, the image defined in the meta tag og:image or twitter:image was not displayed.

The two issues in gatsby/gatsbyjs on GitHub: Metatags from helmet are not recognized by google, neither social medias! #9979 and gatsby-plugin-react-helmet orders the components too late in <head> #22206 seemed to describe my problem pretty accurately.

It seems that the gatsby-plugin-react-helmet renders the meta tags too late in the head section. To test this assumption I briefly checked it with the Facebook sharing debugger.

And indeed, the debugger showed me the message that it could not find the meta tag og:image. To be on the safe side I checked the source code of my generated sites but the meta tags were there.

In both tickets it is mentioned that the rendering of the meta tags should happen before the styles. This is possible with a modification of the Gatsby Server Rendering APIs1 in the file gatsby-ssr.js.

Modifing gatsby-ssr.js to render the helmet components as first in the <head> section
var React = require("react");

exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {
    /**
     * @type {any[]} headComponents
     */
    const headComponents = getHeadComponents();

    headComponents.sort((a, b) => {
        if (a.props && a.props["data-react-helmet"]) {
            return 0;
        }
        return 1;
    });
    replaceHeadComponents(headComponents);
};

After a re-deployment on Netlify with the changes mentioned above I checked the articles again with the Facebook sharing debugger and indeed the meta tag og:image was now found.

The only problem, the url to the picture was still wrong, this was due to a change I made before, where I tried to define the base url based on the location instead of getting the defined base url from SiteMetaData.

After reverting the change, the problem should now be solved. Feel free to try it out and share this article on your favorite social media platform ;-) — Thanks!