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

any possible way to disable 'data-react-helmet="true"' from server side rendering? #79

Open
ghost opened this issue Dec 2, 2015 · 69 comments
Labels

Comments

@ghost
Copy link

ghost commented Dec 2, 2015

i don't mind if its in the client but i don't like these extra chars in my markup.

any suggestions?
thanks

@cwelch5
Copy link
Contributor

cwelch5 commented Dec 3, 2015

We currently use that markup to distinguish Helmet's tags from existing tags in the app, in case a user wants tags managed outside of Helmet. The current implementation clears all the tags managed by Helmet and re-adds them. If we eliminated this from the server, we couldn't distinguish on the front end.

We will be moving to an implementation that will track individual tags on the front end and only update the changed ones. But for that we still need the client to establish a set of known Helmet-managed tags.

We could potentially re-visit why we have separate Helmet-managed tags and consider having Helmet manage everything...or perhaps an opt-in for full management vs. partial management. Hmmm....thoughts?

@pavelkornev
Copy link

@cwelch5 Having such an option would be cool

@janoist1
Copy link

janoist1 commented Aug 3, 2016

Still nothing?

@dergachevm
Copy link

dergachevm commented Dec 6, 2016

Realy need to disable data-attributes from meta tags on server side. I have asked support of Yandex and they say data attributes not allowed in meta tags

@svagi
Copy link

svagi commented Dec 6, 2016

@dergachevm As a workaround, you can replace it with empty string. Something like:

const Head = Helmet.rewind()
const regexp = / data-react-helmet="true"/g
const attr = Head.htmlAttributes.toString()
const title = Head.title.toString().replace(regexp, '')
const link = Head.link.toString().replace(regexp, '')
const style = Head.style.toString().replace(regexp, '')
const meta = Head.meta.toString().replace(regexp, '')
const script = Head.script.toString().replace(regexp, '')

@dergachevm
Copy link

@svagi Thank you

@huygn
Copy link

huygn commented Dec 21, 2016

Anyways I can do this in the client? I have a React client side rendered page and trying to use meta tags for Twitter Card.

@staylor
Copy link

staylor commented Feb 24, 2017

Only remove the data attribute from element sets that aren't already in the <head>:

<head>
${head.meta.toString().replace(regExp, '')}
${head.title.toString().replace(regExp, '')}
${head.script.toString().replace(regExp, '')}
${head.link.toString()}
${cssBundle ? `<link rel="stylesheet" type="text/css" href="${cssBundle}" />` : ''}
</head>

Otherwise, the <link> tag will get wiped out.

@gajus
Copy link

gajus commented May 8, 2017

@cwelch5 Can you make HELMET_ATTRIBUTE configurable?

In the mean time, a dirty workaround is:

require('react-helmet/lib/HelmetConstants.js').HELMET_ATTRIBUTE='data-react';

Personally, I don't feel comfortable exposing the fact that the server-side code is using a particular framework. Exposing in markup that react-helmet is being used to generate headers creates a possible attack vector.

@ncochard
Copy link

I am wondering if anybody has evidence that the data-react-helmet attribute is a detriment to SEO?

We are using react-helmet for SEO. We use it to insert content into the <title> tag, and manage other tags such as <link rel="canonical" href="...">, etc.

Our SEO consultant suspect that the attribute data-react-helmet may affect SEO negatively.

Since we are implementing an isomorphic application, removing the data-react-helmet attribute server-side (e.g. ${head.title.toString().replace(regExp, '')}) is not an option, because this will cause the element to be duplicated when the page is re-rendered client-side.

So I am considering working on a fork (or pull-request) which does not use the attribute data-react-helmet. But this will be a lot of work. And clearly according to W3C data-* attributes are allowed and should not cause any issue. So do the Google bots correctly ignore the data-* attributes when analysing the HTML?

@jfuchs
Copy link

jfuchs commented May 31, 2017

I've run into another issue with this data attribute — it breaks Google AMP's [albeit strict] validation for their boilerplate tags.

@shahkashani
Copy link

Please. 🙏

