Keep UTM Source tracking in URL when user clicks on link - javascript

I run a news/publishing website where 95% of the traffic is coming from Facebook and from different Facebook fanpages.
I have set up UTM tracking through Google Analytics to track all links from different Fanpages to calculate how many visitors each page sents. This only tracks sessions when the user is sent to the website but when a user clicks on a link in the website such as another article the tracking is lost.
All users sent to the website have a UTM tracking code to the URL but when a user clicks on another link or article on the website the UTM tracking is removed from the URL therefore the tracking is lost for that user.
I want to track all pageviews from all users and sessions sent to the site.
I want the website to automatically have the UTM tracking in the URL when a user clicks on any link on the website.
For example, this is a link when a user is brought to the website:
http://99soccer.com/man-united-worried-as-rivals-man-city-are-poised-to-sign-their-transfer-target/?utm_source=slign-11&utm_medium=slign&utm_campaign=slign-11
If the user clicks on an article on the website this UTM tracking will disappear from the URL therefore not tracking the pageviews.
/?utm_source=slign-11&utm_medium=slign&utm_campaign=slign-11
Every user that will be sent to the website will be sent via referral and will have a utm source to track them but once you click on a link when you are on the website the tracking url (utm source) disappears. I want the tracking to stay there when you click on another link in the website.

var links = document.getElementsByTagName('a');
var utm = /(utm_source=.*)&(utm_medium=.*)&(utm_campaign=.*)/gi.exec(window.location.href);
for(var i=0;i<links.length;i++){
console.log(links[i].href = links[i].href + "?" + utm[0]);
}
This should do the trick.

I had this same problem and everywhere I searched, the solutions would suggest querying all <a> tags in the document on page load, loop over them, and apply the UTM parameters. This seems incomplete to me... what if the DOM gets updated with new links after page load? Seems using a click event handler would be the better route.
I came up with this and it seems to work for me. I don't know if it's foolproof though, so I'm open to improvements.
if (window.location.search.includes('utm_')) {
document.addEventListener('click', function(event){
// get the nearest anchor tag to where the user clicked (in case they clicked on something inside the anchor tag like an <img> or <span>
let aTag = event.target.closest('a');
if (aTag !== null) {
let urlParams = new URLSearchParams(window.location.search);
let aParams = new URLSearchParams(aTag.search);
// update the <a> tag's params with UTM params
for (let [key, value] of urlParams.entries()) {
// skip duplicates and only add new params that belong to UTM
if (! aParams.has(key) && key.includes('utm_')) {
aParams.append(key, value);
}
}
// reset the anchor's URL with all the query params added
aTag.href = aTag.href.split('?')[0] + '?' + aParams.toString();
}
});
}

There are better ways to get this data within GA. You can segment users with the initial referal source to your site and track the data that they have associated with them. I think this will accomplish what you want.
If for some reason I can't really think of you NEED to do this you could actively change all links on a page to include the UTM tag if a user loads the page with a UTM tag.
The rough structure of this:
1. Get the Document.url attribute
2. Logic check if it contains a UTM tag
3. If yes, add the same UTM tag to all links on the page
4. Add additional checks to remove UTM tags or other params those links might have as needed. Especially as the use of the & and ? in the url will need to be addressed.

You can manually set parameters for the session like this on the home page.
sessionStorage.setItem('utm_source', params.utm_source);
sessionStorage.setItem('utm_medium', params.utm_medium);
sessionStorage.setItem('utm_campaign', params.utm_campaign);
And then retrieve them on the contact page, probably to assign to a form field.
sessionStorage.getItem('itemName');

Related

Google bookmarks script only saves about 1 in 5 links

I've been having this problem with the Google bookmarks "bookmarklet" button in Chrome for several years now: it does not reliably save URLs to https://www.google.com/bookmarks so I have to double-check every link I save. The form is invoked by clicking the Google Bookmark button in the Chrome bookmarks bar that is a javascript link that opens the form. The button comes from the bottom of the Google bookmarks page itself:
Google Bookmarks page
Google Bookmark button properties
Many links will not save unless I add a suffix such as #1 to the end of the URL, and even that is not a 100% effective workaround. For example, the URL http://jsbeautifier.org/ only saves if I append the #1 in the URL field: http://jsbeautifier.org/#1.
Google Bookmarks Form
I don't know if it's an issue with the javascript, encoding the URL, or an issue on Google's end they have never fixed. Here is the full javascript that comes directly from the button properties. I added the whitespace for readability:
javascript: (function() {
var a = window,
b = document,
c = encodeURIComponent,
d = a.open("https://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk=" + c(b.location) + "&title=" + c(b.title), "bkmk_popup", "left=" + ((a.screenX || a.screenLeft) + 10) + ",top=" + ((a.screenY || a.screenTop) + 10) + ",height=510px,width=550px,resizable=1,alwaysRaised=1");
a.setTimeout(function() {
d.focus()
}, 300)})();
Thanks in advance! :)
I have similar issue of not able to add a lot of https website into Google Bookmarks, especially those from Github or Google's Chrome Webstore. Sometimes if you change the https prefix to http, it will work, but not for all.
I guess the problem lies at the backend side, because it also fails when you try to add the URL in question directly at the Add bookmark page.
Seems Google deserted this product (originated from the time of Google Toolbar) and favors Google Chrome bookmark sync solution.

