I am working on a hybrid application in which login page is written in php and rest application is written on react. I want to implement google analytics for the same SPAs. I am pushing data layer in componentWillMount and my gtm script is being added via php code in index.php file.
The problem that I am facing is on first time and whenever page is transitioning from non-react to react pages, my GTM layer is not pushing data into gtm. if move with in react pages, everything is working fine.
Any help is highly appreciated.
Thanks
The problem you are facing is very common when using SPAs.
Let me give you an example:
When you move from https://digitalmarketingbloq.com to
https://digitalmarketingbloq.com/2018/08/07/how-to-filter-internal-traffic-in-google-analytics-with-google-tag-manager/
The browser communicates with the server. The page is being rendered
and GTM gets initiated.
In your example on the first-page view of
your SPA, it works fine because the communication with the server is established
. But in an SPA moving from one page to the other
happens, client side. Do GTM does not have anything to act upon.
How can you solve this?
The first option is to enable the built-in variables in the "History" (Variables > Configure > History) section:
Second, create a trigger (Triggers > New > History Change) that fires on all History changes:
In preview mode, you can check if your SPA pick up on history changes. Read more information about the variables here: https://support.google.com/tagmanager/answer/7182738?hl=en&ref_topic=7182737#history and about the trigger here https://support.google.com/tagmanager/answer/7679322?hl=en.
If that doesn't work you need to develop "virtual page view" events in the SPA when transitions are completed. Let me give you some more perspective. When a transition from page A to page B is completed fire the following event:
dataLayer.push({
'virtualPageTitle': 'My Login Screen',
'virtualPageURL': 'https://www.my-example/login',
'event': 'VirtualPageview'
});
The above will push virtualPageTitle and virtualPageURL to the dataLayer as and event VirtualPageview. GTM will be able to pick this up but you need to create 2 user-defined variables virtualPageTitle and virtualPageURL. The trigger will be VirtualPageview.
Hopefully, this clarifies things for you.
Related
Cypress not catching click event triggered hence API end points are not called for multiple containers.
It’s very difficult to explain issue, tried my best any hints are really appreciated.
I can’t share any application details.
I have a main UI application interacting with couple of backend components. API calls are made to endpoints with the same base URL but API containers are different based on component.
Manual Test steps;
Visit application url In main UI click search link
New tab/form (in same window) is opened which will interact with component 1
New tab is a form, fill in details and click verify button
2 API calls are triggered 1 : button click event success for container 1 2: API call to container 2
On successful 2 API call , page returns to main application page with search result details
In cypress runner for step 4 only 1 API call for container 1 is triggered with 200 success response.
Unfortunately second API call for container 2 was not triggered.
Asked developers about this, suggestion was cypress is not catching triggers, container 2 is not reachable from container 1.
I am stuck here, not sure what to search for or ask developers. Anyone noticed similar issue?
Not knowing much I can read you this quote from cypress.io
"Can I test anchor links that open in a new tab?
Cypress does not and may never have multi-tab support for various reasons.
Luckily there are lots of clear and safe workarounds that enable you to test this behavior in your application."
Maybe this could help: https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/testing-dom__tab-handling-links
hi am trying to setup rules in DTM.
Below is my setup - no page load rules
Custom Event based rule
Direct call rules within custom code of above event based rule.
My expectation is not to fire site catalyst call on custom event based rule but fire only with direct call rules.
Actual result is:
When page is loaded even before firing event based rule- I see a site catalyst call is made 'SATELLITE: Adobe Analytics: tracked page view' I am pretty sure this is coming from scode within DTM but I dont want that to happen rather al my calls should be from direct call rules
Any thoughts?
Add return false; to your custom page code within the tool setup. This will prevent the default page view from getting called.
There are a few ways to do this. The easiest is to configure the Adobe Analytics section your event-based rule to not send a request:
Adobe Analytics Section - tracking disabled
And then call the DC rule via a third-party JS tag in your rule:
_satellite.track('MY_RULE_NAME')
If for some reason you're firing a page view on event activity (using other rules in the property) you may consider setting a data element when your event-based rule triggers and then in your custom Adobe Analytics configuration abort the analytics call.
if(_satellite.getVar('MY_EVENT_BASED_RULE_FIRED')
{
s.abort = true;
}
Hope this helps.
Thanks for your valuable inputs!!
I could very much suppress the event based and other direct call rules but my major issue was to suppress the initial SC call with page load (happening from DTM library).
But I could achieve that based on the hostname - I am returning false when my first rule is event based rule.
I want to implement Google Analytics with enhanced ecommerce tracking using Tag Manager. I'm getting in a mess though, with either page views being tracked multiple times, or parts of the data not being tracked at all.
Rightly or wrongly, this is where I'm at so far:
A data layer initialized before any other script
<script>
tagManagerData = [];
</script>
Markup decorated with ecommerce information
<div class="productBox"
data-ga-product="impression"
data-product-id="#Model.Product.Id"
data-product-name="#Model.Product.Title"
data-product-price="#Model.Product.Price"
data-product-position="#Model.SequencePosition"
data-product-url="#Model.Product.RelativeUrl">
Javascript which populates the data layer
$('[data-ga-product="impression"]').each(function () {...});
and finally the Tag Manager script.
I can get everything to track if I have a trigger set up for each "push" (which is how I read the documentation) and Tag Manager script at the top of the page, but then I end up with something like 4 page views tracked per product detail page impression.
If I populate the datalayer and just have the default analytics "all pages" event run, stuff like products details will go over, but then "related product" impressions will not (I think because there ends up several ecommerce properties set in the datalayer?).
I've been working on this for 3 days and I'm getting in a complete mess and incredibly frustrated with the documentation.
You do not have to track each item as a single product, just add all of them into javascript array in predefined structure and send them in batch mode on pageview.
If you use each function, it will be loaded probably after document ready so if you have track pageview on .* in GTM, it will require some additional server call like event with non interaction flag, or you redefine Track pageview to some event emitted by you page after all data what you want to track are ready.
Summary:
Load all ecommerce data into JavaScript Object (https://developers.google.com/tag-manager/enhanced-ecommerce)
Set dataLayer.push({event:'manualEvent'});
in GTM create firing rule form manualEvent and Allow Enhanced Ecommerce in Tag configuration.
I am developing an application using websockets, with a fallback on ajax.
Most of the logic resides on the client side of the application, models, views, etc.
While developing I often need to make minor changes, and do a refresh. The way I do this is by a hard browser refresh, which basically restarts the whole application.
This can take some time, these are the steps:
get the index.html from the server
index.html loads all the javascript files
javascript creates the app and starts the websocket
on succesfull websocket connection the server will send the init data
the init data from the server is recieved by the client and the page is generated
In a normal situation this will be ok, because as soon as the app is loaded, there is no more refresh.
But this get's painfull while developing, so I thought of the following solution:
After I made my CSS changes, I run the following script:
softreset: function(){
var queryString = '?reload=' + new Date().getTime();
$('link[rel="stylesheet"]').each(function () {
this.href = this.href.replace(/\?.*|$/, queryString);
});
}
This resets all the CSS instantly, so I do not need to do a complete refresh. One step out the way.
Often times this is not enough, I also need new content, so I want to do the following:
question
I need to unload all the JS files on the page, except for the one that holds the websocket connection.
All the DOM elements, Objects, Events that are associated with these files need to be removed to.
I need to get the new JS files from the server.
Load them into the page, and fire the onload action
I tried working with the snippet I use for CSS, but it does not do the same trick. Anyone have an idea?
i think live.js may match your require partly
I am working on a MVC project that is supposed to have one page only, with two zones. On one zone I have a Google Map with markers, and the second zone is populated with the selected marker's details.
The details view has a button that when clicked should change the entire view into edit mode without refreshing the page or redirecting it. I have used two views, for details and edit and with the help of ajaxForm function I am switching back and forth between these two views. I'm adding the ajaxForm on documentready for edit view.
<script type="text/javascript">
// wait for the DOM to be loaded
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$('#currentDiv').ajaxForm(function(data) {
$('#currentDiv').html(data);
});
});
</script>
The problem appears when on server-side an error appears while trying to save data from edit view and I want to return to the same edit view with the errors displayed. The ajaxForm handler is not added any more and even if the new values that will try to be saved are ok, the detail view is loaded in another page.
Unfortunately, the use of ajaxForm creates some other problems because I don't have control over the cases when the ajax call fails.
Any ideas on how could I fix this? Is it some other solution to switch between those two views without using ajaxForm and without refreshing the page?
I think there are a couple of different questions that you are asking.
First off, you add jquery handlers to deal with the case when you get a 500 type error from the server.
Something like the following. I suggest taking a look at the docs for more info.
$(document).ajaxError(function(event,jqXHR,ajaxSettings,thrownError){
if (jqXHR.status != 0){
window.location = <error page>
}
}
The second problem seems to stem around error handling of known errors (say invalid input). In this case I suggest the following workflow.
1) User clicks on edit button, taken to edit screen
2) User enters in data, use client side validation to do initial check
3) User submits, user is then taken to the view screen and is shown a
success or error message.
The server response could look like:
public ActionResult Edit(EditModel model){
if (!ModelState.IsValid)
{
return Json(new {successful = false, message = "Failed.."});
}
...
}
On the client side, your form callback should now handle the message and the fact it was successful or not. In my implementation, I used knockoutjs to create a "message" area that I could update and clear. (I created templates, etc).
Remember to use client side validation for the easy field validation stuff.... This will save a trip back to the server.
Yours could be quite simple, by popping up the message returned from the server.
Lastly, document ready only fires when the original document is done loading, never again for an ajax call (at least that is my understanding). Just put that code that is the document.ready at the bottom of the edit page. It will fire after the html it is targeting has already been rendered.
Hope that helps!
I have begun to move away from the asp.net views available in ASP.Net MVC due to some incompatibilities and/or unnecessary complexities when trying to achieve functionalities expected of AJAX enabled sites of the day.
I would recommend moving towards a design where you use "dumb" HTML files, use jQuery to download them using AJAX and drop them into a container (personally I use a div) and then use another AJAX call to gather the data from a controller. There are a number of advantages to this approach:
It establishes a real (not fake) separation between client side and server side code.
Html files can be cached on the client cutting down on the amount of data transmitted.
Binding of the Html elements becomes a client side task achieved using jQuery offloading processing cycles from the server.
Controllers essentially become collections of web methods which means they can be untilized by iPhone and Android apps making mobile deployment easier.
I realize this probably isn't the exact answer you're looking for and this may not be an option for you but my hope is that it will help someone at some point make a decision to move away from mixing HTML and server side code.