@hugmanrique
Copy link

+1 This is affecting Google's AMP pages

@esbb48
Copy link

esbb48 commented Aug 18, 2017

It also affect Facebook debugger
https://developers.facebook.com/tools/debug/

@jcdarwin
Copy link

jcdarwin commented Sep 5, 2017

In order to deal with this annoying behaviour, you can do this hack, which removes the data-react-helmet attribute between Helmet calls.

    <!-- The mount point for the header.js component; this can be whatever you want. -->
    <div id="header"></div>

    <!-- The mount point for the footer.js component; this can be whatever you want. -->
    <div id="footer"></div>

    <script>
        (function() {
          this.removeAttribute = function(tagName, attribute) {
            var tags = document.getElementsByTagName(tagName)
            // Convert our nodelist to an array, so we can iterate using forEach
            tags = Array.prototype.slice.call(tags);
            tags.forEach(function (tag) {
              tag.removeAttribute(attribute)
            })
          }

          this.renderComponent = function(component, mountPoint, props) {
            // We need to remove the data-react-helmet attribute from any <style>s added
            // previously by react-helmet, otherwise on the next invocation (i.e. inside a component)
            // it will remove these styles from the DOM.
            // https://github.com/nfl/react-helmet/issues/79
            this.removeAttribute('style', 'data-react-helmet')

            ReactDOM.render(
              React.createElement(component, props || {}, null),
              document.getElementById(mountPoint)
            )
          }

          // Render the header
          this.renderComponent(StuffIsomorphicComponent__header, 'header')

          // this.renderComponent(StuffIsomorphicComponent__headline, 'headline', {title: 'What is this?'})

          // Render the footer
          this.renderComponent(StuffIsomorphicComponent__footer, 'footer')
        }())
    </script>

@calpa
Copy link

calpa commented Nov 8, 2017

It affects the Facebook open graph...

@elrumordelaluz
Copy link

elrumordelaluz commented Nov 10, 2017

Same problem here for Twitter Cards

@spiral2k
Copy link

any updates on this one?

@adam-26
Copy link

adam-26 commented Dec 14, 2017

I have forked react-helmet and removed the data-react-helmet attribute usage, it's published as react-cap.

There is one caveat, if you include any metadata in your render using alternative methods (not react-helmet syntax), you must assign the HTML element the attribute data-ignore-metadata. There's more information on the readme page.

Obviously it would be preferable if react-helmet included an option to disable use of the attribute, but given this issue is over 2 years old that seems unlikely. As a side note, the fork was originally created to enable support of the react 16 server-side streaming interface.

@priteshpoddar
Copy link

Any updates on this?

@milotindragos
Copy link

Any news on this?

@ghost
Copy link

ghost commented Apr 12, 2018

data-react-helmet is annoying

@RobsonAraujo
Copy link

Our project is using Helmet too and we use server side rendering. When checking the SEO with https://seositecheckup.com/ we get missing tags (especially the description meta tag) although it is there. We suspect that thedata-react-helmettags might cause this problem.
Note, we don't have problems with the Facebook og:+* tags...
So it might not be a real problem, just that the mentioned site gives us a bad note...

@championshuttler
Copy link

How to add meta tag of twitter card in react-helmet to render dynamic data

@flavioalves
Copy link

+1

@AubreyHewes
Copy link
Contributor

AubreyHewes commented Oct 9, 2020

all these "problems" are not due to react-helmet....

One of my personal favorites is as @gajus said

Personally, I don't feel comfortable exposing the fact that the server-side code is using a particular framework. Exposing in markup that react-helmet is being used to generate headers creates a possible attack vector.

Wrong in so many cases, usage of react-helmet is negligible. Serve it as cold html ... is that html a vector?... anyway even then you can remove it from the generated static html files. (your app js as react is still recognizable as react.. still can see anything you use... usage of react-helmet is negligible);

If you don't like the attribute, the fear of the dark;
When you are SSR you have control of the output. If not look to the library used. Else remove the scare before deploy.
When you are SG you have control of the output. If not look to the library used. Else remove the scare before deploy.

