Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby): Reorder head tags #34030

Merged

Conversation

graysonhicks
Copy link
Contributor

@graysonhicks graysonhicks commented Nov 19, 2021

Description

Reorder tags to e.g. move css below meta tags as apparently larger stylesheets block the parsers

Documentation

Related Issues

Fixes #22206

@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Nov 19, 2021
KyleAMathews
KyleAMathews previously approved these changes Nov 19, 2021
Copy link
Contributor

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏🥳

@KyleAMathews
Copy link
Contributor

Actually why don't we just do this in the framework itself?

@graysonhicks
Copy link
Contributor Author

Fine by me. Probably a better 'batteries included' experience than needing this plugin configured for that best practice. As long as the plugin wouldn't undo the framework's sorting.

@KyleAMathews
Copy link
Contributor

Yeah we'd do the sorting after all plugins have run. This is in the oddly named static-entry.js files

@LekoArts LekoArts added topic: core Relates to Gatsby's core (e.g. page loading, reporter, state machine) and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Nov 22, 2021
axfoxtail
axfoxtail previously approved these changes Nov 23, 2021
@graysonhicks
Copy link
Contributor Author

graysonhicks commented Dec 1, 2021

@KyleAMathews I moved the same sorting logic to right before head components are sent to static HTML in static-entry. One thing I am not sure of is whether this will interfere with this line for determining whether to inline styles.

@graysonhicks
Copy link
Contributor Author

I still need to make a contrived example with lots of head tags to compare the sorting order.

@Ciantic
Copy link

Ciantic commented Dec 2, 2021

I looked at the diff, what does it do to tags that are not listed in this?

   headComponents = [
      ...groupedByType.title,
      ...groupedByType.base,
      ...groupedByType.meta,
      ...groupedByType.style,
      ...groupedByType.link,
      ...groupedByType.script,
      ...groupedByType.noscript,
    ]

For example, if you have <template /> tags in your head, will they be removed?

According to MDN, allowed tags inside <head /> are:

<title>, <base>, <link>, <style>, <meta>, <script>, <noscript>, <template>

Notable that I don't know what tags are disallowed, MDN doesn't explicitly say that, so people might be throwing other tags there too.

IMO, re-ordering all tags in the head can have odd consequences, like having template before or after a script tag might make site broken. It would be better if it could be done in order of introduction.

Move just meta tags above everything else, and leave the order as is, it would probably break less stuff than ordering all tags.

@graysonhicks
Copy link
Contributor Author

@Ciantic Yea, that is a good point about tags not listed there. Technically there is already some opinionated ordering done by when certain tags are pushed to headComponents, but we could, as you say, just preserve those and move meta to the top.

@graysonhicks
Copy link
Contributor Author

Possible other solution in static-entry then is just:

 headComponents.sort((a, b) => {
        if (a.type && a.type === 'meta') {
            return -1;
        }
        return 0;
    });

@KyleAMathews
Copy link
Contributor

The inline styles are already added by the time you sort right?

We should definitely sort rather than rewrite.

@graysonhicks
Copy link
Contributor Author

Yea, the inline styles are added via unshift before I have the sort.

@LekoArts LekoArts changed the title Reorder head tags in react-helmet fix(gatsby): Reorder head tags Dec 3, 2021
@graysonhicks
Copy link
Contributor Author

In my first bit of testing on this with the sort, the ordering looks correct during SSR, but then the tags are back out of order (meta tags from helmet specifically) in DevTools. Is there something updating the head components during/after hydration?

@KyleAMathews

@KyleAMathews
Copy link
Contributor

So if you curl the page the tags are correct?

Once on the client, tags are added by react-helmet in the order of the code so they'll be back to that. But to fix the issue with crawlers we only need to worry about the SSRed html.

@graysonhicks
Copy link
Contributor Author

I didn't curl exactly, but yea the first network request with the SSR'd HTML looks correct. Cool, that makes sense about the crawlers! I'm gonna try to repro the actual og:image failure.

@graysonhicks
Copy link
Contributor Author

graysonhicks commented Dec 7, 2021

URL with this fork patched in shows the correct tags on the initial request now:

