mirror of
https://github.com/tachiyomiorg/website.git
synced 2024-12-21 07:31:58 +01:00
Add initial analytics for downloads (#43)
* Add initial analytics for downloads. * Change analytics events and enable it. * Change to a custom ID. * Use custom analytics plugin. * Bound gtag to window. * Update id for `kodo.moe`.
This commit is contained in:
parent
c410fcbffe
commit
0af948cd8d
@ -52,6 +52,7 @@
|
|||||||
"@mdit/plugin-img-size": "^0.4.8",
|
"@mdit/plugin-img-size": "^0.4.8",
|
||||||
"@mdit/plugin-include": "^0.4.8",
|
"@mdit/plugin-include": "^0.4.8",
|
||||||
"@resvg/resvg-js": "^2.4.1",
|
"@resvg/resvg-js": "^2.4.1",
|
||||||
|
"@types/gtag.js": "^0.0.13",
|
||||||
"@types/lodash.groupby": "^4.6.7",
|
"@types/lodash.groupby": "^4.6.7",
|
||||||
"@types/markdown-it": "^13.0.1",
|
"@types/markdown-it": "^13.0.1",
|
||||||
"@types/node": "^20.6.0",
|
"@types/node": "^20.6.0",
|
||||||
@ -71,7 +72,6 @@
|
|||||||
"unplugin-element-plus": "^0.8.0",
|
"unplugin-element-plus": "^0.8.0",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vitepress": "1.0.0-rc.11",
|
"vitepress": "1.0.0-rc.11",
|
||||||
"vitepress-plugin-google-analytics": "^1.0.2",
|
|
||||||
"vitepress-plugin-tabs": "^0.3.0",
|
"vitepress-plugin-tabs": "^0.3.0",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-eslint-parser": "^9.3.1",
|
"vue-eslint-parser": "^9.3.1",
|
||||||
|
22
website/pnpm-lock.yaml
generated
22
website/pnpm-lock.yaml
generated
@ -1,9 +1,5 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify-prerendered/vue-mdi':
|
'@iconify-prerendered/vue-mdi':
|
||||||
specifier: ^0.23.1689058119
|
specifier: ^0.23.1689058119
|
||||||
@ -64,6 +60,9 @@ devDependencies:
|
|||||||
'@resvg/resvg-js':
|
'@resvg/resvg-js':
|
||||||
specifier: ^2.4.1
|
specifier: ^2.4.1
|
||||||
version: 2.4.1
|
version: 2.4.1
|
||||||
|
'@types/gtag.js':
|
||||||
|
specifier: ^0.0.13
|
||||||
|
version: 0.0.13
|
||||||
'@types/lodash.groupby':
|
'@types/lodash.groupby':
|
||||||
specifier: ^4.6.7
|
specifier: ^4.6.7
|
||||||
version: 4.6.7
|
version: 4.6.7
|
||||||
@ -121,9 +120,6 @@ devDependencies:
|
|||||||
vitepress:
|
vitepress:
|
||||||
specifier: 1.0.0-rc.11
|
specifier: 1.0.0-rc.11
|
||||||
version: 1.0.0-rc.11(@algolia/client-search@4.19.1)(@types/node@20.6.0)(axios@1.5.0)(search-insights@2.8.2)(stylus@0.60.0)
|
version: 1.0.0-rc.11(@algolia/client-search@4.19.1)(@types/node@20.6.0)(axios@1.5.0)(search-insights@2.8.2)(stylus@0.60.0)
|
||||||
vitepress-plugin-google-analytics:
|
|
||||||
specifier: ^1.0.2
|
|
||||||
version: 1.0.2
|
|
||||||
vitepress-plugin-tabs:
|
vitepress-plugin-tabs:
|
||||||
specifier: ^0.3.0
|
specifier: ^0.3.0
|
||||||
version: 0.3.0(vitepress@1.0.0-rc.11)(vue@3.3.4)
|
version: 0.3.0(vitepress@1.0.0-rc.11)(vue@3.3.4)
|
||||||
@ -1183,6 +1179,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/gtag.js@0.0.13:
|
||||||
|
resolution: {integrity: sha512-yOXFkfnt1DQr1v9B4ERulJOGnbdVqnPHV8NG4nkQhnu4qbrJecQ06DlaKmSjI3nzIwBj5U9/X61LY4sTc2KbaQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/json-schema@7.0.12:
|
/@types/json-schema@7.0.12:
|
||||||
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -5472,10 +5472,6 @@ packages:
|
|||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitepress-plugin-google-analytics@1.0.2:
|
|
||||||
resolution: {integrity: sha512-ri8bFUAmt3c/DtPrALauGBIUr2gIJ11c1qNRhwd3/+aiuYZBfQpOosSxcO1AswgwRxP9FwBS6Z7jgdDVyXb2hA==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vitepress-plugin-tabs@0.3.0(vitepress@1.0.0-rc.11)(vue@3.3.4):
|
/vitepress-plugin-tabs@0.3.0(vitepress@1.0.0-rc.11)(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-3dKsBuP6PDzcFHgUtNCwwCs3bYoZduj7AcQkT9JfAKTRAKPCNmjiNInPT3IZ7AihL0SJNoQ3liz/e97z8oo+XA==}
|
resolution: {integrity: sha512-3dKsBuP6PDzcFHgUtNCwwCs3bYoZduj7AcQkT9JfAKTRAKPCNmjiNInPT3IZ7AihL0SJNoQ3liz/e97z8oo+XA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5728,3 +5724,7 @@ packages:
|
|||||||
/yoga-wasm-web@0.3.3:
|
/yoga-wasm-web@0.3.3:
|
||||||
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
|
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
/// <reference types="@types/gtag.js" />
|
||||||
|
|
||||||
import { computed, onMounted, ref } from "vue"
|
import { computed, onMounted, ref } from "vue"
|
||||||
import { data as release } from "../data/release.data"
|
import { data as release } from "../data/release.data"
|
||||||
|
|
||||||
@ -20,6 +22,16 @@ const isAndroid = ref(true)
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
isAndroid.value = !!navigator.userAgent.match(/android/i)
|
isAndroid.value = !!navigator.userAgent.match(/android/i)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function handleAnalytics(type: "preview" | "stable") {
|
||||||
|
window.gtag?.("event", "Download", {
|
||||||
|
event_category: "App",
|
||||||
|
event_label: type === "stable" ? "Stable" : "Preview",
|
||||||
|
version: type === "stable"
|
||||||
|
? release.stable.tag_name
|
||||||
|
: release.preview.tag_name,
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -47,12 +59,22 @@ onMounted(() => {
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<div class="download-buttons">
|
<div class="download-buttons">
|
||||||
<a class="download-button primary" :download="downloadInformation.stable.asset?.name" :href="downloadInformation.stable.asset?.browser_download_url">
|
<a
|
||||||
|
class="download-button primary"
|
||||||
|
:download="downloadInformation.stable.asset?.name"
|
||||||
|
:href="downloadInformation.stable.asset?.browser_download_url"
|
||||||
|
@click="handleAnalytics('stable')"
|
||||||
|
>
|
||||||
<IconDownload />
|
<IconDownload />
|
||||||
<span class="text">Stable</span>
|
<span class="text">Stable</span>
|
||||||
<span class="version">{{ downloadInformation.stable.tagName }}</span>
|
<span class="version">{{ downloadInformation.stable.tagName }}</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="download-button secondary" :download="downloadInformation.preview.asset?.name" :href="downloadInformation.preview.asset?.browser_download_url">
|
<a
|
||||||
|
class="download-button secondary"
|
||||||
|
:download="downloadInformation.preview.asset?.name"
|
||||||
|
:href="downloadInformation.preview.asset?.browser_download_url"
|
||||||
|
@click="handleAnalytics('preview')"
|
||||||
|
>
|
||||||
<IconBugReport />
|
<IconBugReport />
|
||||||
<span class="text">Preview</span>
|
<span class="text">Preview</span>
|
||||||
<span class="version">{{ downloadInformation.preview.tagName }}</span>
|
<span class="version">{{ downloadInformation.preview.tagName }}</span>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
/// <reference types="@types/gtag.js" />
|
||||||
|
|
||||||
import { computed, toRefs } from "vue"
|
import { computed, toRefs } from "vue"
|
||||||
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
|
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
|
||||||
|
|
||||||
@ -19,6 +21,14 @@ const iconUrl = computed(() => {
|
|||||||
const apkUrl = computed(() => {
|
const apkUrl = computed(() => {
|
||||||
return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/apk/${item.value.apk}`
|
return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/apk/${item.value.apk}`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function handleAnalytics() {
|
||||||
|
window.gtag?.("event", "Download", {
|
||||||
|
event_category: "Extension",
|
||||||
|
event_label: pkgName.value,
|
||||||
|
version: item.value.version,
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -35,7 +45,15 @@ const apkUrl = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
<Badge v-if="pkgIsNsfw" type="danger" :text="item.version" title="This extension contains NSFW entries." />
|
<Badge v-if="pkgIsNsfw" type="danger" :text="item.version" title="This extension contains NSFW entries." />
|
||||||
<Badge v-else type="info" :text="item.version" title="This extension is free from NSFW entries." />
|
<Badge v-else type="info" :text="item.version" title="This extension is free from NSFW entries." />
|
||||||
<a :href="apkUrl" class="extension-download" title="Download APK" download>↓</a>
|
<a
|
||||||
|
:href="apkUrl"
|
||||||
|
class="extension-download"
|
||||||
|
title="Download APK"
|
||||||
|
:download="item.apk"
|
||||||
|
@click="handleAnalytics"
|
||||||
|
>
|
||||||
|
↓
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -11,12 +11,11 @@ import { VueQueryPlugin } from "@tanstack/vue-query"
|
|||||||
|
|
||||||
import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"
|
import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"
|
||||||
|
|
||||||
// Import components
|
// Import icon components
|
||||||
import { IconBugReport, IconDownload, IconNewspaperVariant } from "@iconify-prerendered/vue-mdi"
|
import { IconBugReport, IconDownload, IconNewspaperVariant } from "@iconify-prerendered/vue-mdi"
|
||||||
import Layout from "./Layout.vue"
|
|
||||||
|
|
||||||
// Import Google Analytics plugin
|
import analytics from "./plugin/analytics"
|
||||||
import googleAnalytics from "vitepress-plugin-google-analytics"
|
import Layout from "./Layout.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
extends: DefaultTheme,
|
extends: DefaultTheme,
|
||||||
@ -26,7 +25,7 @@ export default {
|
|||||||
app.component("IconDownload", IconDownload)
|
app.component("IconDownload", IconDownload)
|
||||||
app.component("IconNewspaperVariant", IconNewspaperVariant)
|
app.component("IconNewspaperVariant", IconNewspaperVariant)
|
||||||
app.component("IconBugReport", IconBugReport)
|
app.component("IconBugReport", IconBugReport)
|
||||||
// googleAnalytics({ id: "G-2CBXXM1Y86" })
|
analytics({ id: "G-J1GE7WPJEX" })
|
||||||
},
|
},
|
||||||
Layout,
|
Layout,
|
||||||
}
|
}
|
||||||
|
37
website/src/.vitepress/theme/plugin/analytics.ts
Normal file
37
website/src/.vitepress/theme/plugin/analytics.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Code based on vitepress-plugin-google-analytics.
|
||||||
|
// Customized as the plugin did not consider the script loading time.
|
||||||
|
// https://github.com/ZhongxuYang/vitepress-plugin-google-analytics
|
||||||
|
|
||||||
|
function mountGoogleAnalytics(id: string) {
|
||||||
|
if (("dataLayer" in window && window.gtag) || window.location.hostname === "localhost") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const analyticsScript = document.createElement("script")
|
||||||
|
|
||||||
|
analyticsScript.addEventListener("load", () => {
|
||||||
|
// @ts-expect-error Missing types
|
||||||
|
window.dataLayer = window.dataLayer || []
|
||||||
|
function gtag(..._args: any[]) {
|
||||||
|
// @ts-expect-error Missing types
|
||||||
|
// eslint-disable-next-line prefer-rest-params
|
||||||
|
window.dataLayer.push(arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag("js", new Date())
|
||||||
|
gtag("config", id)
|
||||||
|
|
||||||
|
window.gtag = gtag
|
||||||
|
})
|
||||||
|
|
||||||
|
analyticsScript.src = `https://www.googletagmanager.com/gtag/js?id=${id}`
|
||||||
|
|
||||||
|
document.body.appendChild(analyticsScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ({ id }: { id: string }) {
|
||||||
|
// eslint-disable-next-line n/prefer-global/process
|
||||||
|
if (process.env.NODE_ENV === "production" && id && typeof window !== "undefined") {
|
||||||
|
mountGoogleAnalytics(id)
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"lib": ["esnext", "dom"],
|
"lib": ["esnext", "dom"],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"types": ["vite/client"],
|
"types": ["vite/client", "@types/gtag.js"],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./docs/.vitepress/*"]
|
"@/*": ["./docs/.vitepress/*"]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user