Adding google analytics code on ajax calls - gtag.js

I have added google analytics code on my site. It's working fine.
I want to add it on a particular ajax call.
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-220192-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '--my--GTAG--Number');
</script>
How can I trigger that so that I can add it and see on backend that that a particular ajax call has been hit?

Related

Google tag seems to be installed, but gtag not defined

I have gtag installed in the head, script copypasted from Analytics basically (it's pug)
script(async src="https://www.googletagmanager.com/gtag/js?id=" + id).
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', '#{id}');
I see google tag console output, dozens of lines (would love to get rid of it, but don't know how yet)
But when I try to trigger an event, or to get clientId with gtag() function, I get Uncaught ReferenceError: gtag is not defined
If tag is installed - why do I get the error? If not - why do I have those logs? And how do I fix this?

Network Error when click <nuxt-link/> in NUXT?

Network error when click <nuxt-link/>,
this is my error details, but when i refresh the link, everything is good ? why ?
this is my entire code ,...
<template>
<div>
<nuxt-child/>
<h1>Videos</h1>
<div v-for="video in $store.state.videos" :key="video.id">
<nuxt-link :to="`/videos/${video.id}`">{{ video.customerName }}</nuxt-link>
</div>
</div>
</template>
<script>
export default {
head:{
title: 'Customer List'
},
async fetch({$axios, store}) {
let response = await $axios.get('/customers');
let videos = response.data;
store.commit('SET_VIDEOS', videos);
},
}
</script>
<style lang="scss" scoped>
</style>````
Your API request is cross-origin as localhost:3000 differs from localhost:8000
Your API needs to respond to the request on /api/customers with a header of Access-Control-Allow-Origin: *. This enables the API to be called from any origin page. Ideally in the future you would want to replace this "wildcard" * with the actual origin but for testing this is fine.
I assume your API is an Express one, in this case adding this to your application would force all requests to utilise a wildcard CORS:
// Set middlware
app.use(function (req, res, next) {
// URL of website to allow or a wildcard
res.setHeader('Access-Control-Allow-Origin', '*');
// Continue to next layer of request/middleware
next();
});
Alternatively you could also set the origin to http://localhost:8000
As a side note, in your example code I see you are using the Vuex store and have a method to make the API call before committing to the store.
If you ever plan on repeating this API call on another component, it would be advised to turn your function into an action within the Vuex store so it is in one central, reusable place.

Google SignIn2 won't call the onsuccess callback

I put a google signin button on my page using the "gapi.signin2.render" function. To this function I pass an object with the onsuccess handler.
When the user initially clicks on the button everything works as expected. The google signin popup appears. But after finishing the signin process nothing happens on my page.
After refreshing the page, the button triggers the auth process again. And as soon as the "Signed In" appears, the onsuccess handler gets called.
I looked at the network traffic and saw a response containing all the information. That means that everything should be configured correctly in the google console. Otherwise I wouldn't get the response, right?
This is my vue component:
<template>
...
<div id="google-signin-button" class="g-signin2"></div>
...
</template>
<script>
...
window.gapi.signin2.render('google-signin-button', {
onsuccess: this.onSignIn,
})
...
onSignIn: function(googleUser) { }
<script>
This is the index.html:
<meta name="google-signin-client_id" content="xxx.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
What can I do to get the onsuccess handler called on the initial signin?
Ok, i found it. Unfortunately i misunderstood the official documentation.
I had to load the auth2 module first:
window.gapi.load('auth2', () => {
window.gapi.signin2.render('google-signin-button', {
onsuccess: this.onSignIn,
})
})

Use Facebook Instant Games CDN in Vue project - Webpack

I want to make a Facebook Instant game with Vue. But facebook just has a cdn for the js file.
<script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>
If I import the cdn in index file I still cannot use it in the components. Vue shows undefined error.
I tried to import it in index.js just after body tag and initialize it to a window variable.
But that does not seem to work too.
<script>
window.onload = function() {
window._FBInstant = FBInstant;
FBInstant.initializeAsync()
.then(function() {
// Start loading game assets here
FBInstant.startGameAsync().then(function() {
startGame();
});
});
}
</script>
you can store the FB instance on a data property in the created or any other hook
data: () => ({ FBInstance: null}),
created() {
this.FBInstance = window._FBInstant
}
and if you want to use it globally, you can do the same trick inside a mixin
Vue.mixin({
data: () => ({ FBInstance: null}),
created() {
this.FBInstance = window._FBInstant
}
})
Insert the Facebook Instant Game CDN script tag just after <body> tag.
Don't use cdn or direct <script> include for importing vuejs in your project.
Download the vuejs production version and save it in the project folder and compress (bundle) it along with other game files in the zip during the uploading in web hosting.
after fb cdn, include the <script src="js/vue.js"></script> from the files.
This way you can use facebook sdk as well as vuejs in the instant games.

Using MSAL v0.1.3 with Aurelia for Authentication

I've found all kind of examples of using MSAL and even examples of using MSAL with SPA applications (generally Angular or React) but I'm struggling to get this to work with Aurelia.
I did the following to ensure that the library is actually working as expected.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<style>
.hidden {
visibility: hidden;
}
</style>
</head>
<body>
<div id="username"></div>
<div id="token"></div>
<button id="login" onclick="loginPopup()">Log In</button>
<button id="logout" class="hidden">Log Out</button>
<script>
var authClient = new Msal.UserAgentApplication("my v2 endpoint client id",null);
function loginPopup(){
authClient.loginPopup(["openid","user.readbasic.all"])
.then(token => {
authClient.acquireTokenSilent(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
authClient.acquireTokenPopup(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
console.log("Token Error: " + error)
})
})
},
error =>{
console.log("Login error " + error)
})
}
function updateUI(token){
var loginbutton = document.getElementById("login");
loginbutton.className = "hidden";
let usernamediv = document.getElementById("username");
let tokendiv = document.getElementById("token");
usernamediv.innerText = authClient.getUser().name;
tokendiv.innerText = token;
}
</script>
</body>
</html>
That code works great. You click the Log In button, the Login Popup is displayed, you select the user, enter your password and the popup disappears and the UI is updated appropriately with username and token.
Now I'm trying to add this into my Aurelia app as follows:
main.js
export async function configure(aurelia){
aurelia.use
.standardConfiguration()
.developmentLogging();
let msClient = new Msal.UserAgentApplication('my v2 endpoint client id",null);
aurelia.use.instance("AuthService",msClient);
await aurelia.start();
if(msClient.getUser()) {
await aurelia.setRoot(PLATFORM.moduleName("app"));
else
await aurelia.setRoot(PLATFORM.moduleName("login/login"));
login.js
export class Login {
static inject = [Aurelia, "AuthService"]
constructor(aurelia, auth){
this.authService = auth
this.app = aurelia
}
activate(){
//Also tried this code in constructor
this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
}
However, with this code in place, the app loads and navigates to the login page which pops up the login popup. However, once the user enters/selects name and password, the popup screen does not go away. The app (behind the popup) seems to reload and navigate to the app.js viewmodel but the popup remains on the screen and appears to be asking the user to enter/select username.
I've also tried using loginRedirect rather than loginPopup with a similar result in that the app is constantly redirected to the login page even after authenticating.
I'm guessing this has to do with the way MSAL is trying to respond to the app and the way Aurelia is trying to handle navigation, etc but I can't figure out where things are going awry.
Any help would be greatly appreciated!
Use the attached() lifecycle callback
It seems like everything is working, but the popup isn't going away. It's hard to know why without seeing the code in action, but the first thing you'll want to try is moving the relevant code to the attached() callback, which is called once the view and view-model are bound and added to the DOM.
Do NOT return the login promise in activate()
If you returned the login promise in activate(), activation wouldn't complete until the promise resolved. However, app.setRoot() is being called when the promise resolves as well, which means that you would be starting a new navigation before the first one completed. This is bad.
activate() {
// THIS WOULD BREAK
return this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
Use the detatched() lifecycle callback
If that doesn't work, the next thing to do is check to see if authService.loginPopup() is properly logging in and resolving. If so, you can always go ahead and manually remove the popup from the DOM in the case that the library wasn't cleaning up after itself. You should do this detatched() lifecycle callback.