Compare commits

..

No commits in common. "main" and "0.0.1" have entirely different histories.
main ... 0.0.1

14 changed files with 43 additions and 239 deletions

View file

@ -1,28 +0,0 @@
/sample
.editorconfig
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View file

@ -1,12 +1,8 @@
![full_logo_color_light_transparent](https://user-images.githubusercontent.com/4896588/224442362-45dd92e7-e118-46ac-a423-83d479a9654b.png)
# Wide Angle Analytics for Vue.js # Wide Angle Analytics for Vue.js
[![License][license-src]][license-href]
[![Latest][npm-version-src]][npm-version-href]
[![Downloads][npm-downloads-src]][npm-downloads-href]
[![Wide Angle][wideangle-src]][wideangle-href]
![wide-angle-analytics-logo.png](assets/full_logo_color_light_transparent.png)
Enable **privacy-friendly** web analytics in your Vue.js 3.x application with our official plugin. Enable **privacy-friendly** web analytics in your Vue.js 3.x application with our official plugin.
[Wide Angle Analytics](https://wideangle.co) is powerful, strictly-GDPR compliant Google Analytics alternative. [Wide Angle Analytics](https://wideangle.co) is powerful, strictly-GDPR compliant Google Analytics alternative.
@ -40,11 +36,10 @@ option|description|required|default|example
siteId| The Site ID from Wide Angle Site settings| :white_check_mark: | _none_ | 8D27G3B9ACA01F4241 siteId| The Site ID from Wide Angle Site settings| :white_check_mark: | _none_ | 8D27G3B9ACA01F4241
domain| Domain hosting the script, can be found in Wide Angle Analytics Site settings | :white_check_mark: | _none_ | stats.wideangle.co domain| Domain hosting the script, can be found in Wide Angle Analytics Site settings | :white_check_mark: | _none_ | stats.wideangle.co
fingerprint | Should script use browser fingerprinting; this might require collecting consent depeing on the applicable laws | :x: | false | true fingerprint | Should script use browser fingerprinting; this might require collecting consent depeing on the applicable laws | :x: | false | true
suppressDnt | Should script ingore Do Not Track browser setting. If not enabled, not events will be sent if user's browser has DNT enabled | :x: | false | true supressDnt | Should script ingore Do Not Track browser setting. If not enabled, not events will be sent if user's browser has DNT enabled | :x: | false | true
includeParams | An array of query parameters that can be passed as part of tracking event. By default only `utm_*` and `ref` parameters are passed in the event | :x: | `[]` | `['sessionId', 'offset']` includeParams | An array of query parameters that can be passed as part of tracking event. By default only `utm_*` and `ref` parameters are passed in the event | :x: | `[]` | `['sessionId', 'offset']`
excludePaths | An array of URL paths that should not trigger default events such as page view, page leave | :x: | `[]` | `['^/wp-admin/.*', ]` excludePaths | An array of URL paths that should not trigger default events such as page view, page leave | :x: | `[]` | `['^/wp-admin/.*', ]`
ignoreHash | If enabled, change in the URL fragment will not trigger page view event | :x: | false | true ignoreHash | If enabled, change in the URL fragment will not trigger page view event | :x: | false | true
consentMarker | Cookie (with or without) value which present implies consent and absence lack its lack | :x: | n/a | `WAA_CONSENT=true`
You will find more details about these settings in [Wide Angle Analytics documentation](https://wideangle.co/documentation/configure-site). You will find more details about these settings in [Wide Angle Analytics documentation](https://wideangle.co/documentation/configure-site).
@ -60,7 +55,7 @@ app.use(WideAngle, {
siteId: "8D27G3B9ACA01F4241", siteId: "8D27G3B9ACA01F4241",
domain: "stats.example.com", domain: "stats.example.com",
fingerprint: true, fingerprint: true,
suppressDnt: true supressDnt: true
}); });
``` ```
@ -94,12 +89,18 @@ Site has to have these event enable in Wide Angle Analytics configuration prior
Currently **Click Events** are [emitted automatically](https://wideangle.co/documentation/tracking-click-events) based on element data attributes. Currently **Click Events** are [emitted automatically](https://wideangle.co/documentation/tracking-click-events) based on element data attributes.
| :warning: The tracker script does not listen to events inside shadow DOM. This is known limitation to be addressed in near term. |
|--------------------------------------------------------------------------------------------------------------------------------------------|
### Tracking Downloads ### Tracking Downloads
Depending on the configured mode, the **Download Event** will fire automatically when either: Depending on the configured mode, the **Download Event** will fire automatically when either:
* a file with recognized extension is being downloaded, or * a file with recognized extension is being downloaded, or
* when a link is marked with `data-waa-name` attribute. * when a link is marked with `data-waa-name` attribute.
| :warning: Currently the tracker script does not listen to events inside shadow DOM. This is known limitation to be addressed in near term. |
|--------------------------------------------------------------------------------------------------------------------------------------------|
### Tracking Custom Actions ### Tracking Custom Actions
Custom action are the most flexible and can be triggered directly from Vue components. As such their usage is not limitted due to Shadow DOM. Custom action are the most flexible and can be triggered directly from Vue components. As such their usage is not limitted due to Shadow DOM.
@ -119,78 +120,7 @@ const sendEvent = async () => {
session: 'cjhw92nf9aq', session: 'cjhw92nf9aq',
cohort: 'c1233' cohort: 'c1233'
} }
waa.value.dispatchEvent('interest', params); waa.dispatchEvent('interest', params);
} }
</script> </script>
``` ```
# Consent Handling
By default, Wide Angle Analytics does nore require consent thanks to its privacy-first, anonymous tracking and principaled approached to compliance.
However, you have additional toggles should you wish to control consent, either in **Opt-In** or **Opt-Out** mode.
## Opt-Out by default
If the visitors browsers has `DoNotTrack` setting enabled in the browser, it will be understood as opt-out and not tracking events will be issued.
You website can't overwrite this behaviour by specifying `suppressDnt` setting.
```javascript
app.use(WideAngle, {
siteId: "8D27G3B9ACA01F4241",
suppressDnt: true
});
```
## Opt-In or Opt-Out based on Cookie
Wide Angle can be configure to handle presence of a cookie, or a cookie with specific value, as an implicit consent. Lack of the cookie will be handled as implicit opt-out.
Example configuration with cookie marker, expecting cookie name `WAA_CONSENT` with value `true`:
```javascript
app.use(WideAngle, {
siteId: "8D27G3B9ACA01F4241",
consentMarker: "WAA_CONSENT=true"
});
```
## Programmatic consent
The Wide Angle serving offers two additional methods, which allow for recording tracking consent:
- `recordConsent(subjectId: String): void`, and
- `revokeConsent()`
Calling above methods on `waa` service will overwrite other consent mechanism (ie. DoNotTrack, and cookie marker).
Example usage:
```vue
<script setup>
import { inject } from 'vue'
const waa = inject('waa');
waa.value.recordConsent('FHJ44111');
</script>
```
<!-- Badges -->
[license-src]: https://img.shields.io/npm/l/wideangle-vuejs.svg?style=flat&colorA=18181B&colorB=28CF8D
[license-href]: https://opensource.org/license/apache-2-0/
[npm-downloads-src]: https://img.shields.io/npm/dm/wideangle-vuejs.svg?style=flat&colorA=18181B&colorB=28CF8DD
[npm-downloads-href]: https://npmjs.com/package/wideangle-vuejs
[npm-version-src]: https://img.shields.io/npm/v/wideangle-vuejs/latest.svg?style=flat&colorA=18181B&colorB=28CF8DD
[npm-version-href]: https://npmjs.com/package/wideangle-vuejs
[wideangle-src]: https://img.shields.io/badge/logo-wideangle-blue?label=&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAACXBIWXMAAAsSAAALEgHS3X78AAAJVUlEQVR4nO3dMZLcxhkFYIxLufcGok9gVfkA5g1En8B0soEjOt3EcuKY0QZKRN+APoGtA2wVdQJTJ7B9gnWh0FM7XHOXO4ueQXe/76tSMaIK8wg8/A1gMLvb29sJyPQL/+6QSwFAMAUAwRQABFMAEEwBQDAFAMEUAARTABBMAUAwBQDBFAAEUwAQTAFAMAUAwRQABFMAEEwBQDAFAMEUAARTABBMAUAwBQDBFAAEUwAQTAFAMAUAwRQABFMAEEwBQDAFAMEUAARTABBMAUAwBQDBFAAEUwAQTAFAMAUAwRQABFMAEEwBQDAFAMEUAARTABDsq44/+m0D2wB7ux6TMAFAMAUAwRQABFMAEEwBQLCeC+DnBrZhBHIM1nMBfGxgG0Ygx2CWABCs5wL40MA2jECOwXougP80sA0jkGMwEwByDGYCQI7Bdre3XX+nxheC1tvJsQpfBtqAe9h1yDFU7wVg/VqHHEMpAOQYrPcC+GcD2zACOYbq/SLgxTRN/25gO3q2k2MVLgJuYL6F9VPnn6EFcgw1wncBjK91yDGQAkCOwXq/BjBZv662X7vKcR3XADYyr19/HOBzbE2OgUZ5H8D7BrZhBHIMM8ISYPZimqZ/NbAdPTocXeX4fJYAG/roNlYVcgwz0ivB3jWwDSOQY5BRlgCT8fXZ7o+ucnweS4CNzePr3wf6PFuRY5DR3gpsfK1DjiFGWgLszWewr9vYlC48NLrK8TiWAI1w9qpDjgFGnAA80nqch85ccjyOCaAR8yOtfxvwc52bHAOMOAFMbmUd5bEzlxyfzgTQkI/OXlXIcXCjTgCTs9eTfenMJcenMQE0xtmrDjkObOQJYCpnr/mV179sYFta9ZQzlxy/zATQoPns9Xbwz3gOchzU6BPAVO5nf/BU24OeeuaS4+NMAI2a72e/CficpybHASVMAHvzW29/28amNOXYM5ccP6/LCSCpAFzI+rxjd1w5fp4lQOPmC1nfBX3eU5HjQJImgD0j7Keee+aS46csATphhP3Uc3dcOX7KEqAT8wj7OvBz1ybHASQWwFR+AMPjrevJsXOJS4C9i7KO/XUbm7OZtaOrHBeuAXTIOrbOjitH1wC6NK9jX4VnUIMcO5VeAFMZX//QwHb0To4dUgCL+Q24f2lhQzonx86kXwO4b96Bf9/WJp3cKdaucuyECeBTr93WqkKOnVAA/8/OW4ccO6AAPs/OW4ccG6cAHmbnrUOODVMAj7Pz1iHHRimAL3vt1lYVcmyQ24BPN+/AP/SysUc49+0rOTZEARznZfkG3EjPvG+x48qxEZYAx5kfd/1mmqafetroBsmxEQrgeB/LGcxFrXXk2ABLgHVelcdeex5lWxhd5bgRE8A678so+2PPH6IBctyIAlhvP8r+aZqm//b+YTYkxw1YAtT1ooyyPb0uu8XRVY5nYgKoa38W+900TT+P9MHOTI5nYgI4nYvyY5pvGr+41fqZS44npABO70X5Ka1WX5DRy44rxxOwBDi9/Q9o/Mo971XkeAIK4HzswHXIsSJLgO3s17bzzvz1htvR5eh6QI4rKIA2vCo78LcbbE3vBXBIjkdSAG15cbATn+untkYqgD05PpECaNd+J3514gdiRiyAQ3J8hALow0V5MGb/X82z2ugFcEiO9yiAPl2UL8+8LH9+s+ICWFIB3BefowIYy8uDnXr/51TG4Id27OQCeEhMjl81sA1UcrO7Ovp/9Jvbv4r/vuvL4//OH78/8UadhgLo0M3uqubomuv6Mj5HBdCBcsCf6uJVjuWAl+MBBdCom93VuW5fje36Uo6PUAANOTjoz/kAy3juDno5foECaMDN7mrLR1jHcX0pxyMpgI2UdX0LX2Lp27Kul+MzKYAzK2N+yy+26MMy5stxJQVwJg78Shz4VSmAE3PgV+LAPwkFcCIHa/zWX2bZtrs1vhxPQAGcQLmq/9ZFqZWWq/pyPCEFUFEZ93v7QYv2LOO+HM/AS0ErudldzSPqBzvtSteXcjwjE8BKzvqVOOtvwgSwQlnrO1uttaz15bgBE8AzlCv8b92SWmm5wi/HDSmAI5WR/70vmay0jPxy3JglwBFudlcvy6hqp13j+lKOjVAAT3Szu5q/bPIPD6OsdH0px4YogCe42V3Nj6D+0PyGtu76Uo6NcQ3gC252V+9cpKrg+lKODTIBPMLBX4mDv1kK4AEO/koc/E1TAJ/h4K/Ewd88BXCPg78SB38XFMABB38lDv5uKICi3Oqz06613OqTYycUwN1DPn9uYFP6tjzkI8eOxBdAebzXwylrLY/3yrEz0QVw8MUe1rj7Yg+diS2A8pXe955JX2n5Sq8cO5U8Abz1bbQq5NixyAIob/JxpXqt5U0+cuxYXAEcvMOPNe7e4UfHEieAd9arVchxAFEFUF7d7cWTay2v7pbjAGIK4OA3+ljj7jf6GEDSBGBkrUOOA4kogHLV38i61nLVX44DGb4ADt7hzxp37/BnIAkTwBu/LluFHAc0dAGUC39vGtiUvi0X/uQ4oNEngO9csKpCjoMatgDK2d9jqmstZ385DmrkCcC96jrkOLAhC8DZvxJn/+GNOgE4a9Uhx8ENVwDlvr+z1lrLfX85Dm7ECcDtqjrkGGDEAnjdwDaMQI4BhiqA8sy/p9XWWp75l2OA0SYAZ6065BhimAIot/6+bWBT+rbc+pNjiJEmgFcNbMMI5BhkpAIwttYhxyBDFEAZ/72bfq1l/JdjkFEmAGNrHXIMowCQY7DuC6A8+us9dWstj/7KMcwIE8DLBrZhBHIMpACQYzAFgByDdV0AZf3vttVay/pfjoF6nwC+aWAbRiDHUL0XgLG1DjmGMgEgx2AKADkG670AvLSiDjmG6rYAbnZX1q01XF/KMVjPE8BFA9swAjkG67kArFvrkGMwEwByDGYCQI7BRv95cOARPRfAiwa2YQRyDNZzAbh3XYccg1kCQDAFAMEUAARTABBMAUCw3e3trX9/CGUCgGAKAIIpAAimACCYAoBgCgCCKQAIpgAgmAKAYAoAgikACKYAIJgCgGAKAIIpAAimACCYAoBgCgCCKQAIpgAgmAKAYAoAgikACKYAIJgCgGAKAIIpAAimACCYAoBgCgCCKQAIpgAgmAKAYAoAgikACKYAIJgCgGAKAIIpAAimACCYAoBgCgCCKQAIpgAgmAKAVNM0/Q+XzeBEp8MpGQAAAABJRU5ErkJggg==
[wideangle-href]: https://wideangle.co?utm_source=github&utm_content=wideangle-vuejs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

