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

Cannot read properties of undefined (reading 'addSourceMiddleware') #327

Closed jerturowetz closed 1 year ago

jerturowetz commented 1 year ago

Hi there, I'm reporting on the same issue mentioned in #207

analytics.ts:53 Uncaught TypeError: Cannot read properties of undefined (reading 'addSourceMiddleware')
    at co (analytics.ts:53:1)
    at index.tsx:219:1
    at _.setState (preact.module.js:1:8307)
    at n.handleSaveConsent [as saveConsent] (index.tsx:184:1)
    at onSave (container.tsx:108:1)
    at t.handleSubmit [as submit] (preference-dialog.tsx:51:1)
    at HTMLFormElement.P (preact.module.js:1:4016)

The readme states:

Breaking Changes: Version 5.0.0 and above require that your analytics.js snippet include the method addSourceMiddleware in the analytics.methods array

However, I am using the Standalone Script which doesn't seem to permit editing the analytics.methods array, or, at least, the docs don't indicate how.

My implementation is nearly identical to the example code:

<script>
window.consentManagerConfig = function(exports) {
    var React = exports.React
    var inEU = exports.inEU

    var bannerContent = React.createElement(
    'span',
    null,
    'We use cookies (and other similar technologies) to collect data to improve your experience on our site. By using our website, you՚re agreeing to the collection of data as described in our',
    ' ',
    React.createElement(
        'a',
        { href: '/docs/legal/website-data-collection-policy/', target: '_blank' },
        'Website Data Collection Policy'
    ),
    '.'
    )
    var bannerSubContent = 'You can change your preferences at any time.'
    var preferencesDialogTitle = 'Website Data Collection Preferences'
    var preferencesDialogContent =
    'We use data collected by cookies and JavaScript libraries to improve your browsing experience, analyze site traffic, deliver personalized advertisements, and increase the overall performance of our site.'
    var cancelDialogTitle = 'Are you sure you want to cancel?'
    var cancelDialogContent =
    'Your preferences have not been saved. By continuing to use our website, you՚re agreeing to our Website Data Collection Policy.'

    return {
        container: '#segment-consent-manager',
        writeKey: segmentGlobals.api,
        otherWriteKeys: segmentGlobals.otherWriteKeys,
        shouldRequireConsent: () => true, // Show up all the time for testing
        bannerContent: bannerContent,
        bannerSubContent: bannerSubContent,
        preferencesDialogTitle: preferencesDialogTitle,
        preferencesDialogContent: preferencesDialogContent,
        cancelDialogTitle: cancelDialogTitle,
        cancelDialogContent: cancelDialogContent
    }
  }
</script>

<script
  src="https://unpkg.com/@segment/consent-manager@5.3.0/standalone/consent-manager.js"
  defer
></script>

<div id="segment-consent-manager"></div>

I have validated that I am not loading analytics.js by any other means.

edsonjab commented 1 year ago

Hi @jerturowetz thank you for your report, we start looking into this.

edsonjab commented 1 year ago

Hi @jerturowetz you need add this code on the <head> element:


    <script>
      !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="YOUR_KEY";;analytics.SNIPPET_VERSION="4.15.3";
      analytics.load("YOUR_KEY");
      analytics.page();
      }}();
    </script>
jerturowetz commented 1 year ago

Hey @edsonjab

Doesn't including the following load segment on page load and not via the consent manager?

    analytics.load("YOUR_KEY");
    analytics.page();