Display hash (or fragment Identifier) with Javascript

My DNS hosting points a domain to my website (Stealth forward) so the domain that shows in my website is like www.mydomain.com, my website is based on SPA (Single page) design and that pages are accessed through fragment identifiers like (#home, #aboutus, etc).
The problem is the forward is stealth so the URL in the browser does not show the hash when navigating to pages.
How can I deal with this with Javascript? How can I make the hash (#home, #aboutus) in the browser URL?
Can this be easily be done with plain JS or I need jQuery for this?
Here's how I manager links in SPA:
Each anchor tag (or button for that matter) gets explicit hash like this:
My Title
You can generate hash like above easily like this:
var urlHash = "#" + $.param({ action:"doSomething", param1: 5, param2: 10});
I don't attach any event handlers to these anchors at all. They are really just plain anchors in HTML. Instead I use delegated event to catch hashchange event. One very easy way to do this is using JQuery BBQ plugin. There are numerous advantages in doing this including the fact that your users can bookmark fragments in SPA or send those URLs in emails because they show up in browser just like normal URLs. They also go in history so users can use back and forward buttons just like normal website.
Here's the sample code that listens to hashchange events which will be triggered whenever user clicks on above anchor:
//Global event handler for hash change for above type of anchors
$(window).bind("hashchange", function (e) {
var action = e.getState("action");
if (action === "doSomething") {
var param1= e.getState("param1");
var param2= e.getState("param2");
doSomething(param1, param2);
}
//else ignore unknown state
});

Bookmarklet target page DOM traversal. How?

How do I make a bookmarklet that places something into a field and submits the form?
I think along these lines:
1)var p = document.open(http://site.com/form.htm)
2) var h = p.innerHTML
3) var f = h.getElementById('formfield')
now how do I get the URL of the current page to become the value for 'formfield'?
var p = document.open(http://site.com/form.htm)
This won't work. You may be thinking of window.open. If you use window.open, it will only be useful for your purposes if the bookmarklet is run from the same domain. If run from any other domain, it will open the window, but you won't be able to do anything else with the document in that newly opened window.
var h = p.innerHTML
This does nothing helpful in your case. It just returns a string of text.
var f = h.getElementById('formfield')
This is not correct because it uses "h", which isn't correct. What you probably want is this...
var w = window.open('http://site.com/form.htm');
// need code that will check if window is done loading before you use next line!
w.document.getElementById('formfield').value = window.location;
If you use the bookmarklet on the page with the form, you only need this:
document.getElementById('formfield').value = window.location;
If you want to open the window to another domain, enter a form value, and submit the form - This can not be done with a bookmarklet. A bookmarklet faces the same restrictions as any other javascript in a page. This is for security to prevent any web page on the internet from trying to take control of your browser and do things on other sites as you. Your only reasonable option in this case would be to create/use a browser addon/extension.
If you are looking to put the current page's URL into formfield, this is how it could be accomplished:
f.value = window.location;
If I understand correctly, you want to submit the current URL and maybe some other data to your server using a bookmarklet.
I would do it this way:
Append your form to the current DOM using JavaScript. The form should be hardcoded in the bookmarklet.
Populate the form, you are on the guest page now, same domain.
Submit the form, maybe using a target="_blank" for the result.
You can't use Ajax instead of a form to submit your data because of crossdomain restrictions.

Using JavaScript to change the URL used when a page is bookmarked

JavaScript doesn't allow you to update window.location without triggering a reload. While I agree with this policy in principle (it shouldn't be possible to visit my website and have JavaScript change the location bar to read www.yourbankingsite.com,) I believe that it should be possible to change www.foo.org/index to www.foo.org/help.
The only reason I care about this is for bookmarking. I'm working on a photo browser, and when a user is previewing a particular image, I want that image to be the default if they should bookmark that page. For example, if they are viewing foo.org/preview/images0-30 and they click on image #15, that image is expanded to a medium-sized view. If they then bookmark the page, I want the bookmark URL to be foo.org/preview/images0-30/active15.
Any thoughts, or is there a security barrier on this one as well? I can certainly understand the same policy being applied here, but one can dream.
Sounds like you should check out Really Simple History. It's how Google (for example, Gmail) allows any page to be bookmarkable (and has history) but doesn't refresh the whole page.
As for the other side of things (having people visit your site then automatically popping up the correct image), I'd try checking window.location.hash once the page loads and firing events based on that.
You can add an anchor to the URL without reloading the page and pick that up with javascript:
location.href = '.../#' + imageId;
As mentioned, generally with ajaxy sites, you manipulate/check the hash part of the URL (window.location.hash) to determine this kind of activity.
The biggest issue is making sure to check against the hash in DOM-ready/window-load, as if the user clicked on a given image. This will work with browsers and bookmarks, but may hamper search indexing.
How about detecting on page load if the URL contains a hash, and if it does, directing them to the page you want them to go to?
You can add [Add to Favorites] button on the page.
Sample:
var urlAddress = "http://www.example.com/#image1";
var pageName = "Example Page Title - Image1";
function addToFavorites() {
if (window.external) {
window.external.AddFavorite(urlAddress, pageName);
} else {
alert("Sorry! Your browser doesn't support this function.");
}
}
Or use one of these jQuery plugins:
http://plugins.jquery.com/project/bookmark
http://plugins.jquery.com/project/jqbookmark
http://plugins.jquery.com/project/AddFavourite
http://plugins.jquery.com/project/jFav
http://plugins.jquery.com/project/jBookmarkEngine
AND / OR
Use URLs with hash at the end and load your content (images etc.) based on that hash value.
function onLoad() {
if (window.location.hash == "image1") {
// load image1
}
}
There are also lots for jQuery plugins for working with URL hash events, for example:
http://plugins.jquery.com/project/hashhistory
http://plugins.jquery.com/project/hashchange
There are also lots of non jQuery JavaScript libraries for that, for example:
http://code.google.com/p/reallysimplehistory/
<html>
<head>
<script type="text/javascript">
function myHref(){
document.getElementById('myAnchor').innerHTML="Visit Google"
document.getElementById('myAnchor').href="http://www.google.com"
}
</script>
</head>
<body>
<a id="myAnchor" href="http://www.java2s.com">Visit Java2s</a>
<form>
<input type="button" onclick="myHref()" value="Change URL and text">
</form>
</body>
</html>

