├── playground ├── package.json ├── app.vue ├── pages │ ├── page-a.vue │ ├── page-b.vue │ └── index.vue ├── nuxt.config.ts └── layouts │ └── default.vue ├── .eslintignore ├── .npmrc ├── .nuxtrc ├── tsconfig.json ├── dist ├── runtime │ ├── plugin.d.ts │ └── plugin.mjs ├── types.d.ts ├── module.json ├── module.cjs ├── module.d.ts └── module.mjs ├── .vscode └── settings.json ├── .yarnrc.yml ├── .eslintrc ├── .editorconfig ├── .release-it.json ├── renovate.json ├── .gitignore ├── LICENSE ├── package.json ├── src ├── runtime │ └── plugin.ts └── module.ts ├── README.md └── CHANGELOG.md /playground/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /.nuxtrc: -------------------------------------------------------------------------------- 1 | imports.autoImport=false 2 | typescript.includeWorkspace=true 3 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./playground/.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /dist/runtime/plugin.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: any; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /dist/types.d.ts: -------------------------------------------------------------------------------- 1 | 2 | import { } from './module' 3 | 4 | 5 | 6 | export { default } from './module' 7 | -------------------------------------------------------------------------------- /playground/app.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /dist/module.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yandex-metrika-module-nuxt3", 3 | "configKey": "yandexMetrika", 4 | "compatibility": { 5 | "nuxt": ">=3.0.0" 6 | }, 7 | "version": "1.5.3" 8 | } -------------------------------------------------------------------------------- /playground/pages/page-a.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /playground/pages/page-b.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "scss.lint.unknownAtRules": "ignore", 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll.eslint": true 5 | }, 6 | "typescript.tsdk": "node_modules/typescript/lib" 7 | } -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 5 | spec: "@yarnpkg/plugin-interactive-tools" 6 | 7 | yarnPath: .yarn/releases/yarn-3.2.0.cjs 8 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@nuxtjs/eslint-config-typescript" 4 | ], 5 | "rules": { 6 | "@typescript-eslint/no-unused-vars": [ 7 | "off" 8 | ], 9 | "vue/multi-word-component-names": "off" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /dist/module.cjs: -------------------------------------------------------------------------------- 1 | module.exports = function(...args) { 2 | return import('./module.mjs').then(m => m.default.call(this, ...args)) 3 | } 4 | const _meta = module.exports.meta = require('./module.json') 5 | module.exports.getMeta = () => Promise.resolve(_meta) 6 | -------------------------------------------------------------------------------- /playground/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import YandexMetrikaModule from '..' 2 | 3 | export default defineNuxtConfig({ 4 | modules: [ 5 | YandexMetrikaModule 6 | ], 7 | yandexMetrika: { 8 | id: 'XXXXXX', 9 | useRuntimeConfig: true, 10 | consoleLog: true 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /playground/pages/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "commitMessage": "chore: release v${version}" 4 | }, 5 | "github": { 6 | "release": true, 7 | "releaseName": "v${version}" 8 | }, 9 | "npm": { 10 | "skipChecks": true 11 | }, 12 | "plugins": { 13 | "@release-it/conventional-changelog": { 14 | "preset": "conventionalcommits", 15 | "infile": "CHANGELOG.md" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /playground/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 26 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "packages:linters", 5 | ":labels(dependencies,devops)", 6 | ":maintainLockFilesWeekly", 7 | ":enableVulnerabilityAlerts", 8 | ":automergeLinters", 9 | ":automergeTypes", 10 | ":semanticCommitTypeAll(chore)", 11 | ":automergePatch" 12 | ], 13 | "rebaseStalePrs": true, 14 | "prCreation": "not-pending", 15 | "rangeStrategy": "bump", 16 | "npm": { 17 | "commitMessageTopic": "{{prettyDepType}} {{depName}}" 18 | }, 19 | "packageRules": [ 20 | { 21 | "packagePatterns": ["lint"], 22 | "groupName": "all lint dependencies", 23 | "groupSlug": "all-lint" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Logs 5 | *.log* 6 | 7 | # Temp directories 8 | .temp 9 | .tmp 10 | .cache 11 | 12 | # Yarn 13 | **/.yarn/cache 14 | **/.yarn/*state* 15 | 16 | # Nuxt 17 | .nuxt 18 | .output 19 | .vercel_build_output 20 | .build-* 21 | .env 22 | .netlify 23 | 24 | # Env 25 | .env 26 | 27 | # Testing 28 | reports 29 | coverage 30 | *.lcov 31 | .nyc_output 32 | 33 | # VSCode 34 | .vscode/* 35 | !.vscode/settings.json 36 | !.vscode/tasks.json 37 | !.vscode/launch.json 38 | !.vscode/extensions.json 39 | !.vscode/*.code-snippets 40 | 41 | # Intellij idea 42 | *.iml 43 | .idea 44 | 45 | # OSX 46 | .DS_Store 47 | coverage 48 | 49 | # yarn v2 50 | .yarn/cache 51 | .yarn/unplugged 52 | .yarn/build-state.yml 53 | .yarn/install-state.gz 54 | .pnp.* 55 | -------------------------------------------------------------------------------- /dist/module.d.ts: -------------------------------------------------------------------------------- 1 | import * as _nuxt_schema from '@nuxt/schema'; 2 | import { ModuleOptions } from '@nuxt/schema'; 3 | 4 | interface YandexMetrikaModuleOptions extends ModuleOptions { 5 | id?: string; 6 | metrikaUrl?: string; 7 | accurateTrackBounce?: boolean | number; 8 | childIframe?: boolean; 9 | clickmap?: boolean; 10 | defer?: boolean; 11 | ecommerce?: boolean | string | []; 12 | params?: object | []; 13 | useRuntimeConfig?: boolean; 14 | useCDN?: boolean; 15 | userParams?: object; 16 | trackHash?: boolean; 17 | trackLinks?: boolean; 18 | trustedDomains?: []; 19 | type?: number; 20 | webvisor?: boolean; 21 | triggerEvent?: boolean; 22 | consoleLog?: boolean; 23 | partytown?: boolean; 24 | } 25 | declare const _default: _nuxt_schema.NuxtModule; 26 | 27 | export { YandexMetrikaModuleOptions, _default as default }; 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Nuxt 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": "yandex-metrika-module-nuxt3", 3 | "version": "1.5.3", 4 | "description": "Add Yandex Metrika to your Nuxt 3 application.", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/digitalcortex/yandex-metrika-module-nuxt3.git" 9 | }, 10 | "homepage": "digitalcortex/yandex-metrika-module-nuxt3", 11 | "bugs": { 12 | "url": "https://github.com/digitalcortex/yandex-metrika-module-nuxt3/issues" 13 | }, 14 | "exports": { 15 | ".": { 16 | "import": "./dist/module.mjs", 17 | "require": "./dist/module.cjs" 18 | } 19 | }, 20 | "type": "module", 21 | "main": "./dist/module.cjs", 22 | "module": "./dist/module.mjs", 23 | "types": "./dist/types.d.ts", 24 | "files": [ 25 | "dist" 26 | ], 27 | "scripts": { 28 | "build": "nuxt-module-build", 29 | "dev": "nuxi dev playground", 30 | "dev:build": "nuxi dev playground", 31 | "dev:prepare": "pnpm build --stub && nuxi prepare playground", 32 | "prepack": "pnpm build", 33 | "lint": "eslint --ext .js,.ts,.vue .", 34 | "lint:fix": "eslint --fix --ext .js,.ts,.vue ." 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "dependencies": { 40 | "@nuxt/kit": "^3.0.0", 41 | "defu": "^6.1.1", 42 | "pathe": "^1.0.0" 43 | }, 44 | "devDependencies": { 45 | "@nuxt/module-builder": "latest", 46 | "@nuxtjs/eslint-config-typescript": "latest", 47 | "@release-it/conventional-changelog": "^4.3.0", 48 | "@types/node": "latest", 49 | "eslint": "latest", 50 | "nuxt": "^3.0.0", 51 | "release-it": "^14.14.3" 52 | }, 53 | "packageManager": "pnpm@7.17.1" 54 | } 55 | -------------------------------------------------------------------------------- /dist/module.mjs: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url'; 2 | import { resolve } from 'pathe'; 3 | import { useLogger, defineNuxtModule, addTemplate, addPlugin } from '@nuxt/kit'; 4 | import defu from 'defu'; 5 | 6 | const logger = useLogger("nuxt:yandex-metrika"); 7 | const CONFIG_KEY = "yandexMetrika"; 8 | const module = defineNuxtModule({ 9 | meta: { 10 | name: "yandex-metrika-module-nuxt3", 11 | configKey: CONFIG_KEY, 12 | compatibility: { 13 | nuxt: ">=3.0.0" 14 | } 15 | }, 16 | defaults: { 17 | id: process.env.YANDEX_METRIKA_ID, 18 | metrikaUrl: "https://mc.yandex.ru/metrika", 19 | accurateTrackBounce: true, 20 | childIframe: false, 21 | clickmap: true, 22 | defer: false, 23 | useRuntimeConfig: true, 24 | trackHash: false, 25 | trackLinks: true, 26 | type: 0, 27 | webvisor: false, 28 | triggerEvent: false, 29 | consoleLog: true, 30 | partytown: false 31 | }, 32 | setup(options, nuxt) { 33 | const isDev = nuxt.options.dev && process.env.NODE_ENV !== "production"; 34 | options.isDev = isDev; 35 | logger.info(`Initializing Yandex Metrika in ${isDev ? "development" : "production"} mode`); 36 | if (!options.id) { 37 | logger.error("No id provided."); 38 | } 39 | options.metrikaUrl = (options.useCDN ? "https://cdn.jsdelivr.net/npm/yandex-metrica-watch" : options.metrikaUrl) + "/tag.js"; 40 | if (options.useRuntimeConfig) { 41 | nuxt.options.runtimeConfig.public[CONFIG_KEY] = defu(nuxt.options.runtimeConfig.public[CONFIG_KEY], options); 42 | } 43 | addTemplate({ 44 | filename: "yandex-metrika.options.mjs", 45 | getContents: () => { 46 | return `export default () => Promise.resolve(${JSON.stringify(options.useRuntimeConfig ? nuxt.options.runtimeConfig.public[CONFIG_KEY] : options || {})})`; 47 | } 48 | }); 49 | const head = nuxt.options.app.head; 50 | head.script = head.script || []; 51 | logger.debug(`Yandex Metrika script URL: ${options.metrikaUrl}`); 52 | if (!isDev) { 53 | const scriptObj = { 54 | src: options.metrikaUrl, 55 | async: true, 56 | tagPosition: "head" 57 | }; 58 | if (options.partytown) { 59 | scriptObj.type = "text/partytown"; 60 | } 61 | head.script.push(scriptObj); 62 | } 63 | const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url)); 64 | addPlugin({ 65 | src: resolve(runtimeDir, "plugin"), 66 | mode: "client" 67 | }); 68 | } 69 | }); 70 | 71 | export { module as default }; 72 | -------------------------------------------------------------------------------- /dist/runtime/plugin.mjs: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin } from "#app"; 2 | import { useRouter } from "#imports"; 3 | import options from "#build/yandex-metrika.options.mjs"; 4 | export default defineNuxtPlugin(async ({ _ }) => { 5 | const { id, isDev, consoleLog, metrikaUrl, partytown, ...metrikaOptions } = await options(); 6 | let ready = false; 7 | useRouter().isReady().then(() => { 8 | ready = true; 9 | }); 10 | function create() { 11 | if (!ready) { 12 | if (!isDev) { 13 | (function(m, e, t, r, i, k, a) { 14 | m[i] = m[i] || function() { 15 | (m[i].a = m[i].a || []).push(arguments); 16 | }; 17 | m[i].l = 1 * new Date(); 18 | k = e.createElement(t); 19 | a = e.getElementsByTagName(t)[0]; 20 | k.async = 1; 21 | k.src = r; 22 | a.parentNode.insertBefore(k, a); 23 | })(window, document, "script", metrikaUrl, "ym"); 24 | ym(id, "init", metrikaOptions); 25 | } 26 | if (consoleLog) { 27 | console.log(`Yandex Metrika initialized in ${isDev ? "development" : "production"} mode. ID=${id}. Options: ${JSON.stringify(metrikaOptions)}`); 28 | } 29 | if (partytown && window) { 30 | window.dispatchEvent(new CustomEvent("ptupdate")); 31 | } 32 | } 33 | useRouter().afterEach((to, from) => { 34 | if (to.fullPath === from.fullPath) { 35 | return; 36 | } 37 | if (consoleLog) { 38 | console.log(`Yandex Metrika page hit: "${to.fullPath}" (referer="${from.fullPath}")`); 39 | } 40 | if (!isDev) { 41 | ym(id, "hit", to.fullPath, { 42 | referer: from.fullPath 43 | }); 44 | } 45 | }); 46 | } 47 | if (window.ym === void 0) { 48 | create(); 49 | } 50 | return { 51 | provide: { 52 | ym: (method, ...args) => { 53 | if (window.ym) { 54 | ym.apply(null, [id, method, ...args]); 55 | if (consoleLog) { 56 | if (args.length === 0) { 57 | console.log(`Yandex Metrika call: ym("${id}", "${method}")`); 58 | } else { 59 | const argumentsText = args.map((a) => JSON.stringify(a)).join(", "); 60 | console.log(`Yandex Metrika call: ym("${id}", "${method}", ${argumentsText})`); 61 | } 62 | } 63 | } else if (consoleLog) { 64 | if (args.length === 0) { 65 | console.log(`Yandex Metrika is not initialized! Failed to execute: ym("${id}", "${method}")`); 66 | } else { 67 | const argumentsText = args.map((a) => JSON.stringify(a)).join(", "); 68 | console.log(`Yandex Metrika is not initialized! Failed to execute: ym("${id}", "${method}", ${argumentsText})`); 69 | } 70 | } 71 | } 72 | } 73 | }; 74 | }); 75 | -------------------------------------------------------------------------------- /src/runtime/plugin.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin, useRuntimeConfig } from '#app' 2 | import { useRouter } from '#imports' 3 | import options from '#build/yandex-metrika.options.mjs' 4 | 5 | export default defineNuxtPlugin(async ({ _ }) => { 6 | const { id, isDev, consoleLog, metrikaUrl, partytown, ...metrikaOptions } = await options() 7 | 8 | let ready = false 9 | // const basePath = (useRuntimeConfig().app.baseURL || '/').replace(/\/$/, '') 10 | 11 | // Mark when the router has completed the initial navigation. 12 | useRouter().isReady().then(() => { 13 | ready = true 14 | }) 15 | 16 | function create () { 17 | if (!ready) { 18 | if (!isDev) { 19 | // Don't record a duplicate hit for the initial navigation. 20 | (function (m, e, t, r, i, k, a) { 21 | m[i] = m[i] || function () { (m[i].a = m[i].a || []).push(arguments) } 22 | m[i].l = 1 * new Date() 23 | k = e.createElement(t) 24 | a = e.getElementsByTagName(t)[0] 25 | k.async = 1 26 | k.src = r 27 | a.parentNode.insertBefore(k, a) 28 | })(window, document, 'script', metrikaUrl, 'ym') 29 | ym(id, 'init', metrikaOptions) 30 | } 31 | if (consoleLog) { 32 | console.log(`Yandex Metrika initialized in ${isDev ? 'development' : 'production'} mode. ID=${id}. Options: ${JSON.stringify(metrikaOptions)}`) 33 | } 34 | 35 | if (partytown && window) { 36 | window.dispatchEvent(new CustomEvent('ptupdate')) 37 | } // trigger partytown rescan 38 | } 39 | 40 | useRouter().afterEach((to, from) => { 41 | if (to.fullPath === from.fullPath) { 42 | return 43 | } 44 | if (consoleLog) { 45 | console.log(`Yandex Metrika page hit: "${to.fullPath}" (referer="${from.fullPath}")`) 46 | } 47 | if (!isDev) { 48 | ym(id, 'hit', to.fullPath, { 49 | referer: /* basePath + */from.fullPath 50 | }) 51 | } 52 | }) 53 | } 54 | 55 | if (window.ym === undefined) { 56 | create() 57 | } 58 | 59 | return { 60 | provide: { 61 | ym: (method: string, ...args: any[]) => { 62 | if (window.ym) { 63 | ym.apply(null, [id, method, ...args]) 64 | if (consoleLog) { 65 | if (args.length === 0) { 66 | console.log(`Yandex Metrika call: ym("${id}", "${method}")`) 67 | } else { 68 | const argumentsText = args.map(a => JSON.stringify(a)).join(', ') 69 | console.log(`Yandex Metrika call: ym("${id}", "${method}", ${argumentsText})`) 70 | } 71 | } 72 | } else if (consoleLog) { 73 | if (args.length === 0) { 74 | console.log(`Yandex Metrika is not initialized! Failed to execute: ym("${id}", "${method}")`) 75 | } else { 76 | const argumentsText = args.map(a => JSON.stringify(a)).join(', ') 77 | console.log(`Yandex Metrika is not initialized! Failed to execute: ym("${id}", "${method}", ${argumentsText})`) 78 | } 79 | } 80 | } 81 | } 82 | } 83 | }) 84 | -------------------------------------------------------------------------------- /src/module.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | import { resolve } from 'pathe' 3 | import { defineNuxtModule, addPlugin, addTemplate, useLogger } from '@nuxt/kit' 4 | import { ModuleOptions } from '@nuxt/schema' 5 | import defu from 'defu' 6 | 7 | export interface YandexMetrikaModuleOptions extends ModuleOptions { 8 | id?: string, 9 | metrikaUrl?: string, 10 | accurateTrackBounce?: boolean | number, 11 | childIframe?: boolean, 12 | clickmap?: boolean, 13 | defer?: boolean, 14 | ecommerce?: boolean | string | [], 15 | params?: object | [], 16 | useRuntimeConfig?: boolean, 17 | useCDN?: boolean, 18 | userParams?: object, 19 | trackHash?: boolean, 20 | trackLinks?: boolean, 21 | trustedDomains?: [], 22 | type?: number, 23 | webvisor?: boolean, 24 | triggerEvent?: boolean, 25 | consoleLog?: boolean, 26 | partytown?: boolean 27 | } 28 | 29 | const logger = useLogger('nuxt:yandex-metrika') 30 | const CONFIG_KEY = 'yandexMetrika' 31 | 32 | export default defineNuxtModule({ 33 | meta: { 34 | name: 'yandex-metrika-module-nuxt3', 35 | configKey: CONFIG_KEY, 36 | compatibility: { 37 | nuxt: '>=3.0.0' 38 | } 39 | }, 40 | defaults: { 41 | id: process.env.YANDEX_METRIKA_ID, 42 | metrikaUrl: 'https://mc.yandex.ru/metrika', 43 | accurateTrackBounce: true, 44 | childIframe: false, 45 | clickmap: true, 46 | defer: false, 47 | useRuntimeConfig: true, 48 | trackHash: false, 49 | trackLinks: true, 50 | type: 0, 51 | webvisor: false, 52 | triggerEvent: false, 53 | consoleLog: true, 54 | partytown: false 55 | }, 56 | setup (options: YandexMetrikaModuleOptions, nuxt) { 57 | const isDev = (nuxt.options.dev && process.env.NODE_ENV !== 'production') 58 | options.isDev = isDev 59 | 60 | logger.info(`Initializing Yandex Metrika in ${isDev ? 'development' : 'production'} mode`) 61 | 62 | if (!options.id) { 63 | logger.error('No id provided.') 64 | } 65 | 66 | // Adds https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js 67 | options.metrikaUrl = (options.useCDN ? 'https://cdn.jsdelivr.net/npm/yandex-metrica-watch' : options.metrikaUrl) + '/tag.js' 68 | 69 | if (options.useRuntimeConfig) { 70 | nuxt.options.runtimeConfig.public[CONFIG_KEY] = defu(nuxt.options.runtimeConfig.public[CONFIG_KEY], options) 71 | } 72 | 73 | addTemplate({ 74 | filename: 'yandex-metrika.options.mjs', 75 | getContents: () => { 76 | return `export default () => Promise.resolve(${JSON.stringify( 77 | options.useRuntimeConfig ? nuxt.options.runtimeConfig.public[CONFIG_KEY] : options || {} 78 | )})` 79 | } 80 | }) 81 | 82 | // Script preload 83 | const head = nuxt.options.app.head 84 | head.script = head.script || [] 85 | 86 | logger.debug(`Yandex Metrika script URL: ${options.metrikaUrl}`) 87 | if (!isDev) { 88 | const scriptObj: Parameters[number] = { 89 | src: options.metrikaUrl, 90 | async: true, 91 | tagPosition: 'head' 92 | } 93 | if (options.partytown) { 94 | scriptObj.type = 'text/partytown' 95 | } 96 | head.script.push(scriptObj) 97 | } 98 | 99 | const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url)) 100 | 101 | // Register plugin 102 | addPlugin({ 103 | src: resolve(runtimeDir, 'plugin'), 104 | mode: 'client' 105 | }) 106 | } 107 | }) 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yandex Metrika for Nuxt 3 2 | [![npm version][npm-version-src]][npm-version-href] 3 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 4 | [![License][license-src]][license-href] 5 | 6 | ## Disclaimer 7 | 8 | This package is a fork for those who don't want to wait for the official release of a Yandex Metrika module. 9 | 10 | The module was created by Nuxt Community and rewritten by dankerow to support Nuxt 3. All credit belongs to: 11 | 12 | - [Official Nuxt Community module for Yandex Metrika](https://github.com/nuxt-community/yandex-metrika-module) 13 | - [dankerow's fork of Yandex Metrika to support Nuxt 3](https://github.com/dankerow/yandex-metrika-module) 14 | 15 | > This package includes precompiled scripts to let people integrate Yandex Metrika into their project. There's no need to compile anything, it is ready to be used out of the box. 16 | 17 | ## Route change events by default 18 | 19 | This module automatically sends first page and route change events to Yandex Metrika. 20 | 21 | **Note:** Yandex Metrika is not enabled in dev mode. 22 | You can set environment variable `NODE_ENV` to `production` for testing in dev mode. 23 | 24 | ## Setup 25 | 26 | - Add `yandex-metrika-module-nuxt3` dependency using yarn or npm to your project 27 | - Add `yandex-metrika-module-nuxt3` to `modules` section of `nuxt.config.js` 28 | 29 | ```js 30 | { 31 | modules: ['yandex-metrika-module-nuxt3'] 32 | } 33 | ``` 34 | 35 | ## Configure 36 | 37 | You can pass options directly in module declaration: 38 | 39 | ```ts 40 | { 41 | modules: [ 42 | [ 43 | 'yandex-metrika-module-nuxt3', 44 | { 45 | id: 'XXXXXX', 46 | webvisor: true, 47 | // consoleLog: true, 48 | // clickmap: true, 49 | // useCDN: false, 50 | // trackLinks: true, 51 | // accurateTrackBounce: true, 52 | } 53 | ] 54 | ] 55 | } 56 | ``` 57 | 58 | Or you can specify `yandexMetrika` key: 59 | 60 | ```ts 61 | { 62 | modules: ['yandex-metrika-module-nuxt3'], 63 | yandexMetrika: { 64 | id: 'XXXXXX', 65 | // ... 66 | } 67 | } 68 | ``` 69 | 70 | In Nuxt 2.13+, you can also use public runtime config: 71 | 72 | ```js 73 | { 74 | modules: ['yandex-metrika-module-nuxt3'], 75 | publicRuntimeConfig: { 76 | yandexMetrika: { 77 | id: process.env.YANDEX_METRIKA_ID, 78 | // ... 79 | } 80 | } 81 | } 82 | ``` 83 | 84 | ## Options 85 | 86 | For more information: 87 | - [Documentation for Ya.Metrika](https://yandex.com/support/metrica/code/counter-initialize.html) 88 | - [hit method](https://yandex.com/support/metrica/objects/hit.html) 89 | 90 | | Name | Default value | Type | Description | 91 | |---------------------|---------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------| 92 | | accurateTrackBounce | true | Boolean | Number |Accurate bounce rate The parameter can accept these values: true — Enable the accurate bounce rate, with a non-bounce event registered after 15000 ms (15 s). false — Don't enable the accurate bounce rate. (integer) — Enable the accurate bounce rate. Non-bounce events are recorded after ms.| 93 | | childIframe | false | Boolean | Whether to record iframe contents without a tag in a child window | 94 | | clickmap | true | Boolean | Whether to collect data for a click map | 95 | | defer | false | Boolean | Whether to disable automatically sending data during tag initialization | 96 | | ecommerce | false | Boolean | String | Array|Collect data for e-commerce — Ecommerce. true — Enable e-commerce data collection. Data is transmitted via a JavaScript array named dataLayer in the global namespace (window.dataLayer) false — Disable Ecommerce data collection. (String) — Enable Ecommerce data collection. Data is transmitted via a JavaScript array named in the global namespace (window.) (Array) — Enable Ecommerce data collection. Data is transmitted via a JavaScript | 97 | | params | — | Object | Array |Session parameters transmitted during tag initialization To transmit session parameters at any other time, use the params method| 98 | | userParams | — | Object | Parameters of site users that are transmitted when initializing the tag To transmit user parameters at any other time, use the userParams method | 99 | | trackHash | false | Boolean | Hash tracking in the browser's address bar | 100 | | trackLinks | true | Boolean | Track clicks on outbound links | 101 | | trustedDomains | — | Array | Indicates a trusted domain for recording the contents of a child iframe. Contains the domain address of the parent window | 102 | | type | 0 | Number | Tag type. 1 for YAN | 103 | | webvisor | false | Boolean | Whether to use Session Replay | 104 | | triggerEvent | false | Boolean | Whether to check if the tag is ready | 105 | 106 | ## Development 107 | 108 | - Clone this repository 109 | - Install dependencies using `yarn install` 110 | - Run `yarn dev:prepare` to generate type stubs. 111 | - Use `yarn dev` to start [playground](./playground) in development mode. 112 | 113 | ## License 114 | 115 | [MIT License](./LICENSE) 116 | 117 | 118 | [npm-version-src]: https://img.shields.io/npm/v/yandex-metrika-module-nuxt3/latest.svg?style=flat-square 119 | [npm-version-href]: https://npmjs.com/package/yandex-metrika-module-nuxt3 120 | 121 | [npm-downloads-src]: https://img.shields.io/npm/dt/yandex-metrika-module-nuxt3.svg?style=flat-square 122 | [npm-downloads-href]: https://npmjs.com/package/yandex-metrika-module-nuxt3 123 | 124 | [license-src]: https://img.shields.io/npm/l/yandex-metrika-module-nuxt3.svg?style=flat-square 125 | [license-href]: https://npmjs.com/package/yandex-metrika-module-nuxt3 126 | -------------------------------------------------------------------------------- /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 | ## 1.4.0 (2022-02-26) 6 | 7 | 8 | ### ⚠ BREAKING CHANGES 9 | 10 | * **yandex-metrika:** Using new tag.js script 11 | 12 | ### Features 13 | 14 | * **yandex-metrika:** add support use cdn ([#194](https://github.com/nuxt/modules/issues/194)) ([749c249](https://github.com/nuxt/modules/commit/749c249f927fc97e0d6e79c2d0409f0dd255b45e)) 15 | * **yandex-metrika:** replace deprecated `watch.js` with new `tag.js` ([#313](https://github.com/nuxt/modules/issues/313)) ([c37814d](https://github.com/nuxt/modules/commit/c37814df45509c813199f22052022b2d1d63fe7e)) 16 | * **yandex-metrika:** support `yandexMetrika` option ([#375](https://github.com/nuxt/modules/issues/375)) ([1d6c851](https://github.com/nuxt/modules/commit/1d6c8516fb3dd6643b340928c1e63ef6fb35dffb)) 17 | * **yandex-metrika:** support runtime config ([#384](https://github.com/nuxt/modules/issues/384)) ([d8913e6](https://github.com/nuxt/modules/commit/d8913e6e873a59807761be690a722ea0d6e34a9d)) 18 | * **yandex-metrika:** update loading script ([#371](https://github.com/nuxt/modules/issues/371)) ([f138add](https://github.com/nuxt/modules/commit/f138add7e81aa69571a93f4bd217a46d79d31ffc)) 19 | * **yandex-metrika:** use new version of yandex metrics code ([#363](https://github.com/nuxt/modules/issues/363)) ([b6785d9](https://github.com/nuxt/modules/commit/b6785d95cb5ca4f1b57d896022fb6474a5bbb6d9)) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * correct homepage URLs ([#282](https://github.com/nuxt/modules/issues/282)) ([7c2f965](https://github.com/nuxt/modules/commit/7c2f9659ba283ab01a74362701482cabadb6a5c9)) 25 | * html validate error ([#253](https://github.com/nuxt/modules/issues/253)) ([bca2d70](https://github.com/nuxt/modules/commit/bca2d70635dd87f9fffa0c9074538ecf31701ce8)) 26 | * **yandex-metrika:** constructor name for `tag.js` ([#318](https://github.com/nuxt/modules/issues/318)) ([c8277a8](https://github.com/nuxt/modules/commit/c8277a8cb3251cec975ea93b2d328d2eeef21f9e)) 27 | * **yandex-metrika:** correct class existence check ([#319](https://github.com/nuxt/modules/issues/319)) ([2ef472d](https://github.com/nuxt/modules/commit/2ef472db3a662289104cb5a18e7e610b4e300509)) 28 | * **yandex-metrika:** preload and async ([#325](https://github.com/nuxt/modules/issues/325)) ([b442460](https://github.com/nuxt/modules/commit/b442460e59eb4004a560766cb7bb472924ae260c)) 29 | * **yandex-metrika:** prepend router base to paths ([#386](https://github.com/nuxt/modules/issues/386)) ([df421a5](https://github.com/nuxt/modules/commit/df421a5e3b0795a13b27865c3725d9248408eb8f)) 30 | 31 | # [1.3.0](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.2.0...@nuxtjs/yandex-metrika@1.3.0) (2020-08-27) 32 | 33 | 34 | ### Features 35 | 36 | * **yandex-metrika:** support `yandexMetrika` option ([#375](https://github.com/nuxt/modules/issues/375)) ([85feb99](https://github.com/nuxt/modules/commit/85feb990ef190655a1cc5823f89e6a228f5b0133)) 37 | 38 | 39 | 40 | 41 | 42 | # [1.2.0](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.1.0...@nuxtjs/yandex-metrika@1.2.0) (2020-07-23) 43 | 44 | 45 | ### Features 46 | 47 | * **yandex-metrika:** update loading script ([#371](https://github.com/nuxt/modules/issues/371)) ([3e9711c](https://github.com/nuxt/modules/commit/3e9711c61cf1be2a4c6c75c35c3838c721764626)) 48 | 49 | 50 | 51 | 52 | 53 | # [1.1.0](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.0.3...@nuxtjs/yandex-metrika@1.1.0) (2020-07-14) 54 | 55 | 56 | ### Features 57 | 58 | * **yandex-metrika:** use new version of yandex metrics code ([#363](https://github.com/nuxt/modules/issues/363)) ([a08b725](https://github.com/nuxt/modules/commit/a08b72518ca79c1ee346d902ad204437e3f03534)) 59 | 60 | 61 | 62 | 63 | 64 | ## [1.0.3](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.0.2...@nuxtjs/yandex-metrika@1.0.3) (2019-11-01) 65 | 66 | 67 | ### Bug Fixes 68 | 69 | * **yandex-metrika:** preload and async ([#325](https://github.com/nuxt/modules/issues/325)) ([4d61053](https://github.com/nuxt/modules/commit/4d61053)) 70 | 71 | 72 | 73 | 74 | 75 | ## [1.0.2](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.0.1...@nuxtjs/yandex-metrika@1.0.2) (2019-10-09) 76 | 77 | 78 | ### Bug Fixes 79 | 80 | * **yandex-metrika:** correct class existence check ([#319](https://github.com/nuxt/modules/issues/319)) ([39dd9d7](https://github.com/nuxt/modules/commit/39dd9d7)) 81 | 82 | 83 | 84 | 85 | 86 | ## [1.0.1](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@1.0.0...@nuxtjs/yandex-metrika@1.0.1) (2019-10-08) 87 | 88 | 89 | ### Bug Fixes 90 | 91 | * **yandex-metrika:** constructor name for `tag.js` ([#318](https://github.com/nuxt/modules/issues/318)) ([1f9eb5f](https://github.com/nuxt/modules/commit/1f9eb5f)) 92 | 93 | 94 | 95 | 96 | 97 | # [1.0.0](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.1.2...@nuxtjs/yandex-metrika@1.0.0) (2019-10-07) 98 | 99 | 100 | ### Features 101 | 102 | * **yandex-metrika:** replace deprecated `watch.js` with new `tag.js` ([#313](https://github.com/nuxt/modules/issues/313)) ([6bb2522](https://github.com/nuxt/modules/commit/6bb2522)) 103 | 104 | 105 | ### BREAKING CHANGES 106 | 107 | * **yandex-metrika:** Using new tag.js script 108 | 109 | 110 | 111 | 112 | 113 | ## [0.1.2](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.1.1...@nuxtjs/yandex-metrika@0.1.2) (2019-05-28) 114 | 115 | 116 | ### Bug Fixes 117 | 118 | * correct homepage URLs ([#282](https://github.com/nuxt/modules/issues/282)) ([960f933](https://github.com/nuxt/modules/commit/960f933)) 119 | 120 | 121 | 122 | 123 | 124 | ## [0.1.1](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.1.0...@nuxtjs/yandex-metrika@0.1.1) (2019-01-22) 125 | 126 | 127 | ### Bug Fixes 128 | 129 | * html validate error ([#253](https://github.com/nuxt/modules/issues/253)) ([0b2ee5e](https://github.com/nuxt/modules/commit/0b2ee5e)) 130 | 131 | 132 | 133 | 134 | 135 | 136 | # [0.1.0](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.0.5...@nuxtjs/yandex-metrika@0.1.0) (2018-03-05) 137 | 138 | 139 | ### Features 140 | 141 | * **yandex-metrika:** add support use cdn ([#194](https://github.com/nuxt/modules/issues/194)) ([dc06e67](https://github.com/nuxt/modules/commit/dc06e67)) 142 | 143 | 144 | 145 | 146 | 147 | ## [0.0.5](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.0.4...@nuxtjs/yandex-metrika@0.0.5) (2017-11-20) 148 | 149 | 150 | 151 | 152 | **Note:** Version bump only for package @nuxtjs/yandex-metrika 153 | 154 | 155 | ## [0.0.4](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.0.3...@nuxtjs/yandex-metrika@0.0.4) (2017-09-22) 156 | 157 | 158 | ### Bug Fixes 159 | 160 | * **yandex-metrika:** fix ReferenceError, fix duplicate initial hit (#147) ([c6c5a81](https://github.com/nuxt/modules/commit/c6c5a81)), closes [#147](https://github.com/nuxt/modules/issues/147) 161 | 162 | 163 | 164 | 165 | 166 | ## [0.0.3](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.0.2...@nuxtjs/yandex-metrika@0.0.3) (2017-09-21) 167 | 168 | 169 | ### Bug Fixes 170 | 171 | * **yandex-metrika:** script initialization (#146) ([b59ae54](https://github.com/nuxt/modules/commit/b59ae54)) 172 | * **yandex-metrika:** fix undefined vars, prevent race condition (#143) ([23b7b58](https://github.com/nuxt/modules/commit/23b7b58)), closes [#143](https://github.com/nuxt/modules/issues/143) 173 | 174 | 175 | 176 | 177 | 178 | ## [0.0.2](https://github.com/nuxt/modules/compare/@nuxtjs/yandex-metrika@0.0.1...@nuxtjs/yandex-metrika@0.0.2) (2017-08-29) 179 | 180 | 181 | ### Bug Fixes 182 | 183 | * **yandex-metrika:** fix string interpolation & plugin options (#115) ([72f0982](https://github.com/nuxt/modules/commit/72f0982)), closes [#115](https://github.com/nuxt/modules/issues/115) 184 | 185 | 186 | 187 | 188 | 189 | ## 0.0.1 (2017-05-30) 190 | 191 | 192 | 193 | 194 | # Change Log 195 | 196 | All notable changes to this project will be documented in this file. 197 | See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 198 | --------------------------------------------------------------------------------