The only reason for removing the attribute is management purity. Which in most cases is negligible. If you think you may need to remove it then add a job after the build.

@DesignByOnyx
Copy link

@AubreyHewes - it's not very constructive to tell people that there's no problem in helmet. This has been a long-standing issue and lots of people are clearly having issues with this, especially in the realm of unfurling (which is why I'm here), so please don't brush it off. Not everybody has the skills or ability to write sed or gc -replace or node scripts to go and muck around with machine generated markup. And unless you're a trained security expert, there's no telling what kind of information is useful to an attacker, no matter how benign or static the website is. Some people just want to to be able to control the generated markup, others don't want to expose what modules they used "just because"... and they should be allowed to do so.

I suggest that instead of writing arbitrary attributes to the helmet-controlled nodes, helmet should precede all helmet nodes with a special/configurable html comment:

<head>
  <!-- helmet -->
  <meta property="og:title" description="..." />
</head>

Then helmet could do something like this to get all of its controlled nodes:

const meta = Array.from(document.head.querySelectorAll('meta')).map(meta => 
    meta.previousSibling.nodeType === 8 && meta.previousSibling.textContent.trim() === 'helmet'
)

Not so hacky solution, but with caveats

For those who want to try out a post build script, you can do the following. Please note that this will fix the server-generated markup, but the mounted SPA will result in duplicate tags because helmet cannot differentiate between tags it created and tags it did not. This will not break your app, but it might confuse bots which execute javascript.

  1. Install this package: npm i replace-in-file
  2. Update your package.json to have a postbuild script:
    "scripts": {
      "build": "gatsby build",
      "postbuild": "node scripts/postbuild.js",
      ...
    }
  3. Create a file at [root]/scripts/postbuild.js with the following content:
    const replace = require('replace-in-file')
    
    const replaceOptions = {
      files: ['public/**/*.html'],
      from: / data-react-helmet="true"/g,
      to: '',
    }
    
    async function replaceHelmetAttrs() {
      const results = await replace(replaceOptions)
      const count = results.reduce((cnt, res) => cnt + (res.hasChanged ? 1 : 0), 0)
      console.log(`replaceHelmetAttrs: ${count} files changed`)
    }
    
    const start = Date.now()
    replaceHelmetAttrs()
      .then(() => console.log(`postbuild done in ${Date.now() - start}ms`))
      .catch((err) => console.error(err))
  4. Run your build: npm run build

@AubreyHewes
Copy link
Contributor

@DesignByOnyx your solution is exactly what I said

even then you can remove it from the generated static html files

I was not brushing anything off.

Your idea of a prepended comment does not work in react-helmet; and just exposes the exact same information (the original issue).

But still, when a developer uses this library they should know what they are doing, i.e. accept this issue /or resolve it themselves.

The solution for static generated sites is to remove the attribute (as I stated and your solution). Non static sites are crappy seo anyway. If you are not static but public.. then you need to rethink your application decisions.

This is only a problem if you think it is a problem or do not like the attribute. I have yet to generate a static site that does not work properly with opengraph compatible consumers (fb/twitter/etc -- unfurling).

@scragg0x
Copy link

I'm not doing SSR and I am trying to load a 3rd party script and it's complaining about the attribute data-react-helmet and throwing an error as part of a validation process. Now I fully understand that the 3rd party script should just ignore it but that is out of my control.

@AubreyHewes what is the problem with just adding a prop to get rid of this attr?

@AubreyHewes
Copy link
Contributor

@scragg0x As you stated "Now I fully understand that the 3rd party script should just ignore it"...

Your best chance is to reach out to the 3rd party that they should ignore things that have nothing to do with them. Or use a 3rd party lib that does not test things that are not their responsibility... (which lib?)

To remove the prop requires ... well look at the codebase.

@scragg0x
Copy link

@AubreyHewes The library is from a CC payment gateway service, not an open source project on github so it's unlikely to change in a timely manner. I am resorting to a vanilla JS approach to loading the script. I use react-helment for other script includes, so it would of been nice to use it as well.

@qdm12
Copy link

qdm12 commented Nov 13, 2020

Same situation here, for example Google site verification also fails because of this, so I rely on hardcoding it in the index.html instead. I had issues with other platforms too, like Facebook, especially when it's about verification. It would be really nice to have an option (a prop?) to disable it.

@AubreyHewes
Copy link
Contributor

AubreyHewes commented Nov 26, 2020

@scragg0x @qdm12

The current solution is to add a post build script that scrubs the attribute as previously proposed. Though this depends on if the app/site in question is static SPA vs dynamic SPA.

you can remove it from the generated static html files

For a possible postbuild script see #79 (comment)

@scragg0x So you are deploying as a dynamic SPA? If so there is not really a solution... the dynamically generated html will always have the attribute.

To reiterate this is not actually really a problem with the library but the usage/expectation within other frameworks.

@Morantron
Copy link

Morantron commented Feb 12, 2021

Using https://github.com/ds300/patch-package and replacing "data-react-helmet" for "data-react" in node_modules did the trick for me.

It's hacky but not that much ™️

@philr35
Copy link

philr35 commented Mar 10, 2021

This ticket was opened in 2015.. clearly people still want the ability to remove this. Whether its a bug, an enhancement, or a new feature, is not the point. The community around this open-sourced project want the ability to disable this attribute. In the worst case, maybe there is a bug in some use-cases that you're not aware of. In the best case, its people complaining about semantics of if attributes should be included on the meta tag. Regardless, of the situation, its something people are coming to this ticket about because they want the ability to disable this. This seems reasonable to me and after 6 years I don't see why its been pushed into a corner for so long. I don't think this should continue to be ignored.

@y1n0
Copy link

y1n0 commented Jun 4, 2021

still there is no decent solution to this?

@devinhalladay
Copy link

devinhalladay commented Jul 27, 2021

Bumping this again because maintainers behaving this way really gets to me.

Let me take a stab on some next steps we could take: @AubreyHewes I see PRs posted above long ago, and some discussion around your feeling that this behavior (which is evidently not a bug) is best solved by external libraries and post-processing. To me, that sounds very brittle and incredibly opinionated for a library that should ostensibly be quite _un_opinionated. Not to mention, many people here find this behavior problematic for one reason or another; the reason itself does not really matter because the concerns are valid.

So if you don't like the above solutions @AubreyHewes, would you please take a moment to let us know what a feasible solution might look like? What are your concerns, and how can we turn those into constraints to meet your expectations as a maintainer here? Maybe then we can put up an appropriate PR and get this behavior changed for the 44 commenters here.


Side note

The way maintainers are handling this issue is pretty sad, and I'm sorry @AubreyHewes but your responses here (may I presume you're a maintainer?) are just plain unprofessional and against the spirit of open source. There's no point in you telling others what solutions their use cases mandate, or whether their problems are valid.

