Creating CTA button via embed code does not track clicks


#1

In our Vue.js app, we've create a component, which we pass the CTA link, and this component will create the element and load the CTA scripts, includint the hbspt.cta.load.

We can see the views in our CTA analytics but we can't see the number of clicks. Is there anythine else we have to do?

Below I have an example of our component:

<template lang="pug">
a(:class="buttonClass",
  :href="hubspotCtaHref",
  :target="target",
  :title="title")

  i.el-icon.m-r-10(v-if="icon", :class="`el-${icon}`")
  span(v-if="!$slots.default", style="margin-left: 0")
    | {{ text }}
  slot
</template>

<script>
export default {
  name: 'HubspotCtaButton',
  components: {
    Animation,
  },
  props: {
    text: {
      type: String,
      default: 'Save',
    },
   buttonClass: {
      type: String,
      default: '',
    },
    title: {
      type: String,
      default: '',
    },
    target: {
      type: String,
      default: '_blank',
    },
    icon: {
      type: String,
      default: '',
    },
    hubspotCtaHref: {
      type: String,
      required: true,
      default: '',
    },
    hubspotCtaOptions: {
      type: Object,
      default: () => ({}),
    },
  },
  mounted() {
    // We get the params from the link (so it's easier for the user)
    // The CTA link should look like:
    // https://cta-redirect.hubspot.com/cta/redirect/2853558/caccc178-4b51-40e6-9b18-6f1f53281a60
    const fragments = this.hubspotCtaHref.split('/');
    $.getScript('https://js.hscta.net/cta/current.js', () => {
      window.hbspt.cta.load(Number(fragments[5]), fragments[6], this.hubspotCtaOptions || {});
    });
  },
};

#3

Hi, @Raphael_Arias.

To be transparent, I have never heard of this being done before. Furthermore, I'm not completely certain that it's possible to fully replicate a HubSpot CTA's functionality in a custom Vue.js component.

As I understand it and as David outlines in this topic, CTA clicks are tracked through a redirect server. I believe this is what you're going for with:

https://cta-redirect.hubspot.com/cta/redirect/2853558/caccc178-4b51-40e6-9b18-6f1f53281a60

While the URL above does lead to your landing page, I've noticed some key differences between your redirect's behavior and a "real" HubSpot CTA on one of my own landing pages:

  • Yours is a meta redirect while an embedded HubSpot CTA uses a 301 redirect.
  • Your redirect URL is https://cta-redirect.hubspot.com/cta/redirect/ while a true HubSpot CTA goes through https://cms2.hubspot.com/ctas/v2/public/cs/c/.
  • Your redirect URL contains no query parameters while mine passes the following: cta_guid, placement_guid, portal_id, canon, redirect_url, click, hsutk, utm_referrer, pageId, __hstc, __hssc, and __hsfp. (The parameter which really jumps out is click, which may be how our CTAs count clicks.)

How did you decide on using https://cta-redirect.hubspot.com/cta/redirect as the redirect URL? (As opposed to, https://cms2.hubspot.com/ctas/v2/public/cs/c/, for example.)

Again, I can't guarantee that I'll be able to help you get everything working identically to a native HubSpot CTA, but I'm happy to explore potential options!


#4

Hello @Isaac_Takushi.

Thanks for your reply! We decided to use the CTAs like that for these reasons:

  • Our marketing team can create the CTA (and control the link) without asking the dev team;
  • Our marketing team can just give the dev team the link, and the system will do the rest;
  • Due to the fact we load them dynamically, we thought that would be useful to abstract the CTA API;
  • The image generated from Hubspot is low resolution and we don't really need it.

That's strange, the fact your URL looks different than ours. We got this link from the embed code:

<!--HubSpot Call-to-Action Code --><span class="hs-cta-wrapper" id="hs-cta-wrapper-caccc178-4b51-40e6-9b18-6f1f53281a60"><span class="hs-cta-node hs-cta-caccc178-4b51-40e6-9b18-6f1f53281a60" id="hs-cta-caccc178-4b51-40e6-9b18-6f1f53281a60"><!--[if lte IE 8]><div id="hs-cta-ie-element"></div><![endif]--><a href="https://cta-redirect.hubspot.com/cta/redirect/2853558/caccc178-4b51-40e6-9b18-6f1f53281a60"  target="_blank" ><img class="hs-cta-img" id="hs-cta-img-caccc178-4b51-40e6-9b18-6f1f53281a60" style="border-width:0px;" src="https://no-cache.hubspot.com/cta/default/2853558/caccc178-4b51-40e6-9b18-6f1f53281a60.png"  alt="See all EducationLink features"/></a></span><script charset="utf-8" src="https://js.hscta.net/cta/current.js"></script><script type="text/javascript"> hbspt.cta.load(2853558, 'caccc178-4b51-40e6-9b18-6f1f53281a60', {}); </script></span><!-- end HubSpot Call-to-Action Code -->

We haven't used any redirect or any changes were made to the link. We use the link Hubspot "gave us", so I'm not sure why the redirect is 301 or if it's not supposed to be like that. Indeed, the link currently does not have the parameters. But I figured that it should work by itself right? Because these links are used in emails, with no support for Javascript.