Remove fragment in URL with JavaScript w/out causing page reload

Background: I have an HTML page which lets you expand certain content. As only small portions of the page need to be loaded for such an expansion, it's done via JavaScript, and not by directing to a new URL/ HTML page. However, as a bonus the user is able to permalink to such expanded sections, i.e. send someone else a URL like
http://example.com/#foobar
and have the "foobar" category be opened immediately for that other user. This works using parent.location.hash = 'foobar', so that part is fine.
Now the question: When the user closes such a category on the page, I want to empty the URL fragment again, i.e. turn http://example.com/#foobar into http://example.com/ to update the permalink display. However, doing so using parent.location.hash = '' causes a reload of the whole page (in Firefox 3, for instance), which I'd like to avoid. Using window.location.href = '/#' won't trigger a page reload, but leaves the somewhat unpretty-looking "#" sign in the URL. So is there a way in popular browsers to JavaScript-remove a URL anchor including the "#" sign without triggering a page refresh?
As others have mentioned, replaceState in HTML5 can be used to remove the URL fragment.
Here is an example:
// remove fragment as much as it can go without adding an entry in browser history:
window.location.replace("#");
// slice off the remaining '#' in HTML5:
if (typeof window.history.replaceState == 'function') {
history.replaceState({}, '', window.location.href.slice(0, -1));
}
Since you are controlling the action on the hash value, why not just use a token that means "nothing", like "#_" or "#default".
You could use the shiny new HTML5 window.history.pushState and replaceState methods, as described in ASCIIcasts 246: AJAX History State and on the GitHub blog. This lets you change the entire path (within the same origin host) not just the fragment. To try out this feature, browse around a GitHub repository with a recent browser.
Put this code on head section.
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
var clean_uri = uri.substring(0, uri.indexOf("?"));
window.history.replaceState({}, document.title, clean_uri);
}
</script>
There is also another option instead of using hash,
you could use javascript: void(0);
Example: Open Div
I guess it also depends on when you need that kind of link, so you better check the following links:
How to use it: http://www.brightcherry.co.uk/scribbles/2010/04/25/javascript-how-to-remove-the-trailing-hash-in-a-url/
or check debate on what is better here: Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?
$(document).ready(function() {
$(".lnk").click(function(e) {
e.preventDefault();
$(this).attr("href", "stripped_url_via_desired_regex");
});
});
So use
parent.location.hash = '' first
then do
window.location.href=window.location.href.slice(0, -1);
As others have said, you can't do it. Plus... seriously, as the jQuery Ajaxy author - I've deployed complete ajax websites for years now - and I can guarantee no end user has ever complained or perhaps ever even noticed that there is this hash thing going on, user's don't care as long as it works and their getting what they came for.
A proper solution though is HTML5 PushState/ReplaceState/PopState ;-) Which doesn't need the fragement-identifier anymore:
https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
For a HTML5 and HTML4 compatible project that supports this HTML5 State Functionality check out https://github.com/browserstate/History.js :-)

Categories