react-helmet icon indicating copy to clipboard operation
react-helmet copied to clipboard

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

Open ghost opened this issue 9 years ago • 69 comments

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

any suggestions? thanks

ghost avatar Dec 02 '15 21:12 ghost

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?

cwelch5 avatar Dec 03 '15 19:12 cwelch5

@cwelch5 Having such an option would be cool

pavelkornev avatar May 11 '16 14:05 pavelkornev

Still nothing?

janoist1 avatar Aug 03 '16 15:08 janoist1

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

dergachevm avatar Dec 06 '16 04:12 dergachevm

@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, '')

svagi avatar Dec 06 '16 09:12 svagi

@svagi Thank you

dergachevm avatar Dec 12 '16 09:12 dergachevm

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.

huygn avatar Dec 21 '16 10:12 huygn

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.

staylor avatar Feb 24 '17 17:02 staylor

@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.

gajus avatar May 08 '17 14:05 gajus

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?

ncochard avatar May 31 '17 17:05 ncochard

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

jfuchs avatar May 31 '17 22:05 jfuchs

Please. 🙏

shahkashani avatar Jun 01 '17 17:06 shahkashani

+1 This is affecting Google's AMP pages

hugmanrique avatar Aug 10 '17 20:08 hugmanrique

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

esbb48 avatar Aug 18 '17 10:08 esbb48

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>

jcdarwin avatar Sep 05 '17 04:09 jcdarwin

It affects the Facebook open graph...

calpa avatar Nov 08 '17 00:11 calpa

Same problem here for Twitter Cards

elrumordelaluz avatar Nov 10 '17 16:11 elrumordelaluz

any updates on this one?

spiral2k avatar Nov 29 '17 01:11 spiral2k

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.

adam-26 avatar Dec 14 '17 23:12 adam-26

Any updates on this?

priteshpoddar avatar Feb 09 '18 07:02 priteshpoddar

Any news on this?

milotindragos avatar Mar 13 '18 00:03 milotindragos

data-react-helmet is annoying

ghost avatar Apr 12 '18 03:04 ghost

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...

RobsonAraujo avatar Apr 17 '18 17:04 RobsonAraujo

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

championshuttler avatar May 07 '18 19:05 championshuttler

+1

flavioalves avatar Jun 03 '18 06:06 flavioalves

+1

taze-fullstack avatar Jun 05 '18 04:06 taze-fullstack

As this issue is pretty old, there are lots of people subscribed to it through email. We would appreciate if instead of adding +1 comments you used the reactions feature.

hugmanrique avatar Jun 06 '18 18:06 hugmanrique

+1.

Using this as workaround and feel bad about it.

/**
 * Regular expression used in `removeAdditionalHelmetAttributes`. 
 * @type {RegExp}
 */
const ATTRIBUTE_REGEXP = / data-react-helmet="true"/g;

/**
 * Removes "data-react-helmet" attributes from generated HTML, as it
 * cannot be currently disabled.
 * @method removeAdditionalHelmetProps
 * @see https://github.com/nfl/react-helmet/issues/79
 * @param {Object} helmet
 * @return {Object}
 * @private
 */
const removeAdditionalHelmetAttributes = (helmet) => {
  return Object.keys(helmet).reduce((previous, acc) => {
    const handler = helmet[acc];
    const _toString = handler.toString;
    const toString = () => _toString.call(handler).replace(ATTRIBUTE_REGEXP, '');

    return {
      ...previous,
      [acc]: { ...handler, toString },
    };
  }, {});
};

// In your middleware:

/**
 * Collect properties for Helmet after rendering.
 * @type {Object}
 */
const helmet = removeAdditionalHelmetAttributes(Helmet.rewind());

cmtt avatar Jul 13 '18 10:07 cmtt

react-head might be an interesting alternative, haven't tried it myself, yet, but it uses React Portals and says it's SSR ready. Medium article

Still didn't had the time to test it yet, example app won't install, and the code mentions data-rh attribute, so…

CanRau avatar Jul 14 '18 01:07 CanRau

+1

outofthisworld avatar Aug 28 '18 16:08 outofthisworld