go here:
https://headtagstestmain.gatsbyjs.io/

do this:
open network tab
select first network request (the domain)
open the HTML from the first request (can prettify in chrome with {} button)

see this:
meta tags are above all script and style tags

I tried testing with the Twitter Card Validator, but I think it may be using a cached version (the image is missing) since I had tested before without the patch. The Facebook sharing tester is showing the correct data.

@graysonhicks graysonhicks marked this pull request as ready for review December 13, 2021 15:46
@KyleAMathews KyleAMathews merged commit 10c8227 into gatsbyjs:master Dec 17, 2021
@m99coder
Copy link

Will it be backported/be part of Gatsby 3.x?

@manutdkid77
Copy link
Contributor

Similar question to @m99coder, will this be backported to Gatsby 2.x ? we have some sites still running on Gatsby 2.19

@LekoArts
Copy link
Contributor

It'll only be backported to v3

LekoArts pushed a commit that referenced this pull request Jan 10, 2022
* group head tags and reorder and spread

* move tag ordering to static-entry

* change reduce to sort

* comment purpose of headComponents sort

(cherry picked from commit 10c8227)
@manutdkid77
Copy link
Contributor

It'll only be backported to v3

Thats a bummer, we have sites which we dont want to upgrade to v3 and would be nice if it could be backported to v2

@t2ca
Copy link
Contributor

t2ca commented Jan 12, 2022

I have just tested v4.5 and I noticed that the meta tags show up on top only on initial page load. Once I click on a link it gets reordered again and certain meta tags are under the styles once again.

@KyleAMathews
Copy link
Contributor

KyleAMathews commented Jan 12, 2022

@t2ca crawlers only grab the HTML so you should be fine

@m99coder
Copy link

m99coder commented Jan 14, 2022

Hi @graysonhicks and @KyleAMathews, I updated my Gatsby dependency to 4.5.2 and deployed the new version. Unfortunately, I still see a suboptimal order of tags in the <head>.

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">

<link rel="manifest" href="/site.webmanifest">

<title>Geschenkanhänger Wolke aus Holz · woodist</title>
<title data-react-helmet="true"></title>

<meta name="generator" content="Gatsby 4.5.2">

<link rel="sitemap" type="application/xml" href="/sitemap/sitemap-index.xml">

<!-- script preloads omitted -->
<!-- fetch preloads omitted -->

<noscript>
  <style>
    /* Gatsby image styles */
  </style>
</noscript>
<script type="module">/* Gatsby Image code */</script>
<style data-href="/styles.f096984017ec13218975.css" data-identity="gatsby-global-css">
  /* massive initial styles (probably because of importing them in the layout component */
</style>
<style>/* Gatsby Image styles */</style>

<!-- dns-prefetchs omitted -->

<meta name="description" content="Dieser Holzanhänger in Form einer Wolke zaubert den Beschenkten mit Sicherheit ein Lächeln ins Gesicht. Es ist ausreichend Platz für ein paar liebe Zeilen, ein kurzes Statement, den Namen oder oder oder... Leb dich aus mit Acrylfarben, Brandmalerei oder Acrylstiften." data-react-helmet="true">
<meta name="keywords" content="Geschenkanhänger,Anhänger aus Holz,Wolke aus Holz,Anhänger Wolke" data-react-helmet="true">
<meta name="image" content="https://cdn.shopify.com/s/files/1/0279/1938/4659/products/20210801_134314_400x533_crop_center.jpg?v=1629974153" data-react-helmet="true">

<meta property="og:url" content="https://woodist.de/produkt/anhaenger-wolke" data-react-helmet="true">
<meta property="og:title" content="Geschenkanhänger Wolke aus Holz" data-react-helmet="true">
<meta property="og:description" content="Dieser Holzanhänger in Form einer Wolke zaubert den Beschenkten mit Sicherheit ein Lächeln ins Gesicht. Es ist ausreichend Platz für ein paar liebe Zeilen, ein kurzes Statement, den Namen oder oder oder... Leb dich aus mit Acrylfarben, Brandmalerei oder Acrylstiften." data-react-helmet="true">
<meta property="og:image" content="https://cdn.shopify.com/s/files/1/0279/1938/4659/products/20210801_134314_400x533_crop_center.jpg?v=1629974153" data-react-helmet="true">
<meta name="twitter:card" content="summary_large_image" data-react-helmet="true">
<meta name="twitter:image" content="https://cdn.shopify.com/s/files/1/0279/1938/4659/products/20210801_134314_400x533_crop_center.jpg?v=1629974153" data-react-helmet="true">

