Hubspotutk cookie in Angular 7 App


#1

Hi -- HS support directed me here. I hope someone can help!

We are embedding the HS tracking code in our Angular 7 app. According to the docs, we need the hubspotutk cookie to be set in order for the identity of the user to be established. But we don't understand how that cookie is set for our domain from the CTA links in the marketing email we use to drive users to the app.

Does anyone have any insight? Alternatively, is it possible to append an &email= parameter to the CTA link so that we can call the identify function in our code?

Here is the HS tracking code in our index.html:

    <script>
      var _hsq = window._hsq = window._hsq || [];
      // @see https://developers.hubspot.com/docs/methods/tracking_code_api/tracking_code_overview
      _hsq.push(['setPath', '/home']);
    </script>  
    <script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/1859609.js">
    </script>

Many thanks!


#3

HI @mflorence99 a cookie should be dropped into a user's browser when they land on a page with the tracking code. Is your application a single page app? If so, you'd want to use the setPagePath function, then call the trackPageView function one after the other. The trackPageView function has to be called after setPagePath or identify functions since setPagePath and Identify only store the data in the tracker. trackPageView actually passes the identity into HubSpot

If you're looking to use the identify function and get the email from a specific contact, you can't do this within a CTA, but you could with an anchor. If the contact's email is known, you could have an anchor like this within HubSpot:

<a href="https://www.test.com/?email={{contact.email}}">Click!</a>


Is it possible to append a &email= parameter to a CTA link?
#4

One other thing, can you also send me the Support case #? I'd love to close the loop with Support. Thanks!


#5

Hi @Connor_Barley! Many thanks for your reply, it was very helpful, especially the {{contact.email}} syntax. If all else fails, that could solve all our troubles.

The original support case # is 2099958.

We are an Angular 7 SPA and I was working from the docs starting at https://developers.hubspot.com/docs/methods/tracking_code_api/tracking_code_overview.

There are some things I don't understand though, if I may ask you. First, the docs refer to setPath which is what I am using, then trackPageView. Is setPath an alias for setPagePath?

Now, we are getting anonymous page view stats in HS for all the setPath/trackPageView invocations in the SPA. That's good. But we are not seeing anything on any contact's timeline, leading me to understand that the hubspotutk cookie is not set because the contact can't be identified.

Can you tell me how the cookie should be set?

Our CTA URLs look like this: https://info.appcast.io/e2t/big_long_encoded_string.

That URL redirects to this: https://appcast.io/recruitment-marketing-grader/?utm_medium=email&_hsenc=p2ANqtz-_ATR4eBFts0kdSa6Pj-w6wZZafpt7CjyUWx1D5ArcQX1IN67AQiEmAtV8jJBbhvQ7i-kD4M_5DfMNHGeBi62h6oFwjvg&_hsmi=2&utm_content=2&utm_source=hs_email&hsCtaTracking=10440190-0062-46f4-9452-18dae0f10aec|2494aa87-eecc-4a79-9244-cf279ad987cd

In turn, that URL redirects to this (via a 301): https://admin.appcast.cloud/recruitment-marketing-grader/home?utm_medium=email&_hsenc=p2ANqtz-_ATR4eBFts0kdSa6Pj-w6wZZafpt7CjyUWx1D5ArcQX1IN67AQiEmAtV8jJBbhvQ7i-kD4M_5DfMNHGeBi62h6oFwjvg&_hsmi=2&utm_content=2&utm_source=hs_email&hsCtaTracking=10440190-0062-46f4-9452-18dae0f10aec|2494aa87-eecc-4a79-9244-cf279ad987cd

What is going to set the hubspotutk cookie for the admin.appcast.cloud domain? Is that second redirect a problem?

Many thanks for all your help!


#6

Hi @mflorence99, whoops! Yes I apologize I meant to say setPath. For our purposes setPagePath === setPath. I'll refer to it properly from now on :laughing:!

The hubspotutk cookie is dropped into a visitor's browser once they load the page and the tracking code fires.

Your redirect shouldn't be an issue as long as the tracking code is also on the admin. subdomain

However, now that I look at things again you have email identity tracking (https://knowledge.hubspot.com/email-user-guide-v2/how-to-set-up-your-email-tracking) enabled here (https://app.hubspot.com/settings/1859609/marketing/email/tracking), so I would think you wouldn’t need the identify (https://developers.hubspot.com/docs/methods/tracking_code_api/identify_visitor) function or even the setPath and trackPageView functions since the URL of your SPA never changes.

Which email are you sending to contacts so that I can try to reproduce the behavior and see if my token gets associated with a contact record? Can you please link that email in this thread? Thanks!


#9

You bet @Connor_Barley and many thanks!

Here is the email we used to drive contacts to our Angular 7 SPA: https://app.hubspot.com/email/1859609/details/6406760335/recipients/clicked

BTW: Yes, the URL of the SPA doesn't change, but we wish to track users landing on several different routes within the SPA itself, hence the setPath/trackPageView invocations.


#10

Hello @Connor_Barley! We're still very interested in getting the hubspotutk cookie to work, as you have been helping me in this thread -- but we have temporarily deployed our Angular 7 SPA to look for an &email= query parameter and issue an appropriate identify call.

You can see that working on my test contact: https://app.hubspot.com/contacts/1859609/contact/14953901/?interaction=note

Is it now possible to generate a list of contacts based on which pages they have viewed?

Many thanks as always for your help!


#11

Hi @mflorence99, apologies for the delay. The holidays definitely disrupted my workflow. The hubspot utk is placed in the browser every time a visitor goes to a webpage with your tracking code on it. If the contact hadn't cleared their cookies, the same cookie will be placed in their browser. You should be able to grab the hutk by using the document.cookie object, and using a function to get the HubSpot cookie: https://stackoverflow.com/questions/252665/i-need-to-get-all-the-cookies-from-the-browser.

If you check out this screenshot, you'll see that cookies are being dropped into my browser from your tracking script: http://prntscr.com/lnca7k, so you should be able to use setPath and trackPageView to manually set the page path. Be aware that the trackPageView function won't work for any page paths that has fragments in them as per these docs: https://developers.hubspot.com/docs/methods/tracking_code_api/track_page_view


#12

Hello @Connor_Barley! I hope you had a great holiday and I really appreciate you keeping this thread going. If you need to drop out and pass the issue back to official support, I totally understand!

However, the issue is this: I see the cookie too in my tests, the problem is that it doesn't work in the sense that page views are not being recorded with any contact.

If I look at your record at https://app.hubspot.com/contacts/1859609/contact/15198451/?interaction=note for example, I don't see any page views, even though I can see from your screenshot that you hit our app yesterday.

I'm totally on board with the fact that I'm doing something wrong, but I just don't know what that could be! I'm issuing the setPath and trackPageView commands as documented. In fact, when I use the &email= parameter to feed the identify function, the page views are indeed recorded. Here's the code in my index.html:

    <script>
      var _hsq = window._hsq = window._hsq || [];
      // @see  https://developers.hubspot.com/docs/methods/tracking_code_api/identify_visitor
      function getURLParameterByName(name) {
        var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
        return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
      }
      if (getURLParameterByName('email'))
        _hsq.push(['identify', { email: getURLParameterByName('email') }]);
      // @see https://developers.hubspot.com/docs/methods/tracking_code_api/tracking_code_overview
      _hsq.push(['setPath', '/splash']);
    </script>  
    <script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/1859609.js">
    </script>

Note that the docs explicitly state:

Note: trackPageView is automatically called when the tracking code loads, so you should not push any trackPageView calls to _hsq before the page loads.

That's why you don't see a trackPageView call in the index.html. Anyway, as I say, that exact code does work if the identify call is made.

Your help is very gratefully received. We're getting a lot of pressure to get this working, as the marketing folks can't properly follow up on their campaigns with the new app.


#13

Hey @mflorence99, you're at the top of my list. I'm looping in some more members of my team here to get a better look a this. I completely see what you're talking about now. Thanks for your continued patience and I'll update you with what we find.


#14

Many thanks — I really appreciate your help!


#15

Hi @mflorence99, sorry about the delay on this. Was just working through this with my team and taking a look at your setup. I should've caught this, but it looks like the reason your app doesn't have tracking work without the identify call is because of the sanitization of your URL when clicking the CTA. When the CTA is clicked, HubSpot adds tracking parameters to the URL, most notably the hsenc parameter. This parameter needs to be present in the URL of the pageview that gets recorded in order for the cookie => vid association to happen.

So it seems like the redirect is the issue here if it's stripping out the hsenc parameter before the page actually loads and a page view gets recorded. You need to ensure that the query parameters (specifically hsenc but the others are required for source bucketing) get preserved during any redirects and gets included in the URL set by the setPath method for HubSpot's tracking code. If you do not wish to have those query parameters in your URL, and the identify method is working for you, I'd suggest continuing to use that method instead.


#16

Hi @Connor_Barley -- many thanks again for your help, but I'm afraid we are still at a dead end. Our redirect does not strip out any of the HS query parameters. We could see that from the notes I published in this thread on 11/17.

To try to show that, I just sent this test email to myself: https://app.hubspot.com/email/1859609/details/6406760335/recipients/clicked on behalf of this contact (just picked arbitrarily): https://app.hubspot.com/contacts/1859609/contact/7083351?interaction=note. I follow the CTA link in the test email and no page view activity is being recorded for that user.

To show that the query parameters are not being stripped, I used Chrome with the debugger activated to launch the CTA link. In the debugger Network tab, I set the "preserve log" checkbox. I hope you can see from the two attached screenshots that the _hsenc and all other query parameters are preserved in the redirect.

You or your team should be able to trace identical results.

PLEASE HELP! It may well be we are doing something wrong, but the marketing team is getting very concerned about making this work.

How can we escalate this issue to drive it to a solution?

ADDITIONAL NOTE: In the Chrome debugger, I can see hubspotutk being set in document.cookie. I can also see a tracking request to https://track.hubspot.com/__ptq.gif issued. In the URL, the &vl= query parameter is set to the same value as the cookie. But if I use the http://api.hubapi.com/contacts/v1/contact/utk/xxxx?hapikey=xxxx API to lookup the contact from the token, I get a 'new contact' page and not the intended contact.


#17

Hi @mflorence99, I sat down with a member of the product team and went over step by step walking through each step of the process to make sure we didn't miss anything. Here's what we did:

  1. Sent this email: https://app.hubspot.com/email/1859609/details/6642184476/performance, to myself.
  2. To make sure my IP address didn't get filtered since I was on HubSpot's corporate network, I used Opera and a VPN to visit your SPA. I saw the query parameters in the URL and in the Network tab this time - I must have been refreshing the page when I responded last, as when I do that in your SPA, the query params get removed.
  3. Continuing on, I do see a call to the https://track.hubspot.com/__ptq.gif URL with a k value = to 1 which is a page view. This means that the page is getting tracked, but when we go to my contact again, there's no data as we've seen. Looking further at that ptq event, it looks to be pushing this URL to the tracking code to be tracked: https://admin.appcast.cloud/recruitment-marketing-grader/home#/benchmark?utm_campaign=Campaign%2520-%2520Whitepaper%253A%2520Job%2520Description%2520%2526%2520Titles%2520&utm_medium=email&_hsenc=p2ANqtz-8NoRKNlFN57toJAvPuD6KkoUbbVG3eCOBIgeIKwqELPJmybuKbIRLSb4L8HNtDYRu4ewAc4y3ncAzfryUlkKUHiKgw4A&_hsmi=67889066&utm_content=67889066&utm_source=hs_email&hsCtaTracking=ef04a87c-7b99-4931-bfad-23b5e7c3e959%257C85d5cda6-7c78-4a77-b371-be5a9d24ea27.
  4. Putting the hsenc value into an internal decoding tool returned my own email address:

So we know that the event for tracking page views is being fired, and my email address is property included in the URL, so the only thing that this might point to is the order in which the URL shows up as, specifically, where the URL fragment/hash is.

When I use an internal tool that runs on the same service that we use to actually bucket URL's for page views on your SPA's URL, I get an incorrect bucketing:

Your URL is getting bucketed as Direct Traffic, without it picking up on any query parameters as you can see from the urlParams parameter.

When I remove the # entirely from the URL, we get the correct bucketing:

This points to the fact that the issue lies in the URL and where the # is getting placed. As a matter of fact, it looks like in RFC 3986 here: https://tools.ietf.org/html/rfc3986#section-4.1, that the structure of URLs have to be query parameter > then hash, rather than the other way around.

I'd recommend testing to see if moving the fragment to the end of the URL fixes the issue, as we think that this is the root cause.


#18

Hi @Connor_Barley -- thank you very much again for all your help. I am very sorry this is so painful. Please let me know what I can do to make it easier! Sadly though it is still not working.

I rebuilt and redeployed our Angular 7 SPA to use URL paths rather than fragments for routing, to avoid any of the issues that you raised. However, page view activity was still not observed. I have attached a screenshot to show the state of play at the time the request to https://track.hubspot.com/__ptq.gif was issued. You can see that the URL is formatted as you suggested.

I also question your theory that the URL was the culprit in the first place. Surely the _hsenc parameter has been decoded parsed already -- by the client-side tracking code and before the __ptq.gif call is made. That's how the a parameter is populated with our site ID and the vl parameter with the value of the hubspotutk cookie. The original URL is passed in the pu parameter but sure only to be recorded and not for the its query parameters to be further parsed. In any event, even when formatted without a # bookmark, the code still does not work.


#19

Hey @mflorence99, it's late and haven't tried looking into your reply fully yet, but can you try removing any setPath call? If you're setting the path manually, I believe those query parameters have to be included. If you aren't setting the page path manually, the query parameters will be included automatically when the page loads, but if you do set it manually, those parameters are left off since the tracking code uses your manual call over the actual URL. This could very well be what's happening here. Can you try removing that call to setPath?


#20

I will try that first thing @connor_barley but please take a look at my note tomorrow as I am not sure we are on the right track. Plus your theory would not explain why the setPath works perfectly - if I call identify first with an email address. And in that case none of the URL parameters are present.


#21

Got it. The identify function works because you're manually setting the path and explicitly identifying the contact. You shouldn't need that, though since you're sending an email to contacts who click a CTA to get to the SPA. The tracking code should know the identity of the contact and should therefore be recording page views. Ill look for a reply tomorrow from you.


#22

@Connor_Barley I rebuilt and redeployed without the initial setPath as you suggested, but it made no difference.


#23

hey @mflorence99 alright I am sure we are getting very close. I just tested the following in my own portal and could actively reproduce the behavior you are seeing. I went to a webpage of mine, and added the following code:

<script>
   var _hsq = window._hsq = window._hsq || [];
   _hsq.push(["setPath", "/splash"])
</script>

I then went through the same flow that your customers went through by sending myself an email that linked to the page that should be tracking views. I confirmed that the tracking code fired and registered a page view event by checking the call to the _ptq link, with a k value of 1 (page view), then put the _hsenc param into a decoder and confirmed that it was my email address that was being decoded. Here's what my Network tab looked like when checking out the ptq link:

You can see that po is set to /splash, which is what I manually set. This did not record any page view activities onto my contact record in HubSpot. I then manually added in those query parameters to the setPath function like this:

<script>
	var _hsq = window._hsq = window._hsq || [];
	_hsq.push(['setPath', '/splash?utm_source=hs_email&utm_medium=email&utm_content=2&_hsenc=p2ANqtz-_DkWbWKxp-hfB-TbAXP7GHqGwOlLxZwBj92yJsF5h6ljoRwCHt29rl0Jr3F9bXYy4oGoLUmP1knZM4S-15iLlN3y4K7w&_hsmi=2'])
</script> 

and was able to get page views!

Here's what my network tab looked like:

If you add in the query params during your setPath function, this should work. At the moment, I'm seeing that po on your page is set to /main. I'd recommend making sure to set it to the URL you'd like with all your UTM parameters (in hubspot they'll just get stripped out when viewing a contact record so it won't show a long string), or just don't call the setPath function on the initial page load, so that the initial tracking will default to the normal URL.