View file

@ -1,16 +1,9 @@
import { initWideAngle } from "./dist"; import { initWideAngle } from "./src";
import { ref } from 'vue';
export { initWideAngle } from "./dist";
export default { export default {
install: (app, options) => { install: (app, options) => {
const waaRef = ref()
app.provide('waa', waaRef);
initWideAngle(options) initWideAngle(options)
.then(waa => { .then(waa => { app.provide('waa', waa); })
waaRef.value = waa; .catch(e => { console.error("Failed to load Wide Angle Plugin", e)});
console.debug("[WAA] Wide Angle Analytics instance available");
}).catch(e => { console.error("[WAA] Failed to load Wide Angle Plugin", e)});
return waaRef;
} }
} }

37
package-lock.json generated
View file

@ -1,37 +0,0 @@
{
"name": "wideangle-vuejs",
"version": "0.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "wideangle-vuejs",
"version": "0.0.3",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.0.4"
}
},
"node_modules/typescript": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=12.20"
}
}
},
"dependencies": {
"typescript": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true
}
}
}

View file

@ -1,18 +1,11 @@
{ {
"name": "wideangle-vuejs", "name": "wideangle-vuejs",
"version": "2.0.0", "version": "0.0.1",
"description": "Wide Angle Analytics web analytics Plugin for Vue.js 3.x", "description": "Wide Angle Analytics web analytics Plugin for Vue.js 3.x",
"homepage": "https://wideangle.co", "homepage": "https://wideangle.co",
"repository": { "repository": "github:inputobjects/wideangle-vuejs",
"type": "git",
"url": "https://cloud.inputobjects.eu/forge/wideangle/wideangle-vuejs.git"
},
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json",
"clear": "rimraf dist",
"rebuild": "npm run clear && npm run build",
"prepublishOnly": "npm run rebuild"
}, },
"keywords": [ "keywords": [
"wide angle analytics", "wide angle analytics",
@ -20,13 +13,8 @@
"vue.js", "vue.js",
"vuejs", "vuejs",
"plugin", "plugin",
"vuejs plugin", "vuejs plugin"
"privacy web analytics",
"privacy"
], ],
"author": "Wide Angle Analytics <developers@wideangle.co>", "author": "Wide Angle Analytics <developers@wideangle.co>",
"license": "Apache-2.0", "license": "Apache-2.0"
"devDependencies": {
"typescript": "^5.0.4"
}
} }