<!-- prefetchs omitted -->

I might make something wrong that gatsby-global-css gets so big, but on the other hand, the reordering of meta tags should have moved the <meta …> ones way up, I guess.

Source: https://woodist.de/produkt/anhaenger-wolke/

If needed, I can also provide the dependency list, that I use or some other details for debugging.

@graysonhicks
Copy link
Contributor Author

@m99coder When I visit that site and look at the network tab, I see a different set of head tags than you've posted above. The meta tags are totally missing when I look, but otherwise the order is correct. How are they being added? The network tab is what a crawler would see.

@m99coder
Copy link

m99coder commented Jan 14, 2022

The meta tags are added using react-helmet like this:

import { Helmet } from "react-helmet"

const Layout = () => {
  return (
    <Helmet
      title={seo.title}
      titleTemplate={seo.title === defaultTitle ? seo.title : titleTemplate}
    >
      <meta name="description" content={seo.description} />
      <meta name="keywords" content={seo.metatags.join(",")} />
      <meta name="image" content={seo.image} />

      {/* DNS prefetch */}
      <link rel="dns-prefetch" href="//images.ctfassets.net/" />
      <link rel="dns-prefetch" href="//cdn.shopify.com/" />
      <link rel="dns-prefetch" href="//m99.io/" />

      {/* Open Graph, see https://ogp.me/ */}
      {seo.url && <meta property="og:url" content={seo.url} />}
      {seo.title && <meta property="og:title" content={seo.title} />}
      {seo.description && (
        <meta property="og:description" content={seo.description} />
      )}
      {seo.image && <meta property="og:image" content={seo.image} />}

      {/* Twitter, see https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started */}
      <meta name="twitter:card" content="summary_large_image" />
      {seo.image && <meta name="twitter:image" content={seo.image} />}
    </Helmet>
  )
}

Check the network tab and I also don’t see them. So maybe using react-helmet for that purpose is not a good idea 🤔 On the other my approach looks quite similar to what I read here https://www.gatsbyjs.com/tutorial/seo-and-social-sharing-cards-tutorial/.

Is it maybe only working when I define them as attributes of the Helmet component?

@graysonhicks
Copy link
Contributor Author

@m99coder Yes, would be interesting to see if there is a difference between the Helmet attributes vs children.

@m99coder
Copy link

m99coder commented Jan 15, 2022

@graysonhicks Sadly doesn’t change the result. Even https://github.com/nfl/react-helmet shows that defining the tags as children should work. Now I’m a bit clueless 😕 May it be related to how the SSR works? On the other side I don’t think my setup is anyhow unique, so wonder why it doesn’t happen for others as well.

I will take some time to debug and try to build up my setup from scratch to see at which point it stops working.

@desktopofsamuel
Copy link
Contributor

Same issues here @graysonhicks. Twitter validator & Facebook Sharing Debugger cannot crawl the meta tags after upgrading to v4.5.2 even tags order shifted already. My SEO components was pretty much copied from another site coming from v3 which is totally working right now.

What I discovered is that the crawler completed even before content from the react-helmet injected.
From what Facebook crawler see exactly for the URL https://developers.facebook.com/tools/debug/echo/?q=https%3A%2F%2Fjuxtdesign.cc%2Fblog%2Ftry-our-keystroke-figma-template%2F
All react-helmet content is not present but it's totally there when I open it in Chrome Devtools. Maybe @m99coder you can also try and see the same behavior? (Bottom of the Sharing Debugger)

My testing link:
https://juxtdesign.cc/blog/try-our-keystroke-figma-template/