This is only a problem if you think it is a problem or do not like the attribute *

That's like telling a sick person to just 🪄_imagine_✨ they're not sick anymore, then boom, they're not sick anymore. Clearly a critical mass of people a) believes this functionality is a problem; and/or b) does not like the attribute. Therefore it a) is a problem, and b) might be too opinionated for the purpose of this library.

I'm personally not in a position to contribute but I'd bet many people are. Maintainers, please (on behalf of your community) either fix this or coordinate with contributors to fix it. That's the entire point of being a maintainer of a popular library. Stewarding the library and facilitating the community's contributions.

@AubreyHewes
Copy link
Contributor

AubreyHewes commented Jul 28, 2021

@devinhalladay I am not a maintainer. Your issues are with a perceived issue of using this library. I have only ever proposed and described working solutions that possibly alleviate those issues. Possibly a bandage, but a working bandage without rewriting the complete core. That is also open source.

"To reiterate this is not actually really a problem with the library but the usage/expectation within other frameworks."

If you yourself have a simple solution please PR it, you will help all these people having this problem as well as yourself. That is open source.

A question I actually have for you is why you are still using this library? Most frameworks lift this work themselves.. So what are you using and what entailed such a detailed but wrongly attributed/detailed comment?

Side note: If you are not able to contribute to a library then there is no reason to explain how you can only complain