View file

@ -9,7 +9,8 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"vue": "^3.2.47", "vue": "^3.2.47",
"vue-router": "^4.1.6" "vue-router": "^4.1.6",
"wideangle-vue": "file:../../"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",
@ -17,12 +18,9 @@
} }
}, },
"../..": { "../..": {
"version": "2.0.0", "name": "wideangle-vuejs",
"extraneous": true, "version": "0.0.1",
"license": "Apache-2.0", "license": "Apache-2.0"
"devDependencies": {
"typescript": "^5.0.4"
}
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.21.2", "version": "7.21.2",
@ -773,6 +771,10 @@
"peerDependencies": { "peerDependencies": {
"vue": "^3.2.0" "vue": "^3.2.0"
} }
},
"node_modules/wideangle-vue": {
"resolved": "../..",
"link": true
} }
}, },
"dependencies": { "dependencies": {
@ -1173,6 +1175,9 @@
"requires": { "requires": {
"@vue/devtools-api": "^6.4.5" "@vue/devtools-api": "^6.4.5"
} }
},
"wideangle-vue": {
"version": "file:../.."
} }
} }
} }

View file

@ -3,13 +3,14 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite --host 0.0.0.0", "dev": "vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"vue": "^3.2.47", "vue": "^3.2.47",
"vue-router": "^4.1.6" "vue-router": "^4.1.6",
"wideangle-vue": "file:../../"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",

