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

TypeError: tag[primaryAttributeKey].toLowerCase is not a function with external scripts in reactjs without gatsby

Open Way-U-Need opened this issue 5 years ago • 11 comments

please help me out from this error: `TypeError: tag[primaryAttributeKey].toLowerCase is not a function (anonymous function) node_modules/react-helmet/lib/HelmetUtils.js:141 138 | return false; 139 | } 140 |

141 | var value = tag[primaryAttributeKey].toLowerCase(); | ^ 142 | 143 | if (!approvedSeenTags[primaryAttributeKey]) { 144 | approvedSeenTags[primaryAttributeKey] = {};`

used external javascripts for some animations and css change.

code : import inspinia from "./assets/js/inspinia" class App extends Component { render() { return ( <> <Helmet> <script src={inspinia} type="text/javascript" /> </Helmet>

Way-U-Need avatar Mar 18 '19 12:03 Way-U-Need

I have a similar issue and when looking at what is happening there seems to be an issue w/ an array:

on a console.log

tag, primaryAttributeKey =  { innerHTML: [ 'window.__INITIAL_STATE__ = ', ';' ] } innerHTML

So the primaryAttributeKey is innerHTML, which exists, but that value is an array.

I have the following test setup

 <Helmet>
     <script>
         window.__INITIAL_STATE__ = {};
      </script>
  </Helmet>

I'm able to get this working if I use:

<Helmet script={[{
  type: 'text/javascript',
  innerHTML: `window.__INITIAL_STATE__ = Object.assign(window.__INITIAL_STATE__ || {}, ${someState})`

but I have a further problem w/ this that I actually get two rendered script tags, one for when there's no "someState" and one for after there is someState. :/

fricke avatar Apr 07 '19 05:04 fricke

@Way-U-Need What version are you using?

tmbtech avatar May 02 '19 16:05 tmbtech

It's happened with Helmet 5.2.1 and Webpack 4.39.1 in my case. It not happened with Webpack 3.12

biker9 avatar Aug 08 '19 19:08 biker9

Also got this issue, using 5.2.1 and the following code, on a Gatsby app:

import React from 'react';
import Helmet from 'react-helmet';
import { AppLocale } from '../appTypes';

// prettier-ignore
const FrontLocaleRedirectionScript = ({ locale }: { locale: AppLocale }) => {
  return (
    <Helmet>
      <script type="text/javascript">
        alert("page locale = " + {locale});
      </script>
    </Helmet>
  );
};

export default FrontLocaleRedirectionScript;

TypeError: tag[primaryAttributeKey].toLowerCase is not a function

  • HelmetUtils.js:121

slorber avatar Nov 14 '19 12:11 slorber

On my side I'm running into this issue too. Giving a little bit more context

Currently my team is on a major dependency upgrade and we run into this issue when upgrade the file-loader from v4.3.0 to v5.0.2.

febeck avatar Dec 12 '19 18:12 febeck

In case anyone else is still running into this issue...If you use v5 of file-loader, you're going to have to set {options: { esModule: false } } for file-loader in your webpack config.

Due to defaulting to esModule for file-loader in v5, commonJS exports are now being exported as objects with a default property for compatibility with esModules. For HelmetJS, it means that the href and src attributes for links (tag[primaryAttributeKey]) are being exported as { default: '/link-href' } instead of '/link-href'.

For more on the general discussion around compatibility you can check out the thread here https://github.com/webpack/webpack/issues/4742

kembly avatar Jan 04 '20 20:01 kembly

@kembly hi there ! Can't make it work.

Tried adding as stipulated in gatsby-node.js

exports.onCreateWebpackConfig = ({
  stage,
  rules,
  loaders,
  plugins,
  actions,
}) => {
  actions.setWebpackConfig({
    module: {
      rules: [
        {
          use: [
            {
              loader: "file-loader",
              options: {
                esModule: false,
              },
            },
          ],
        },
      ],
    },
  })
}

but throws me this

ERROR 

There was an error compiling the html.js component for the development server.

See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html TypeError: htmlComponentRenderer.default is not a function

  TypeError: htmlComponentRenderer.default is not a function

Any help would be appreaciated. For me it's the AMP Boilerplate code that is causing this.

pmarxbraun avatar Apr 22 '20 08:04 pmarxbraun

I managed to get round it by not using JSX - this code takes an inlined link or script node, and renders it in the head instead of the body:

const childrenAsString = (node) => {
  return (node.children || [])
            .map((ch) => (ch || {}).data)
            .filter(Boolean)
            .join('\n');
};

const HeaderScript = ({ node }) => {
  const innerHTML = node.attribs.src ? null : childrenAsString(node);

  return (
    <Helmet>
      { React.createElement(node.type, { innerHTML, ...node.attribs }, null) }
    </Helmet>
  );
};

benkitzelman avatar Sep 22 '20 23:09 benkitzelman

Just ran into this error while trying to give 2 strings to a style tag, fixed it by making it one string. It makes sense too, because an array of children doesn't have a function toLowerCase. If you look at the docs, you'll see how they suggest doing it as well:

    {/* inline script elements */}
    <script type="application/ld+json">{`
        {
            "@context": "http://schema.org"
        }
    `}</script>

    {/* noscript elements */}
    <noscript>{`
        <link rel="stylesheet" type="text/css" href="foo.css" />
    `}</noscript>

    {/* inline style elements */}
    <style type="text/css">{`
        body {
            background-color: blue;
        }

        p {
            font-size: 12px;
        }
    `}</style>

Note that each of the style, script and noscript contents is a single string, Helmet only assumes that to be the type of the children

JaffParker avatar Oct 15 '20 14:10 JaffParker

Just ran into this issue with an app bootstrapped with create-react-app 4 with --template typescript. In my case, I solved it by manually pointing to the default export from my file.

<Helmet>
    <link
        rel="icon"
        type="image/png"
        sizes="32x32"
        href={require(file)}
        data-react-helmet="true"
    />
<Helmet/>

Will not work, as @kembly pointed, the import points at {default:'/link'} as opposed to just /link. You can modify the webpack config (in my case with react-rewired or something), or just switch to require(file).default manually, as I did.

arslnb avatar Mar 30 '21 14:03 arslnb

I got the error, trying:

Fix:

  <script
    type="application/ld+json"
    dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
  />;

lacdael avatar Apr 19 '21 07:04 lacdael