@devinhalladay
Copy link

Thank you @AubreyHewes that's clarifying and very valid! Apologies for coming in a bit hot.

@Lazy-C0der
Copy link

I am wondering if anybody has evidence that the data-react-helmet attribute is a detriment to SEO?

We are using react-helmet for SEO. We use it to insert content into the <title> tag, and manage other tags such as <link rel="canonical" href="...">, etc.

Our SEO consultant suspect that the attribute data-react-helmet may affect SEO negatively.

Since we are implementing an isomorphic application, removing the data-react-helmet attribute server-side (e.g. ${head.title.toString().replace(regExp, '')}) is not an option, because this will cause the element to be duplicated when the page is re-rendered client-side.

So I am considering working on a fork (or pull-request) which does not use the attribute data-react-helmet. But this will be a lot of work. And clearly according to W3C data-* attributes are allowed and should not cause any issue. So do the Google bots correctly ignore the data-* attributes when analysing the HTML?

react helmet is not for seo
for seo try react snap

@j-rp
Copy link

j-rp commented Sep 27, 2021

Reading over this recent conversation that @devinhalladay and @AubreyHewes had (and the lack of any further notes from the maintainers) seems to indicate that this project might not be actively maintained as before? Is that the case?

@KneePham
Copy link

the react helmet attribute does not work with twitter cards. Twitter is one of the biggest social media platform out there. And your team doesn't want to add a native way to disable them?

@j-rp
Copy link

j-rp commented Oct 28, 2021

@KneePham See my comment just above yours. This library looks to be dead.

@DesignByOnyx
Copy link

The problem is that this library literally cannot work if the attributes are removed (and I don't use the word "literally" very often). I've looked at the code and tried several tricks to get around this... to no avail. The authors are not going to repeat themselves again. It's not that they're unwilling/unable to change it - it's that they can't.

Your best bet is to use a post-build script to go through and remove the attributes from the compiled code. I provided examples of how to do this above.

@sanjaykamaruddin
Copy link

sanjaykamaruddin commented Oct 28, 2021

@KneePham Did you check if you have the correct Content-Type in the response header?

Twitter Cards should work with the Content-Type: text/html response header.

@KneePham
Copy link

@KneePham Did you check if you have the correct Content-Type in the response header?

Twitter Cards should work with the Content-Type: text/html response header.

I decided to give a test by creating a empty index.html file with just the twitter meta tags. Apparently it works with any sort of attributes including in the twitter meta tags when testing with the twitter validator. Including data-react-helmet="true".

So the issue might not be the attribute... but something entirely different?

There is definitely something weird going wrong with how the meta tags are being render with this library. or a combination with this library + react.

*Yes, I tried with the right content-type. Still doesn't work.

@sanjaykamaruddin
Copy link

sanjaykamaruddin commented Oct 28, 2021

Yup. It's not the data-react-helmet attribute that's tripping up Twitter.
Twitter renders the meta-information correctly for this URL even with the meta attributes.

@duythinh-dev
Copy link

duythinh-dev commented Nov 4, 2021

I need to help :(
Im making website https://www.hahalolo.com/tour
I setting all meta tags but when i check in developers.facebook.com/tools/debug it returns me results of website hahalolo.com

@Elius94
Copy link

Elius94 commented Mar 9, 2022

I think it's because this react plugin changes the index.html only if js is enabled... I suppose that the social engines that generates the preview reads only the "crude" index.js generated in the build process.

To bypass this trouble i've created this usefull npx command:

https://github.com/Elius94/seo-injector

Enjoy

@francesco-serialparts
Copy link

const Head = Helmet.rewind()
const regexp = / data-react-helmet="true"/g
const attr = Head.htmlAttributes.toString()

Hi, I am new in Gatsby. In what file you foresee to write this code. Thanks in advace

@zheeeng
Copy link

zheeeng commented May 17, 2024

Any progress on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests