├── docs ├── tsconfig.json ├── public │ ├── icon.png │ ├── preview.png │ ├── preview-dark.png │ ├── logo-dark.svg │ └── logo-light.svg ├── .gitignore ├── tokens.config.ts ├── nuxt.config.js ├── app.config.ts ├── package.json ├── components │ └── Logo.vue └── content │ └── index.md ├── example ├── tsconfig.json ├── pages │ ├── bar.vue │ ├── foo.vue │ └── index.vue └── nuxt.config.js ├── renovate.json ├── .eslintrc.js ├── .gitignore ├── .eslintignore ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── question.md │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── ci.yml ├── jest.config.js ├── .versionrc ├── templates ├── plugin.server.js └── plugin.client.js ├── netlify.toml ├── tsconfig.json ├── LICENSE ├── package.json ├── src └── module.ts ├── CHANGELOG.md └── README.md /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@nuxtjs" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@nuxtjs/eslint-config-typescript'] 3 | } 4 | -------------------------------------------------------------------------------- /docs/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxt-community/ackee-module/main/docs/public/icon.png -------------------------------------------------------------------------------- /example/pages/bar.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /example/pages/foo.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /docs/public/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxt-community/ackee-module/main/docs/public/preview.png -------------------------------------------------------------------------------- /docs/public/preview-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxt-community/ackee-module/main/docs/public/preview-dark.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_Store 8 | coverage 9 | dist 10 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_Store 8 | coverage 9 | dist 10 | sw.* 11 | .output 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .nuxt 4 | coverage 5 | *.log* 6 | .DS_Store 7 | .code 8 | *.iml 9 | package-lock.json 10 | templates/* 11 | sw.js 12 | -------------------------------------------------------------------------------- /docs/tokens.config.ts: -------------------------------------------------------------------------------- 1 | import { defineTheme, palette } from 'pinceau' 2 | 3 | export default defineTheme({ 4 | color: { 5 | primary: palette('#65deb1') 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /docs/nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | extends: ['@nuxt-themes/docus'], 3 | 4 | modules: [ 5 | 'nuxt-plausible' 6 | ], 7 | 8 | plausible: { 9 | domain: 'ackee.nuxtjs.org' 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /example/nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | buildModules: [ 3 | '../src/module.ts' 4 | ], 5 | ackee: { 6 | server: '', 7 | domainId: '', 8 | detailed: 'opt-in', 9 | ignoreLocalhost: false, 10 | ignoreOwnVisits: false 11 | }, 12 | publicRuntimeConfig: { 13 | ackeeTestEvent: '' 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/app.config.ts: -------------------------------------------------------------------------------- 1 | export default defineAppConfig({ 2 | docus: { 3 | socials: { 4 | twitter: '@nuxt_js', 5 | github: 'nuxt-community/ackee-module' 6 | }, 7 | header: { 8 | title: 'Nuxt Ackee', 9 | logo: true 10 | }, 11 | title: 'Nuxt Ackee', 12 | url: 'https://ackee.nuxtjs.org' 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Nuxt Community Discord 4 | url: https://discord.nuxtjs.org 5 | about: Consider asking questions about the module here. 6 | - name: Documentation 7 | url: https://ackee.nuxtjs.org 8 | about: Check our documentation before reporting issues or questions. 9 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | '\\.(js|ts)$': [ 4 | 'babel-jest', 5 | { 6 | presets: ['@babel/preset-env', '@babel/preset-typescript'], 7 | plugins: ['@babel/plugin-transform-runtime'] 8 | } 9 | ] 10 | }, 11 | collectCoverage: true, 12 | collectCoverageFrom: ['src/**', '!templates/**'] 13 | } 14 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-ackee-docs", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxi dev", 7 | "build": "nuxi build", 8 | "start": "nuxi start", 9 | "generate": "nuxi generate" 10 | }, 11 | "dependencies": { 12 | "@nuxt-themes/docus": "^1.1.3", 13 | "nuxt": "^3.0.0" 14 | }, 15 | "devDependencies": { 16 | "nuxt-plausible": "^0.1.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.versionrc: -------------------------------------------------------------------------------- 1 | { 2 | "types": [ 3 | { 4 | "type": "feat", 5 | "section": "Features" 6 | }, 7 | { 8 | "type": "fix", 9 | "section": "Bug Fixes" 10 | }, 11 | { 12 | "type": "refactor", 13 | "section": "Refactor" 14 | }, 15 | { 16 | "type": "docs", 17 | "section": "Documentation" 18 | }, 19 | { 20 | "type": "chore", 21 | "section": "Chore" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /templates/plugin.server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {import('@nuxt/types').Plugin} 3 | */ 4 | export default function (context, inject) { 5 | inject('ackee', { 6 | <% if (['opt-in', 'opt-out'].includes(options.detailed)) { %> 7 | details: { 8 | value: null, 9 | preference: null, 10 | unknown: true, 11 | optIn() {}, 12 | optOut() {} 13 | },<% } %> 14 | record() {}, 15 | updateRecord() {}, 16 | action() {}, 17 | updateAction() {} 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # Global settings applied to the whole site. 2 | # 3 | # “base” is the directory to change to before starting build. If you set base: 4 | # that is where we will look for package.json/.nvmrc/etc, not repo root! 5 | # “command” is your build command. 6 | # “publish” is the directory to publish (relative to the root of your repo). 7 | 8 | [build] 9 | base = "docs" 10 | command = "yarn generate" 11 | publish = "dist" 12 | ignore = "git diff --quiet HEAD^ HEAD . ../package.json" 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question about the module. 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | --- 8 | 9 | 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "es2018", 5 | "module": "esnext", 6 | "lib": [ 7 | "esnext", 8 | "dom" 9 | ], 10 | "esModuleInterop": true, 11 | "moduleResolution": "node", 12 | "declaration": false, 13 | "skipLibCheck": true, 14 | "resolveJsonModule": true, 15 | "allowSyntheticDefaultImports": true, 16 | "types": [ 17 | "node", 18 | "jest" 19 | ] 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | "dist" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea or enhancement for this project. 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | ### Is your feature request related to a problem? Please describe. 10 | 11 | 12 | ### Describe the solution you'd like to see 13 | 14 | 15 | ### Describe alternatives you've considered 16 | 17 | 18 | ### Additional context 19 | 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | ci: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | os: [ubuntu-latest] 18 | node: [14] 19 | 20 | steps: 21 | - uses: actions/setup-node@v2 22 | with: 23 | node-version: ${{ matrix.node }} 24 | 25 | - name: checkout 26 | uses: actions/checkout@master 27 | 28 | - name: cache node_modules 29 | uses: actions/cache@v2 30 | with: 31 | path: node_modules 32 | key: ${{ matrix.os }}-node-v${{ matrix.node }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }} 33 | 34 | - name: Install dependencies 35 | if: steps.cache.outputs.cache-hit != 'true' 36 | run: yarn 37 | 38 | - name: Lint 39 | run: yarn lint 40 | # - name: Coverage 41 | # uses: codecov/codecov-action@v1 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a bug report to help us improve the module. 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ## Version 10 | Node: 11 | Nuxt: 12 | Module: 13 | 14 | ## Nuxt configuration 15 | 16 | 17 | ## Reproduction 18 | 19 | 20 | **Link (optional):** 21 | - [ ] GitHub repository 22 | 23 | ### Steps to reproduce 24 | 25 | 26 | ### What is expected? 27 | 28 | 29 | ### What is actually happening? 30 | 31 | 32 | ## Additional information 33 | 34 | 35 | ## Checklist 36 | * [ ] I have tested with the latest Nuxt version and the issue still occurs 37 | * [ ] I have tested with the latest module version and the issue still occurs 38 | * [ ] I have searched the issue tracker and this issue hasn't been reported yet 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Nuxt.js Community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nuxtjs/ackee", 3 | "version": "3.0.2", 4 | "description": "Nuxt.js module for Ackee analytics", 5 | "keywords": [ 6 | "nuxt", 7 | "module", 8 | "nuxt-module" 9 | ], 10 | "repository": "nuxt-community/ackee-module", 11 | "license": "MIT", 12 | "main": "dist/module.js", 13 | "types": "dist/module.d.ts", 14 | "files": [ 15 | "dist", 16 | "templates" 17 | ], 18 | "scripts": { 19 | "build": "siroc build", 20 | "dev": "nuxt-ts example", 21 | "lint": "eslint --ext .js,.ts,.vue .", 22 | "release": "yarn build && yarn test && standard-version && git push --follow-tags && npm publish", 23 | "test": "yarn lint" 24 | }, 25 | "dependencies": { 26 | "ackee-tracker": "^5.1.0", 27 | "consola": "^2.15.3", 28 | "defu": "^5.0.0" 29 | }, 30 | "devDependencies": { 31 | "@babel/plugin-transform-runtime": "latest", 32 | "@babel/preset-env": "latest", 33 | "@babel/preset-typescript": "latest", 34 | "@nuxt/test-utils": "latest", 35 | "@nuxt/types": "latest", 36 | "@nuxt/typescript-runtime": "latest", 37 | "@nuxtjs/eslint-config-typescript": "latest", 38 | "@siroc/jest-preset": "latest", 39 | "@types/jest": "latest", 40 | "babel-eslint": "latest", 41 | "babel-jest": "latest", 42 | "eslint": "latest", 43 | "jest": "latest", 44 | "nuxt-edge": "latest", 45 | "siroc": "latest", 46 | "standard-version": "latest" 47 | }, 48 | "publishConfig": { 49 | "access": "public" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /example/pages/index.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 63 | 64 | 69 | -------------------------------------------------------------------------------- /src/module.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import defu from 'defu' 3 | import { Module } from '@nuxt/types' 4 | import consola from 'consola' 5 | const log = consola.withScope('nuxt:ackee') 6 | 7 | export interface ModuleOptions { 8 | server?: string; 9 | domainId?: string; 10 | detailed?: boolean | 'opt-in' | 'opt-out'; 11 | ignoreLocalhost?: boolean; 12 | ignoreOwnVisits?: boolean; 13 | storageKey?: string; 14 | } 15 | const DEFAULTS: ModuleOptions = { 16 | server: '', 17 | domainId: '', 18 | detailed: false, 19 | ignoreLocalhost: true, 20 | ignoreOwnVisits: true, 21 | storageKey: 'nuxt-ackee' 22 | } 23 | const CONFIG_KEY = 'ackee' 24 | 25 | const nuxtModule: Module = /* async */ function (moduleOptions: ModuleOptions) { 26 | const options = defu(this.options[CONFIG_KEY]!, moduleOptions, DEFAULTS) 27 | // const { nuxt } = this 28 | 29 | if (!options.server || !options.domainId) { 30 | return log.warn('Could not activate @nuxtjs/ackee module, `server` and `domainId` properties are required') 31 | } 32 | 33 | this.addPlugin({ 34 | src: resolve(__dirname, '../templates', 'plugin.server.js'), 35 | fileName: 'nuxt-ackee.server.js', 36 | options 37 | }) 38 | this.addPlugin({ 39 | src: resolve(__dirname, '../templates', 'plugin.client.js'), 40 | ssr: false, 41 | fileName: 'nuxt-ackee.client.js', 42 | options 43 | }) 44 | } 45 | 46 | ; (nuxtModule as any).meta = require('../package.json') 47 | 48 | declare module '@nuxt/types' { 49 | interface NuxtConfig { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.14+ 50 | interface Configuration { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.9 - 2.13 51 | } 52 | 53 | export default nuxtModule 54 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [3.0.2](https://github.com/nuxt-community/ackee-module/compare/v3.0.1...v3.0.2) (2021-06-27) 6 | 7 | 8 | ### Documentation 9 | 10 | * add initial credit ([7164793](https://github.com/nuxt-community/ackee-module/commit/71647938b3dacdeb38945f0a5336c644a58023d9)) 11 | * typo ([14bcf0d](https://github.com/nuxt-community/ackee-module/commit/14bcf0d9baf5cd859f2f76865b956a33e8204126)) 12 | 13 | 14 | ### Chore 15 | 16 | * **deps:** maintain dependencies ([07b36df](https://github.com/nuxt-community/ackee-module/commit/07b36df2177ebf3de29dddceb96f85a47d063ec5)) 17 | * add .versionrc ([5e8a2f7](https://github.com/nuxt-community/ackee-module/commit/5e8a2f7800cb1c1c28aab4ade83bae8b72672dc2)) 18 | * **config:** update issue templates ([0648b5e](https://github.com/nuxt-community/ackee-module/commit/0648b5e10233998b609315fa1c720460df34f9bb)) 19 | 20 | ### [3.0.1](https://github.com/nuxt-community/ackee-module/compare/v3.0.0...v3.0.1) (2021-03-10) 21 | 22 | ## [3.0.0](https://github.com/nuxt-community/ackee-module/compare/v2.0.0...v3.0.0) (2021-03-10) 23 | 24 | 25 | ### ⚠ BREAKING CHANGES 26 | 27 | * upgrade to ackee tracker 5 28 | 29 | ### Features 30 | 31 | * add opt-in/opt-out mode to options.detailed ([32bf48e](https://github.com/nuxt-community/ackee-module/commit/32bf48e2370fda9342a0a50495f20cb2a7983e58)) 32 | * allow ignoreOwnVisits option to be used ([2448e58](https://github.com/nuxt-community/ackee-module/commit/2448e58a098865718b57945f43340ff314c26906)) 33 | * upgrade to ackee tracker 5 ([cee1ae7](https://github.com/nuxt-community/ackee-module/commit/cee1ae7da1d9c9e9f2007780a634f27847769d19)) 34 | 35 | 36 | ### Bug Fixes 37 | 38 | * client plugin doesn't need async ([c66907d](https://github.com/nuxt-community/ackee-module/commit/c66907da7c654ac06ef772ea5b217833389b462c)) 39 | -------------------------------------------------------------------------------- /templates/plugin.client.js: -------------------------------------------------------------------------------- 1 | <% if (['opt-in', 'opt-out'].includes(options.detailed)) { %>import Vue from 'vue' 2 | <% } %>import * as ackeeTracker from 'ackee-tracker' 3 | 4 | <% if (['opt-in', 'opt-out'].includes(options.detailed)) { %> 5 | const storageKey = '<%= options.storageKey %>' 6 | <% } %> 7 | 8 | /** 9 | * @type {import('@nuxt/types').Plugin} 10 | */ 11 | export default function(context, inject) { 12 | <% if (options.detailed === 'opt-in') { %> 13 | const detailed = window.localStorage.getItem(storageKey) === 'opted-in' 14 | <% } else if (options.detailed === 'opt-out') { %> 15 | const detailed = window.localStorage.getItem(storageKey) !== 'opted-out' 16 | <% } else { %> 17 | const detailed = <%= options.detailed ? 'true' : 'false' %> 18 | <% } %> 19 | 20 | // plugin is called only once when laoding the app on client-side 21 | const ackee = ackeeTracker.create( 22 | '<%= options.server %>', 23 | { 24 | detailed, 25 | ignoreLocalhost: <%= options.ignoreLocalhost ? 'true' : 'false' %>, 26 | ignoreOwnVisits: <%= options.ignoreOwnVisits ? 'true' : 'false' %> 27 | } 28 | ) 29 | 30 | <% if (['opt-in', 'opt-out'].includes(options.detailed)) { %> 31 | ackee.details = new Vue({ 32 | data: { 33 | value: detailed, 34 | preference: window.localStorage.getItem(storageKey), 35 | unknown: false 36 | }, 37 | methods: { 38 | optIn() { 39 | window.localStorage.setItem(storageKey, 'opted-in') 40 | this.value = true 41 | this.preference = 'opted-in' 42 | }, 43 | optOut() { 44 | window.localStorage.setItem(storageKey, 'opted-out') 45 | this.value = false 46 | this.preference = 'opted-out' 47 | } 48 | } 49 | }) 50 | <% } %> 51 | 52 | inject('ackee', ackee) 53 | 54 | let currentRecord 55 | context.app.router.afterEach((to, from) => { 56 | if (currentRecord) { 57 | currentRecord.stop() 58 | } 59 | 60 | currentRecord = ackee.record( 61 | '<%= options.domainId %>'<% if (['opt-in', 'opt-out'].includes(options.detailed)) { %>, 62 | ackeeTracker.attributes(ackee.details.value)<% } %> 63 | ) 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @nuxtjs/ackee 2 | 3 | [![npm version][npm-version-src]][npm-version-href] 4 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 5 | [![Github Actions CI][github-actions-ci-src]][github-actions-ci-href] 6 | [![Codecov][codecov-src]][codecov-href] 7 | [![License][license-src]][license-href] 8 | 9 | > Track without being tracked on Nuxt 2 with [Ackee analytics](https://ackee.electerious.com) 10 | 11 | - [✨  Release Notes](/CHANGELOG.md) 12 | - [📖  Read the documentation](https://ackee.nuxtjs.org) 13 | 14 | ## Setup 15 | 16 | 1. Add `@nuxtjs/ackee` dependency to your project 17 | 18 | ```bash 19 | yarn add @nuxtjs/ackee # or npm install @nuxtjs/ackee 20 | ``` 21 | 22 | 2. Add `@nuxtjs/ackee` to the `buildModules` section of `nuxt.config.js` 23 | 24 | ```js 25 | { 26 | buildModules: [ 27 | '@nuxtjs/ackee', 28 | ], 29 | ackee: { 30 | server: 'https://example.com', 31 | domainId: 'xxx-xxx-xxx' 32 | // see documentation for more! 33 | } 34 | } 35 | ``` 36 | 37 | ## Development 38 | 39 | 1. Clone this repository 40 | 2. Install dependencies using `yarn install` 41 | 3. Start development server using `yarn dev` 42 | 43 | ## License 44 | 45 | [MIT License](./LICENSE) 46 | 47 | Thanks to [Sergey Bedritsky](https://github.com/bdrtsky) for the initial implementation and transfer to the community of [nuxt-ackee](https://github.com/bdrtsky/nuxt-ackee). 48 | 49 | 50 | 51 | [npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/ackee/latest.svg 52 | [npm-version-href]: https://npmjs.com/package/@nuxtjs/ackee 53 | [npm-downloads-src]: https://img.shields.io/npm/dm/@nuxtjs/ackee.svg 54 | [npm-downloads-href]: https://npmjs.com/package/@nuxtjs/ackee 55 | [github-actions-ci-src]: https://github.com/nuxt-community/ackee-module/workflows/ci/badge.svg 56 | [github-actions-ci-href]: https://github.com/nuxt-community/ackee-module/actions?query=workflow%3Aci 57 | [codecov-src]: https://img.shields.io/codecov/c/github/nuxt-community/ackee-module.svg 58 | [codecov-href]: https://codecov.io/gh/nuxt-community/ackee-module 59 | [license-src]: https://img.shields.io/npm/l/@nuxtjs/ackee.svg 60 | [license-href]: https://npmjs.com/package/@nuxtjs/ackee 61 | -------------------------------------------------------------------------------- /docs/public/logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/public/logo-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /docs/content/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Documentation" 3 | description: "Track without being tracked on Nuxt with Ackee analytics." 4 | layout: "default" 5 | aside: false 6 | --- 7 | 8 | # Documentation 9 | 10 | Track without being tracked on Nuxt with Ackee analytics. 11 | 12 | --- 13 | 14 | ::list 15 | - Add Ackee to your Nuxt app in seconds 16 | - Ask for user consent easily 17 | - Automatic script loading 18 | - Automatic page tracking 19 | - Access to tracker with $ackee 20 | :: 21 | 22 | [Check Release Notes](https://github.com/nuxt-community/ackee-module/blob/main/CHANGELOG.md) 23 | 24 | ## Ackee? 25 | 26 | [Ackee analytics](https://ackee.electerious.com) is a self-hosted, Node.js based analytics tool that has an incentive on privacy. 27 | 28 | You can set up your own Ackee instance pretty easily on [Heroku](https://docs.ackee.electerious.com/#/docs/Get%20started#with-heroku), [Netlify](https://docs.ackee.electerious.com/#/docs/Get%20started#with-netlify), [Vercel](https://docs.ackee.electerious.com/#/docs/Get%20started#with-vercel), and [many more](https://docs.ackee.electerious.com/#/docs/Get%20started). [MongoDB Atlas](https://www.mongodb.com/pricing) can also provide you with a cloud-based Mongo database. 29 | 30 | This module allows you to plug easily your Nuxt website to a domain on your Ackee installation! 31 | 32 | ## Setup 33 | 34 | Add `@nuxtjs/ackee` dependency to your project: 35 | 36 | ::code-group 37 | 38 | ```bash [Yarn] 39 | yarn add --dev @nuxtjs/ackee 40 | ``` 41 | 42 | ```bash [NPM] 43 | npm install --save-dev @nuxtjs/ackee 44 | ``` 45 | :: 46 | 47 | Then add `@nuxtjs/ackee` to the `buildModule` section of `nuxt.config.js` and configure your Ackee `server` and `domainId`: 48 | 49 | 50 | ```javascript[nuxt.config.js] 51 | { 52 | buildModules: [ 53 | '@nuxtjs/ackee' 54 | ], 55 | ackee: { 56 | server: 'https://example.com', 57 | domainId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' 58 | /* see configuration for more */ 59 | } 60 | } 61 | ``` 62 | 63 | ::alert 64 | Use the `modules` property instead of `buildModules` if you are using `nuxt < 2.9.0` 65 | :: 66 | 67 | Voilà! Your Nuxt application is ready to report to your Ackee domain~ 68 | 69 | ## Usage 70 | 71 | This module injects `$ackee` into your application. It contains an [`ackee-tracker` instance](https://github.com/electerious/ackee-tracker#%EF%B8%8F-instance-api) (but not only, see [asking for consent](#asking-for-consent)). You can use it to create and update new records, actions, and more. 72 | 73 | ::alert 74 | This module already takes care of creating a new record on every page navigation. That's why in most cases you don't need to get beyond the above setup! 75 | :: 76 | 77 | ### Sending Events 78 | 79 | 80 | ```vue[pages/contact.vue] 81 | 84 | 85 | 100 | ``` 101 | 102 | 103 | 104 | Ackee recommends to ask user for consent before sending events. For that purpose you can leverage this module's injected [`details.value`](#detailsvalue) property when using the `detailed` option, see [asking for consent](#asking-for-consent) below. More about events on [Ackee documentation](https://docs.ackee.electerious.com/#/docs/Events). 105 | 106 | 107 | 108 | ### Asking for Consent 109 | 110 | The [detailed option](#detailed) allows you to gather personal data from your visitors. [Ackee recommends](https://docs.ackee.electerious.com/#/docs/Anonymization#personal-data) asking for user consent before enabling this option. To get started, set the `detailed` option in your Ackee configuration: 111 | 112 | 113 | ```javascript[nuxt.config.js] 114 | ackee: { 115 | // do not gather detailed data unless user gives permission 116 | detailed: 'opt-in' 117 | } 118 | ``` 119 | 120 | > An `opt-out` mode exists, working the other way around. Consider it if you were using `detailed: true`, it's better than nothing~ 121 | > 122 | > See all [available values](#detailed). 123 | 124 | From now on, a new object will be available at the key `details` in the injected `$ackee` object with the following methods and reactive properties: 125 | 126 | - `optIn()`: opt-in current user from sharing detailed data; 127 | - `optOut()`: opt-out current user from sharing detailed data; 128 | - `value`: can be used to know if Ackee is allowed to send data; 129 | - `preference`: contains the user's preference if any; 130 | - `unknown`: since user opt status is detected on client-side we cannot know it when on server side. Use this property to prevent showing your banner there. 131 | 132 | **Example:** 133 | 134 | 135 | ```vue[components/ConsentBanner.vue] 136 | 137 | 145 | ``` 146 | 147 | ## Configuration 148 | 149 | You can configure `@nuxtjs/ackee` with the `ackee` property in your `nuxt.config.js` or directly when registering the module in the `buildModules` array by using the array syntax. 150 | 151 | ::code-group 152 | 153 | ```javascript [ackee key] 154 | export default { 155 | ackee: { 156 | /* configuration */ 157 | } 158 | } 159 | ``` 160 | 161 | 162 | ```javascript [buildModules array] 163 | export default { 164 | buildModules: { 165 | ['@nuxtjs/ackee', { 166 | /* configuration */ 167 | }] 168 | } 169 | } 170 | ``` 171 | :: 172 | 173 | ### Properties 174 | 175 | #### server 176 | 177 | - Type: `String` 178 | - `required` 179 | 180 | An URL that points to your [Ackee](https://github.com/electerious/Ackee) installation. The `server` property must not end with a slash. 181 | 182 | 183 | ```javascript[nuxt.config.js] 184 | ackee: { 185 | // Nuxt.js private Ackee server example 186 | server: 'https://ackee.nuxtjs.com' 187 | } 188 | ``` 189 | 190 | #### domainId 191 | 192 | - Type: `String` 193 | - `required` 194 | 195 | Id of the desired domain to target. 196 | 197 | 198 | ```javascript[nuxt.config.js] 199 | ackee: { 200 | // example domain id 201 | domainId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' 202 | } 203 | ``` 204 | 205 | #### detailed 206 | 207 | - Type: `Boolean|String` 208 | - Default: `false` 209 | 210 | Enable or disable tracking of personal data. Possible values are: 211 | 212 | - `false`, never collect detailed data; 213 | - `true`, always collect detailed data; 214 | - `'opt-in'`, do not gather detailed data unless user gives permission; 215 | - `'opt-out'`, gather detailed data unless user ask not to. 216 | 217 | 218 | ```javascript[nuxt.config.js] 219 | ackee: { 220 | // tells Ackee to gather detailed data only with user's permission 221 | detailed: 'opt-in' 222 | } 223 | ``` 224 | 225 | > See [Ackee's recommendations](https://docs.ackee.electerious.com/#/docs/Anonymization#personal-data) regarding this feature. 226 | 227 | #### ignoreLocalhost 228 | 229 | - Type: `Boolean` 230 | - Default: `true` 231 | 232 | Enable or disable tracking when on localhost. 233 | 234 | 235 | ```javascript[nuxt.config.js] 236 | ackee: { 237 | // also tracks when on localhost 238 | ignoreLocalhost: false 239 | } 240 | ``` 241 | 242 | #### ignoreOwnVisits 243 | 244 | - Type: `Boolean` 245 | - Default: `true` 246 | 247 | Enable or disable the tracking of your own visits. 248 | 249 | 250 | ```javascript[nuxt.config.js] 251 | ackee: { 252 | // also tracks your own visits 253 | ignoreOwnVisits: false 254 | } 255 | ``` 256 | 257 | ::alert{type="warning"} 258 | For this feature to work you need to set up an `Access-Control-Allow-Credentials` header on your Ackee installation, [more info](https://docs.ackee.electerious.com/#/docs/CORS%20headers#credentials). 259 | :: 260 | 261 | ::alert{type="warning"} 262 | This feature should be turned off when using a wildcard `Access-Control-Allow-Origin` header, [more info](https://docs.ackee.electerious.com/#/docs/Options#cors-headers). 263 | :: 264 | 265 | #### storageKey 266 | 267 | - Type: `String` 268 | - Default: `nuxt-ackee` 269 | 270 | When using `'opt-in'` or `'opt-out'` with the [detailed](#detailed) option, used to determine the local storage key used to save user's preference. 271 | 272 | 273 | ```javascript[nuxt.config.js] 274 | ackee: { 275 | // store user's preference at `custom-key` inside their local storage 276 | storageKey: 'custom-key' 277 | } 278 | ``` 279 | 280 | ### Defaults 281 | 282 | Default configuration only expects you to provide your [Ackee server](#server) and [domain ID](#domainid). 283 | 284 | 285 | ```javascript[nuxt.config.js] 286 | export default { 287 | ackee: { 288 | server: '', 289 | domainId: '', 290 | detailed: false, 291 | ignoreLocalhost: true, 292 | ignoreOwnVisits: true, 293 | storageKey: 'nuxt-ackee' 294 | } 295 | } 296 | ``` 297 | 298 | ## \$ackee object 299 | 300 | This module globally injects a `$ackee` object, meaning that you can access it anywhere using `this.$ackee`. For plugins, `asyncData`, `nuxtServerInit` and middlewares, you can access it from `context.$ackee`. 301 | 302 | ::alert{type="warning"} 303 | `details.*` methods and properties are only available when using `'opt-in'` or `'opt-out'` with the [detailed](#detailed) option. 304 | :: 305 | 306 | ### Methods 307 | 308 | #### record(), updateRecord(), action(), updateAction() 309 | 310 | Those methods are directly forwarded from [`ackee-tracker` instance API](https://github.com/electerious/ackee-tracker#%EF%B8%8F-instance-api). 311 | 312 | #### details.optIn() 313 | 314 | Opt-in current user from sharing detailed data. 315 | 316 | #### details.optOut() 317 | 318 | Opt-out current user from sharing detailed data. 319 | 320 | ### Properties 321 | 322 | #### details.value 323 | 324 | - Type: `Boolean` 325 | - Value: `true` when Ackee is allowed to send detailed data. 326 | 327 | #### details.preference 328 | 329 | - Type: `String` 330 | - Values: `null` when no preference has been set, `'opted-in'`, `'opted-out'` 331 | 332 | #### details.unknown 333 | 334 | - Type: `Boolean` 335 | - Value: `true` when opt status is not yet detected, before client-side. 336 | 337 | ## Contributing 338 | 339 | You're welcome to contribute to this module! 340 | 341 | 1. Clone this repository 342 | 2. Install dependencies using `yarn install` or `npm install` 343 | 3. Start development server using `yarn dev` or `npm run dev` 344 | 345 | ## License 346 | 347 | [MIT License](https://github.com/nuxt-community/ackee-module/blob/main/LICENSE) 348 | 349 | Thanks to [Sergey Bedritsky](https://github.com/bdrtsky) for the initial implementation and transfer to the community of [nuxt-ackee](https://github.com/bdrtsky/nuxt-ackee). 350 | --------------------------------------------------------------------------------