Just for reference, my SEO component, placed in layout.tsx

  return (
    <Helmet>
      {/* General tags */}
      <html lang="en" />
      <title>{title}</title>
      <meta name="title" content={title} />
      <meta name="description" content={description} />
      <meta name="image" content={image} />
      <meta name="keywords" content={keywords} />
      <meta name="publisher" content={config.siteTitleShort} />
      <meta name="author" content={config.siteTitleShort} />
      <meta name="copyright" content={config.copyright} />

      {/* Schema.org tags */}
      <script type="application/ld+json">
        {JSON.stringify(schemaOrgJSONLD)}
      </script>

      {/* OpenGraph tags */}
      <meta property="og:url" content={postURL} />
      {postSEO ? (
        <meta property="og:type" content="article" />
      ) : (
        <meta property="og:type" content="website" />
      )}
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={image} />
      <meta
        property="fb:app_id"
        content={config.siteFBAppID ? config.siteFBAppID : ``}
      />

      {/* Twitter Card tags */}
      <meta name="twitter:card" content="summary_large_image" />
      <meta
        name="twitter:site"
        content={config.userTwitter ? config.userTwitter : ``}
      />
      <meta name="twitter:title" content={title} />
      <meta name="twitter:description" content={description} />
      <meta name="twitter:image" content={image} />
    </Helmet>
  );
}

My info:

  System:
    OS: macOS 12.1
    CPU: (10) arm64 Apple M1 Pro
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    Yarn: 1.22.17 - /opt/homebrew/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Languages:
    Python: 2.7.18 - /usr/bin/python
  Browsers:
    Chrome: 97.0.4692.71
    Safari: 15.2
  npmPackages:
    gatsby: 4.5.2 => 4.5.2
    gatsby-plugin-google-tagmanager: 4.5.0 => 4.5.0
    gatsby-plugin-image: 2.4.0 => 2.4.0
    gatsby-plugin-manifest: 4.5.1 => 4.5.1
    gatsby-plugin-sharp: 4.4.0 => 4.4.0
    gatsby-plugin-sitemap: 5.5.0 => 5.5.0
    gatsby-source-filesystem: 4.4.0 => 4.4.0
    gatsby-source-prismic: 5.2.3 => 5.2.3
    gatsby-theme-stitches: 1.0.0 => 1.0.0
    gatsby-transformer-sharp: 4.4.0 => 4.4.0

@graysonhicks
Copy link
Contributor Author

Okay, thanks. This seems like a separate issue. The original issue was tags were out of order (no matter how they were added). This seems like react-helmet isn't getting SSR'd. There shouldn't be a 'too late' because the static markup should have the correct tags before hydration. Can you open a new issue?

@desktopofsamuel
Copy link
Contributor

Okay, thanks. This seems like a separate issue. The original issue was tags were out of order (no matter how they were added). This seems like react-helmet isn't getting SSR'd. There shouldn't be a 'too late' because the static markup should have the correct tags before hydration. Can you open a new issue?

Sorry, I created a reproduction repo and realised gatsby-plugin-react-helmet has not been installed. Installing it and adding in gatsby-config.js has resolved the issue now.

@m99coder
Copy link

@desktopofsamuel @graysonhicks I checked the Facebook Developer Echo result you shared, and in my case the react-helmet extensions to the <head> are not there. Maybe because I played around with the hydrate function in gatsby-browser.js in that sense:

import ReactDOM from "react-dom"
import { wrapPageElement as wrapper } from "./src/utils/wrap-page-element"

export const wrapPageElement = wrapper

// this is a hack to fix missing styles on refresh in production
// see: https://github.com/gatsbyjs/gatsby/issues/8560#issuecomment-535265414
// and: https://github.com/gatsbyjs/gatsby/discussions/17914
export function replaceHydrateFunction() {
  return (element, container, callback) => {
    ReactDOM.render(element, container, callback)
  }
}

As soon as I find time, I will strip down my setup to the bare minimum and see at which point the functionality is broken. Chances are high that I added some custom logic that killed the expected behaviour 😅

@m99coder
Copy link

m99coder commented Jan 21, 2022

Created a bare, unmodified repository like this:

gatsby new gatsby-metatags https://github.com/gatsbyjs/gatsby-starter-default

You can find the respective code here: https://github.com/m99coder/gatsby-open-graph-metatags.