View file

@ -28,7 +28,5 @@ nav {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2rem; gap: 2rem;
width: 100%;
align-items: center;
} }
</style> </style>

View file

@ -1,13 +1,3 @@
body { body {
background-color: azure;
margin: 2rem;
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 800;
font-family: 'Courier New', Courier, monospace;
}
button {
border-width: 4px;
border-style: solid;
border-color: lightpink;
} }

View file

@ -1,19 +0,0 @@
<template>
<div>
<button type="button" data-waa-click="foo" data-waa-name="embedded-event">Send Click Event</button>
<a data-waa-click="bar" data-waa-name="embedded-event" href="https://adequate.country" target="_blank">Send Click Link</a>
<p>Click me nothing happens; click green background; magic</p>
</div>
</template>
<style scoped>
div {
display: flex;
flex-direction: row;
gap: 2rem;
padding: 1rem;
background-color: yellowgreen;
align-items: center;
}
</style>

View file

@ -1,7 +1,7 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import WideAngle from 'wideangle-vuejs' import WideAngle from 'wideangle-vue'
import './assets/main.css' import './assets/main.css'
@ -10,8 +10,8 @@ const app = createApp(App)
app.use(router) app.use(router)
app.use(WideAngle, { app.use(WideAngle, {
siteId: "8D27G3B9ACA01F4241", siteId: "8D27G3B9ACA01F4241",
domain: "events.wideangle.test", domain: "wideangle.local:3000",
fingerprint: true, fingerprint: true,
suppressDnt: true supressDnt: true
}) })
app.mount('#app') app.mount('#app')

