diff --git a/handlers/backend.go b/handlers/backend.go index 1af403e80..95504ee3d 100644 --- a/handlers/backend.go +++ b/handlers/backend.go @@ -190,6 +190,7 @@ func (h backend) status() func(w http.ResponseWriter, r *http.Request) error { func (h backend) count(w http.ResponseWriter, r *http.Request) error { w.Header().Set("Cache-Control", "no-store,no-cache") + w.Header().Set("Access-Control-Allow-Origin", "*") // Don't track pages fetched with the browser's prefetch algorithm. // See https://github.com/usefathom/fathom/issues/13 diff --git a/public/count.js b/public/count.js index 10d5070c7..012bac6b8 100644 --- a/public/count.js +++ b/public/count.js @@ -75,10 +75,18 @@ if ('visibilityState' in document && document.visibilityState === 'prerender') return; + // Find the tag used to load this script. + var script = document.querySelector('script[data-goatcounter]'), + endpoint; + if (script) + endpoint = script.dataset.goatcounter; + else // TODO: temporary compat. + endpoint = window.counter; + // Don't track private networks. - if (location.hostname.match(/localhost$/) || - location.hostname.match(/^(127\.|10\.|172\.16\.|192\.168\.)/)) - return; + //if (location.hostname.match(/localhost$/) || + // location.hostname.match(/^(127\.|10\.|172\.16\.|192\.168\.)/)) + // return; var data = get_data(count_vars || {}); data.s = [window.screen.width, window.screen.height, (window.devicePixelRatio || 1)]; @@ -91,7 +99,7 @@ var img = document.createElement('img'); img.setAttribute('alt', ''); img.setAttribute('aria-hidden', 'true'); - img.src = window.counter + to_params(data); + img.src = endpoint + to_params(data); img.addEventListener('load', function() { document.body.removeChild(img) }, false); // Remove the image after 3s if the onload event is never triggered. diff --git a/tpl/_backend_sitecode.gohtml b/tpl/_backend_sitecode.gohtml index 527b1208c..799bce232 100644 --- a/tpl/_backend_sitecode.gohtml +++ b/tpl/_backend_sitecode.gohtml @@ -1,21 +1,22 @@ -
<script>
-	(function() {
-		window.counter = '{{.Site.URL}}/count'
-
-		var script = document.createElement('script');
-		script.async = 1;
-		script.src = '//{{.Static}}/count.js';
-		var ins = document.getElementsByTagName('script')[0];
-		ins.parentNode.insertBefore(script, ins)
-	})();
-</script>
+{{define "code"}}<script async + data-goatcounter="{{.Site.URL}}/count" + src="//static.goatcounter.localhost:8081/count.js"></script>{{end}} +
{{template "code" .}}
{{if eq .Path "/settings"}} -

The script is quite small and you can inline it if you want to save a - request. You won’t get any updates, but it’s expected to remain compatible in - the foreseeable future. Just be sure to set window.counter as in - the above snippet.

+

Content security policy

+

You’ll need the following if you use a +Content-Security-Policy:

+ +
+script-src  https://{{.Static}}
+img-src     {{.Site.URL}}/count
+
+ +

If you use the old script then you may also need to add +'unsafe-inline' to script-src, but it's recommended to +upgrade to the new script.

Customizing

You can pass variables with the window.goatcounter.vars object. @@ -67,45 +68,32 @@ on production.com and not staging.com or development.com; for example:

<script>
-	(function() {
-		// Only load on production environment.
-		if (window.location.host !== 'production.com')
-			return;
-
-		window.counter = '{{.Site.URL}}/count'
-
-		var script = document.createElement('script');
-		// [.. rest of standard script omitted ..]
-	})();
-</script>
+ // Only load on production environment. + if (window.location.host !== 'production.com') + window.goatcounter.no_onload = true; +{{template "code" .}}

Note that request from localhost are already ignored.

Custom path and referrer

<script>
-	(function() {
-		window.goatcounter = window.goatcounter || {};
-		window.goatcounter.vars = {
-			path: function(p) {
-				// Don't track the home page.
-				if (p === '/')
-					return null;
-
-				// Remove .html from all other page links.
-				return p.replace(/\.html$/, '');
-			},
-
-			// Very simplistic method to get referrer from URL (e.g. ?ref=Newsletter)
-			referrer: (window.location.search ? window.location.search.split('=')[1] : null),
-		};
-
-		window.counter = '{{.Site.URL}}/count'
-
-		var script = document.createElement('script');
-		// [.. rest of standard script omitted ..]
-	})();
-</script>
+ window.goatcounter = window.goatcounter || {}; + window.goatcounter.vars = { + path: function(p) { + // Don't track the home page. + if (p === '/') + return null; + + // Remove .html from all other page links. + return p.replace(/\.html$/, ''); + }, + + // Very simplistic method to get referrer from URL (e.g. ?ref=Newsletter) + referrer: (window.location.search ? window.location.search.split('=')[1] : null), + }; +</script> +{{template "code" .}}

Ignore query parameters in path

The value of <link rel="canonical"> will be used @@ -121,37 +109,45 @@ query parameters for navigation then you probably don’t want it.

parameters:

<script>
-	(function() {
-		window.goatcounter = window.goatcounter || {};
-		window.goatcounter.vars = {
-			path: location.pathname || '/',
-		};
-
-		window.counter = '{{.Site.URL}}/count'
-
-		var script = document.createElement('script');
-		// [.. rest of standard script omitted ..]
-	})();
-</script>
+ window.goatcounter = window.goatcounter || {}; + window.goatcounter.vars = { + path: location.pathname || '/', + }; +</script> +{{template "code" .}}

SPA

Custom count() example for hooking in to an SPA:

<script>
-	(function() {
-		window.goatcounter = window.goatcounter || {};
-		window.goatcounter.vars = {no_onload: true}
-
-		window.addEventListener('hashchange', function(e) {
-			window.goatcounter.count({
-				page: location.pathname + location.search + location.hash,
-			});
+	window.goatcounter = window.goatcounter || {};
+	window.goatcounter.vars = {no_onload: true}
+
+	window.addEventListener('hashchange', function(e) {
+		window.goatcounter.count({
+			page: location.pathname + location.search + location.hash,
 		});
+	});
+</script>
+{{template "code" .}}
+ + +

Advanced usage

+

You don’t need to use the count.js script, you can also +GET {{.Site.URL}}/count directly with the following query +parameters:

+ + - window.counter = '{{.Site.URL}}/count' +

The endpoint returns a small 1×1 GIF image. A simple no-JS way would be to +load an image on your site:

+

<img src="{{.Site.URL}}/count?p=/test-img">
- var script = document.createElement('script'); - // [.. rest of standard script omitted ..] - })(); -</script> +

Or you can call this from your app’s middleware (note this will probably +result in more bot requests).

-{{end}} +{{end}} {{/* if eq .Path "/settings" */}} diff --git a/tpl/backend_settings.gohtml b/tpl/backend_settings.gohtml index fe51bf03a..95c65f7e5 100644 --- a/tpl/backend_settings.gohtml +++ b/tpl/backend_settings.gohtml @@ -112,7 +112,7 @@

Site code

-

Insert the code below just before the closing </body> tag:

+

Insert the code below just before the closing </body> tag:

{{template "_backend_sitecode.gohtml" .}}