Now when I run gatsby develop, I get the following response when running a request with curl -s http://localhost:8000:

<!DOCTYPE html>
<html>

<head>
  <meta charSet="utf-8" />
  <meta http-equiv="x-ua-compatible" content="ie=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
  <meta name="note" content="environment=development" />
  <title data-react-helmet="true"></title>
  <style>
    .gatsby-image-wrapper {
      position: relative;
      overflow: hidden
    }

    .gatsby-image-wrapper picture.object-fit-polyfill {
      position: static !important
    }

    .gatsby-image-wrapper img {
      bottom: 0;
      height: 100%;
      left: 0;
      margin: 0;
      max-width: none;
      padding: 0;
      position: absolute;
      right: 0;
      top: 0;
      width: 100%;
      object-fit: cover
    }

    .gatsby-image-wrapper [data-main-image] {
      opacity: 0;
      transform: translateZ(0);
      transition: opacity .25s linear;
      will-change: opacity
    }

    .gatsby-image-wrapper-constrained {
      display: inline-block;
      vertical-align: top
    }
  </style><noscript>
    <style>
      .gatsby-image-wrapper noscript [data-main-image] {
        opacity: 1 !important
      }

      .gatsby-image-wrapper [data-placeholder-image] {
        opacity: 0 !important
      }
    </style>
  </noscript>
  <script
    type="module">const e = "undefined" != typeof HTMLImageElement && "loading" in HTMLImageElement.prototype; e && document.body.addEventListener("load", (function (e) { if (void 0 === e.target.dataset.mainImage) return; if (void 0 === e.target.dataset.gatsbyImageSsr) return; const t = e.target; let a = null, n = t; for (; null === a && n;)void 0 !== n.parentNode.dataset.gatsbyImageWrapper && (a = n.parentNode), n = n.parentNode; const o = a.querySelector("[data-placeholder-image]"), r = new Image; r.src = t.currentSrc, r.decode().catch((() => { })).then((() => { t.style.opacity = 1, o && (o.style.opacity = 0, o.style.transition = "opacity 500ms linear") })) }), !0);</script>
  <link rel="icon" href="/favicon-32x32.png?v=4a9773549091c227cd2eb82ccd9c5e3a" type="image/png" />
  <link rel="manifest" href="/manifest.webmanifest" crossorigin="anonymous" />
  <link rel="apple-touch-icon" sizes="48x48" href="/icons/icon-48x48.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="72x72" href="/icons/icon-72x72.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="96x96" href="/icons/icon-96x96.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="144x144" href="/icons/icon-144x144.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="192x192" href="/icons/icon-192x192.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="256x256" href="/icons/icon-256x256.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="384x384" href="/icons/icon-384x384.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <link rel="apple-touch-icon" sizes="512x512" href="/icons/icon-512x512.png?v=4a9773549091c227cd2eb82ccd9c5e3a" />
  <script src="/socket.io/socket.io.js"></script>
  <link rel="stylesheet" href="/commons.css" />
</head>

<body>
  <div id="___gatsby"></div>
  <script src="/polyfill.js" nomodule=""></script>
  <script src="/framework.js"></script>
  <script src="/commons.js"></script>
</body>

</html>

As you can see there are no SEO-related metatags included.
But wait 😄 As soon as I use gatsby serve, I get the following <head> tag content which is expected and correct:

<head>
  <meta charSet="utf-8" />
  <meta http-equiv="x-ua-compatible" content="ie=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
  <meta data-react-helmet="true" name="twitter:description"
    content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need." />
  <meta data-react-helmet="true" name="twitter:title" content="Home" />
  <meta data-react-helmet="true" name="twitter:creator" content="@gatsbyjs" />
  <meta data-react-helmet="true" name="twitter:card" content="summary" />
  <meta data-react-helmet="true" property="og:type" content="website" />
  <meta data-react-helmet="true" property="og:description"
    content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need." />
  <meta data-react-helmet="true" property="og:title" content="Home" />
  <meta data-react-helmet="true" name="description"
    content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need." />
  <meta name="generator" content="Gatsby 4.5.4" />
  <!-- more non-meta tags -->