View file

@ -1,16 +1,13 @@
<template> <template>
<main> <main>
<p>Demostration of using Click and Custom Actions on Vue Components</p> <p>I am sample</p>
<button type="click" @click="sendEvent()">Send Event</button> <button @click="sendEvent()">Send Event</button>
{{ status }} {{ status }}
<EmbeddedButton data-waa-click="component-click" data-waa-name="embedded-button"/>
</main> </main>
</template> </template>
<script setup> <script setup>
import EmbeddedButton from '../components/EmbeddedButton.vue'
import { inject, ref } from 'vue' import { inject, ref } from 'vue'
const waa = inject('waa'); const waa = inject('waa');
const status = ref('idle'); const status = ref('idle');
@ -19,9 +16,9 @@ const sendEvent = async () => {
session: 'cjhw92nf9aq', session: 'cjhw92nf9aq',
cohort: 'c1233' cohort: 'c1233'
} }
console.log(`Sending event: ${JSON.stringify(params)}`); console.log(`Sending event: ${JSON.stringify(params)}`);
status.value = 'pending...'; status.value = 'pending...'
await waa.value.dispatchEvent('interest', params); await waa.dispatchEvent('interest', params);
status.value = 'sent' status.value = 'sent'
} }
</script> </script>
@ -32,6 +29,6 @@ main {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 1rem;
max-width: 600px; max-width: 300px;
} }
</style> </style>

View file

@ -1,14 +0,0 @@
{
"include": ["src/**/*"],
"compilerOptions": {
"target": "es2016",
// "module": "commonjs",
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"allowJs": true,
"outDir": "dist",
"skipLibCheck": true
}
}