segmentio / consent-manager

Drop-in consent management plugin for analytics.js
https://segmentio.github.io/consent-manager/
MIT License
341 stars 142 forks source link

Accessing globals through window.consentManager #276

Closed metalvegetarianoprogresivo closed 1 year ago

metalvegetarianoprogresivo commented 2 years ago

Accessing globals through window.consentManager

Recently we migrated from using the standalone script to use the NextJS component. We need to access window.consentManager and it is no longer available in the browser when using NextJS. This is needed for Google Tag Manager to check preferences and listen for a callback function window.consentManager.preferences.onPreferencesSaved.

Is there any recommended solution to allow window.consentManager to be available? Or is this something that NextJS version of the component won't allow us to do? Or this is not possible since we are using server side rendering?

Implementation

We are using the implementation of consent manager using NextJS like this:

const ConsentManagerComponent: FC = () => {
  return (
    <div className={css['container']}>
      <ConsentManager
        bannerBackgroundColor="#090909"
        bannerContent={bannerContent(isAbsoluteURL)}
        bannerSubContent={bannerSubContent}
        cancelDialogContent={cancelDialogContent}
        cancelDialogTitle={cancelDialogTitle}
        initialPreferences={preferences}
        otherWriteKeys={otherWriteKeys}
        preferencesDialogContent={preferencesDialogContent}
        preferencesDialogTemplate={preferencesDialogTemplate}
        preferencesDialogTitle={preferencesDialogTitle}
        shouldRequireConsent={shouldRequireConsent}
        writeKey={SEGMENT_WRITE_KEY}
      />
    </div>
  );
};

export default ConsentManagerComponent;

Next steps?

Is this something that is possible or should we return to the standalone script version?

edsonjab commented 2 years ago

Hi @metalvegetarianoprogresivo you need to add the script version on your project some like here

image

metalvegetarianoprogresivo commented 2 years ago

Hi @metalvegetarianoprogresivo you need to add the script version on your project some like here

image

Hi @edsonjab, we do have the script inserted in our codebase, but it seems that ´window.consentManager´ is not available.

edsonjab commented 2 years ago

Hey @metalvegetarianoprogresivo could you help me to share us your project configuration, please? or some example on codesandbox or a repo, to check in which place will be the issue, please

metalvegetarianoprogresivo commented 2 years ago

What exactly do we need to share for this? This is the how component on which we use consent manager:

import { ConsentManager } from '@segment/consent-manager';
import Script from 'next/script';
import React, { FC, useEffect, useState } from 'react';

import { SEGMENT_WRITE_KEY } from 'src/constants';
import inEUValidation from 'src/utils/browser';

import {
  bannerContent,
  bannerSubContent,
  cancelDialogContent,
  cancelDialogTitle,
  initialPreferences,
  initialPreferencesEU,
  otherWriteKeys,
  preferencesDialogContent,
  preferencesDialogTemplate,
  preferencesDialogTitle,
  shouldRequireConsent,
} from './config';
import css from './ConsentManager.module.scss';

const ConsentManagerComponent: FC = () => {
  const [ready, setReady] = useState(false);
  const [preferences, setPreferences] = useState({});

  useEffect(() => {
    const inEU = inEUValidation(window);
    setReady(true);
    setPreferences(inEU ? initialPreferencesEU : initialPreferences);
  }, []);

  if (!ready) {
    return null;
  }

  return (
    <>
      <Script
        dangerouslySetInnerHTML={{
          // eslint-disable-next-line @typescript-eslint/naming-convention
          __html: `
        !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)
        if(analytics.invoked)window.console&&console.error&&console.error('Segment snippet included twice.');
        else{analytics.invoked=!0;analytics.methods=['trackSubmit','trackClick','trackLink','trackForm',
        'pageview','identify','reset','group','track','ready','alias','debug','page','once','off','on',
        'addSourceMiddleware','addIntegrationMiddleware','setAnonymousId','addDestinationMiddleware'];
        analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);
        t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){
        var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){
        var t=document.createElement('script');t.type='text/javascript';t.async=!0;
        t.src='https://cdn.segment.com/analytics.js/v1/' + key + '/analytics.min.js';
        var n=document.getElementsByTagName('script')[0];n.parentNode.insertBefore(t,n);
        analytics._loadOptions=e};analytics._writeKey='${SEGMENT_WRITE_KEY}';analytics.SNIPPET_VERSION='4.15.2';
        }}();
        `,
        }}
        id="segment"
        strategy="afterInteractive"
      />
      <div className={css['container']}>
        <ConsentManager
          bannerBackgroundColor="#313441"
          bannerContent={bannerContent(isAbsoluteURL)}
          bannerSubContent={bannerSubContent}
          cancelDialogContent={cancelDialogContent}
          cancelDialogTitle={cancelDialogTitle}
          initialPreferences={preferences}
          otherWriteKeys={otherWriteKeys}
          preferencesDialogContent={preferencesDialogContent}
          preferencesDialogTemplate={preferencesDialogTemplate}
          preferencesDialogTitle={preferencesDialogTitle}
          shouldRequireConsent={shouldRequireConsent}
          writeKey={SEGMENT_WRITE_KEY}
        />
      </div>
    </>
  );
};

export default ConsentManagerComponent;
edsonjab commented 2 years ago

last question @metalvegetarianoprogresivo could you share me your NextJS version and consent-manager version, please?

metalvegetarianoprogresivo commented 2 years ago

@edsonjab Thanks for following up this issue 🎉 . NextJS version is 6.15.0 and consent-manager version is 5.4.0.

metalvegetarianoprogresivo commented 2 years ago

Any update on this @edsonjab ?

edsonjab commented 2 years ago

HI @metalvegetarianoprogresivo I'm build an example on codesanbox to share with you the configuration of the project

edsonjab commented 2 years ago

Hi @metalvegetarianoprogresivo I created this repo with an example how configure consent-manager with nextJs. I created a PR to fix the issue with the lodash library

metalvegetarianoprogresivo commented 2 years ago

Thanks @edsonjab I'm gonna take a look. Is it necessary to update the consent-manager to the latest version that has the lodash fix to make this work properly?

tekstrand commented 2 years ago

@edsonjab any news on that issue with lodash?

metalvegetarianoprogresivo commented 2 years ago

hi @edsonjab just asking again about this lodash issue we have now with consent-manager 5.6 on the example repo you shared, is there any workaround it?

tekstrand commented 2 years ago

@edsonjab any updates?

edsonjab commented 2 years ago

Hi @metalvegetarianoprogresivo @tekstrand we create a new PR to solve the issue with lodash library PR so, we will release a new version soon to solve this issue.

metalvegetarianoprogresivo commented 1 year ago

@edsonjab Hi, as far as version 5.7 of consent-manager we don't have access to the consentManager on the window, we require it to be available for google tag manager, is there any config we need to add for this to be available?

edsonjab commented 1 year ago

Hi @metalvegetarianoprogresivo I'm so sorry for the miss understanding, you can't access to consentManager on window with the library because is loaded like an application, on standalone version (like you can see on the next image) is loaded directly on the window when is configured the consent-manager

image

metalvegetarianoprogresivo commented 1 year ago

So, in this case, in order to have consentManager on window we need to use the standalone version of consent-manager?

edsonjab commented 1 year ago

yes, only works on standlaone version