We tried not to change anything, and load/execute the script as it would if we were embedding the script tags. That's why I think it's strange that the views work (probably the JS being executed) but the click tracking doesn't.

Where did you get the link you sent to me from?

Thank you for your help!


#6

@Isaac_Takushi

Would you have a clue what is happening? Any help is appreciated. :slight_smile:


#7

Hey, @Raphael_Arias.

Apologies for the delayed response while I checked with the product team which owns CTAs.

Unfortunately, I won't be able to guide you any further toward your goal.

While the lack of click tracking is due at least in part to the fact that you aren't passing a click parameter and value to the click tracking domain cms2.hubspot.com/ctas/v2, I haven't learned specific implementation steps. (To your previous question, though, I found that domain by testing a CTA embedded on my own website.)

Here's the official word from the CTA team:

"At the moment, the CTA tool has no open APIs and doesn't support embed code customization, let alone custom-built CTAs. While attempting to build a CTA isn't against our terms of service, if the customer decides they wish to customize it, it's up to them to figure out and is something [our team] would be very much against as it's likely to break at some stage."

As you can see, my hands are a bit tied... I can't offer additional steps or condone building custom CTAs with Vue.js using the HubSpot scripts.


#8

Hello @Isaac_Takushi.

Thanks for your reply. I don't understand then why I have different URL structure in my embed code (generated by Hubspot).

I have just tried embedding the code provided by Hubspot and it does not change the URL, does not send any parameter, nothing.

Let's say I don't want to customise the CTA's API. Why my unchanged embed code of a CTA does not track clicks?

This is the request it triggered when I clicked on it in my website. Just the normal embed code. The URL is totally different than the one you showed me. I can see that when added to Hubspot emails, the URL is yet different (possibly like yours), but the embed code is this one.

So my question would be, why the embed code does not track clicks?

Could you help me with that?


#9

P.S.: I basically followed this guide: https://knowledge.hubspot.com/cta-user-guide-v2/how-to-add-a-call-to-action-cta-to-a-non-hubspot-page

Note that this guide's URL is the same as mine.


#10

P.S. I changed the title to better reflect what we are trying to achieve. :slight_smile:


#11

Done, fixed!

For future reference:

Hubspot provides a "temp" URL in case the script does not run, this URL will redirect the user to the final URL, but will not track the click (!?), probably due to back end limitation due to the lack of more information. Don't know.

When added to the page, the script may not be executed, that's what threw me off in the beginning.
Furthermore, the script needs the wrapping tags with the same tags and ids.

So, here's my final component, working like a charm:

Evidence (note the URL has changed to the script):

<!-- Cta button -->

<template lang="pug">
span.hs-cta-wrapper(:id="`hs-cta-wrapper-${urlComponents[6]}`")
  span.hs-cta-node(:class="`hs-cta-${urlComponents[6]}`",
                  :id="`hs-cta-${urlComponents[6]}`")
    a(:class="buttonClass",
      :href="hubspotCtaHref",
      :target="target",
      :title="title")

      i.el-icon.m-r-10(v-if="icon", :class="`el-${icon}`")
      span(v-if="!$slots.default", style="margin-left: 0")
        | {{ text }}
      slot
</template>

<script>
export default {
  name: 'HubspotCtaButton',
  props: {
    text: {
      type: String,
      default: 'Save',
    },
    buttonClass: {
      type: String,
      default: '',
    },
    title: {
      type: String,
      default: '',
    },
    target: {
      type: String,
      default: '_blank',
    },
    icon: {
      type: String,
      default: '',
    },
    hubspotCtaHref: {
      type: String,
      required: true,
      default: '',
    },
    hubspotCtaOptions: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      urlComponents: this.hubspotCtaHref.split('/'),
    };
  },
  mounted() {
    // We get the params from the link (so it's easier for the user)
    // The CTA link should look like:
    // https://cta-redirect.hubspot.com/cta/redirect/2853558/caccc178-4b51-40e6-9b18-6f1f53281a60

    // If CTA load code is already present we don't need to add the script again
    if (window.hbspt && window.hbspt.cta && window.hbspt.cta.load) {
      this.loadCta();

      return;
    }

    $.getScript('https://js.hscta.net/cta/current.js', () => {
      this.loadCta();
    });
  },
  methods: {
    loadCta() {
      // Add Hubspot special parameters (it will end up changing the URL);
      window.hbspt.cta.load(Number(this.urlComponents[5]), this.urlComponents[6], this.hubspotCtaOptions || {});
    },
  },
};
</script>

P.S.: Hubspot's CTA script is very intrusive in the sense it will replace all classes and text from the DOM. I haven't tested the use of icon or slots with the link (so not sure if this part of the component is working).

P.S.: It's a shame that the CTA product team, didn't want to help.

@Isaac_Takushi Thank you very much for your support!

Thanks!


#12

This is so impressive, @Raphael_Arias! Yeah, apologies I couldn't be of more assistance, but I'm thrilled to hear you got this up and running!