holidaycheck/react-google-tag-manager

Fix noScriptAsReact

Opened this issue · 7 comments

Here is, at least in my opinion, a cleaner way to write the google tag manager component:

import React, {Fragment} from "react";
import ReactDOM from "react-dom";
import PropTypes from "prop-types";
import gtmParts from "react-google-tag-manager";

const GoogleTagManager = ({gtmId, dataLayerName, events, previewVariables}) => {
  const gtm = gtmParts({id: gtmId, dataLayerName, events, previewVariables});

  const gtmNode = !window[dataLayerName]
    ? ReactDOM.createPortal(gtm.scriptAsReact(), document.head)
    : undefined;

  return (
    <Fragment>
      {gtmNode}
      {gtm.noScriptAsReact()}
    </Fragment>
  );
};

GoogleTagManager.propTypes = {
  gtmId: PropTypes.string.isRequired,
  dataLayerName: PropTypes.string,
  events: PropTypes.shape(),
  previewVariables: PropTypes.string,
};
GoogleTagManager.defaultProps = {
  dataLayerName: "dataLayer",
  events: {},
  previewVariables: "",
};

export default GoogleTagManager;

It would work if your scriptAsReact() method returned the javascript code as-is instead of a string which script content need to be retrieved and eval() (ie in the code above, replacing gtm.scriptAsReact() by the script would work fine).
Would you mind adapting the method, or simply add another one to the GtmParts that'll only return the js code ?

Note that Google Tag Manager documentation recommends to set the script in the head element, not the body, which is why I'm using Fragment.

i tried it this way, the scripts appears in the right places in the haed and body, but no event was firing from GTM and the debug console wasn't showing

@abbeyseto works fine for me. Did you click on the "Preview" button from your Tag manager workspace ? The debug pane won't show without it (as far as I understand)

@Fandekasp thanks for suggesting the cleaner way. Can you tell how is data passed to data layer. Looks like right now the component only accepts the datalayer name and events etc. But how to pass data to data layer? Using additionalEvents?

@hhsadiq are you asking about how to use GTM ? You want to read the documentation: https://developers.google.com/tag-manager/devguide#events

@Fandekasp Actually I am asking how to reference the data layer object. In google documentation they use dataLayer.push({...}), so it means that by including this package, the dataLayer object will be available in window. And to push data in dataLayer from non-render sections (lifecycle hooks, handlers, or stores etc) we should use window.dataLayer.push()?

It also means that your above suggested component will most probably be used once (if we are to use one data layer). And rest of the times we just reference the window.dataLayer, given that GTM is correctly loaded. Right?

Awesome, thanks for the prompt reply.