</head>

So there is clearly an issue somewhere in my original project. I will try to narrow it down.

Update

  • Slowing adding plugin by plugin and checking the output
  • The respective steps are tagged in the Git repository
  • The check is run using curl -s http://localhost:9000 | tidy 2>&1 | grep "og:" while gatsby serve is running

Dependencies, plugins and features used

@m99coder
Copy link

m99coder commented Jan 23, 2022

@graysonhicks @KyleAMathews I might have found the issue 🤭

With my last commit m99coder/gatsby-open-graph-metatags@3f63d12 I create a dynamic page like this in gatsby-node.js:

exports.createPages = async ({ actions }) => {
  const { createPage } = actions
  createPage({
    path: "/using-dsg",
    component: require.resolve("./src/templates/using-dsg.js"),
    context: {},
    defer: true,
  })
  
  createPage({
    path: "/test",
    component: require.resolve("./src/templates/test.js"),
    context: {},
  })
}

When the path is requested (with gatsby serve running), the original request is redirected to the one with a trailing slash:

Request URL: http://localhost:9000/test
Request Method: GET
Status Code: 301 Moved Permanently

Request URL: http://localhost:9000/test/
Request Method: GET
Status Code: 200 OK

This is in contrast to the /using-dsg dynamic page – it’s path is not redirected to a trailing-slash version. I also assume that the defer option (using DSG) should not determine if the redirect is happening or not. If the dynamic page is directly requested using a trailing slash, the router removes it instantly.

Finally, I assume that the social share tools work similar to using curl. They might not follow the redirect.

$ curl -s http://localhost:9000/test | tidy 2>&1 | grep "og:"

$ curl -s http://localhost:9000/test/ | tidy 2>&1 | grep "og:"
<meta data-react-helmet="true" property="og:type" content=
<meta data-react-helmet="true" property="og:description" content=
<meta data-react-helmet="true" property="og:title" content=

$ curl -L -s http://localhost:9000/test | tidy 2>&1 | grep "og:"
<meta data-react-helmet="true" property="og:type" content=
<meta data-react-helmet="true" property="og:description" content=
<meta data-react-helmet="true" property="og:title" content=

Never mind, I see that also on my production page the redirect happens, but in this case the version provided under the path with the trailing slash, doesn’t have the correct meta tag order neither 😞

@m99coder
Copy link

m99coder commented Jan 24, 2022

Human error… pure human error 🚯

In my wrapPageElement method, I just forgot to use {element} in non-browser environments as well. This prevented react-helmet from setting the headComponents correctly.

export const wrapPageElement = ({ element }) => {
  // configure Sentry
  Sentry.configureScope(scope => {
    scope.addEventProcessor(event => {
      // eslint-disable-next-line no-unused-vars
      const { user, ...redacted } = event
      return redacted
    })
  })

  return (
    <Sentry.ErrorBoundary fallback={"An error has occurred"}>
      {isBrowser && (
        <ListOptionsProvider>{element}</ListOptionsProvider>
      )}
      {/* the next line was missing before */}
      {!isBrowser && element}
    </Sentry.ErrorBoundary>
  )
}

I really apologize for all the hassle. This feature works as intended.

@graysonhicks
Copy link
Contributor Author

No worries, thanks @m99coder !

@mixdmark
Copy link

I understand from this thread, that Gatsby should now sort the head tags automatically. Or is there something I have to specify in my code for the sorting to be enabled?

I'm using Gatsby 4.10.1, gatsby-react-helmet-plugin and SEO component as defined in official Gatsby site template. My pages are created in gatsby-node.js with createPages. I'm using static site generation as rendering method.

And Chrome Network tab shows that meta tags are still in random places in the head, mostly after scripts, links and styles.

@graysonhicks
Copy link
Contributor Author

@mixdmark Could you please open a new issue with a reproduction? Should be working by default.

@niksumeiko
Copy link

@mixdmark, I just tried it with [email protected] and can confirm the production build contains meta tags correctly ordered (at the very top of the <head> section) automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: core Relates to Gatsby's core (e.g. page loading, reporter, state machine)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gatsby-plugin-react-helmet orders the components too late in <head>