@eox/pages-theme-eox 0.5.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Layout.vue +54 -5
- package/src/components/CTASection.vue +8 -0
- package/src/components/CookieBanner.vue +66 -0
- package/src/components/CookieSettings.vue +180 -0
- package/src/components/NotFound.vue +14 -0
- package/src/helpers.js +122 -0
- package/src/index.js +6 -0
- package/src/vitepressConfig.mjs +83 -1
package/package.json
CHANGED
package/src/Layout.vue
CHANGED
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
:href="withBase(item.link)"
|
|
108
108
|
:target="item.target"
|
|
109
109
|
:rel="item.rel"
|
|
110
|
+
@click="trackEvent(['CTA', 'Click', 'Nav', item.text])"
|
|
110
111
|
>
|
|
111
112
|
<span>{{ item.text }}</span>
|
|
112
113
|
<i
|
|
@@ -172,6 +173,14 @@
|
|
|
172
173
|
: 'border no-elevate white-text'
|
|
173
174
|
"
|
|
174
175
|
:style="i === 0 ? 'margin-left: 0 !important' : ''"
|
|
176
|
+
@click="
|
|
177
|
+
trackEvent([
|
|
178
|
+
'CTA',
|
|
179
|
+
'Click',
|
|
180
|
+
`Hero ${action.theme === 'brand' ? 'primary' : action.theme === 'secondary' ? 'secondary' : 'alt'}`,
|
|
181
|
+
action.text,
|
|
182
|
+
])
|
|
183
|
+
"
|
|
175
184
|
>
|
|
176
185
|
<span>{{ action.text }}</span>
|
|
177
186
|
<i v-if="action.theme !== 'alt'" class="mdi mdi-arrow-right"></i>
|
|
@@ -185,6 +194,12 @@
|
|
|
185
194
|
/>
|
|
186
195
|
</header>
|
|
187
196
|
</template>
|
|
197
|
+
<template #not-found>
|
|
198
|
+
<ClientOnly v-if="router.route.path === '/cookie-settings'">
|
|
199
|
+
<CookieSettings></CookieSettings>
|
|
200
|
+
</ClientOnly>
|
|
201
|
+
<NotFound v-else></NotFound>
|
|
202
|
+
</template>
|
|
188
203
|
<template #page-bottom>
|
|
189
204
|
<FeaturesGallery
|
|
190
205
|
v-if="page.relativePath.startsWith('features/')"
|
|
@@ -207,9 +222,21 @@
|
|
|
207
222
|
:href="theme.nav.find((i) => i.link.includes('contact')).link"
|
|
208
223
|
class="button small border no-margin"
|
|
209
224
|
style="color: var(--on-surface)"
|
|
225
|
+
@click="trackEvent(['CTA', 'Click', 'Footer', action.text])"
|
|
210
226
|
>{{ theme.nav.find((i) => i.link.includes("contact")).text }}</a
|
|
211
227
|
>
|
|
212
228
|
<p v-html="theme.footer.copyright"></p>
|
|
229
|
+
<p class="middle-align">
|
|
230
|
+
Powered by
|
|
231
|
+
<a
|
|
232
|
+
href="https://hub.eox.at"
|
|
233
|
+
target="_blank"
|
|
234
|
+
class="left-margin small-margin"
|
|
235
|
+
><img
|
|
236
|
+
src="https://hub.eox.at/hub/custom/logos/eoxhub.svg"
|
|
237
|
+
style="height: 25px"
|
|
238
|
+
/></a>
|
|
239
|
+
</p>
|
|
213
240
|
</div>
|
|
214
241
|
<div class="s12 l6">
|
|
215
242
|
<div class="grid large-line">
|
|
@@ -229,15 +256,32 @@
|
|
|
229
256
|
<p class="bold">Legal</p>
|
|
230
257
|
<p>
|
|
231
258
|
<a
|
|
232
|
-
href="
|
|
259
|
+
:href="
|
|
260
|
+
theme.theme.brandConfig?.legal?.about ||
|
|
261
|
+
'https://eox.at/impressum'
|
|
262
|
+
"
|
|
263
|
+
target="_blank"
|
|
264
|
+
class="link"
|
|
265
|
+
>About</a
|
|
266
|
+
>
|
|
267
|
+
</p>
|
|
268
|
+
<p>
|
|
269
|
+
<a
|
|
270
|
+
:href="
|
|
271
|
+
theme.theme.brandConfig?.legal?.termsAndConditions ||
|
|
272
|
+
'https://eox.at/impressum'
|
|
273
|
+
"
|
|
233
274
|
target="_blank"
|
|
234
275
|
class="link"
|
|
235
|
-
>
|
|
276
|
+
>Terms & Conditions</a
|
|
236
277
|
>
|
|
237
278
|
</p>
|
|
238
279
|
<p>
|
|
239
280
|
<a
|
|
240
|
-
href="
|
|
281
|
+
:href="
|
|
282
|
+
theme.theme.brandConfig?.legal?.privacyPolicy ||
|
|
283
|
+
'https://eox.at/privacy-notice'
|
|
284
|
+
"
|
|
241
285
|
target="_blank"
|
|
242
286
|
class="link"
|
|
243
287
|
>Privacy</a
|
|
@@ -250,6 +294,7 @@
|
|
|
250
294
|
<div class="large-space"></div>
|
|
251
295
|
</div>
|
|
252
296
|
</footer>
|
|
297
|
+
<CookieBanner v-if="theme.theme.brandConfig?.analytics"></CookieBanner>
|
|
253
298
|
<slot name="layout-bottom"></slot>
|
|
254
299
|
</template>
|
|
255
300
|
</Layout>
|
|
@@ -257,9 +302,11 @@
|
|
|
257
302
|
|
|
258
303
|
<script setup>
|
|
259
304
|
import DefaultTheme from "vitepress/theme";
|
|
305
|
+
import { useData, useRouter, withBase } from "vitepress";
|
|
306
|
+
import { trackEvent } from "./helpers";
|
|
260
307
|
const { Layout } = DefaultTheme;
|
|
261
|
-
import { useData, withBase } from "vitepress";
|
|
262
308
|
const { frontmatter, page, site, theme } = useData();
|
|
309
|
+
const router = useRouter();
|
|
263
310
|
|
|
264
311
|
if (!import.meta.env.SSR) {
|
|
265
312
|
const scrollListener = () => {
|
|
@@ -348,7 +395,7 @@ header {
|
|
|
348
395
|
margin-top: calc(var(--vp-nav-height) * -1);
|
|
349
396
|
padding-top: 10rem !important;
|
|
350
397
|
padding-bottom: 10rem !important;
|
|
351
|
-
height: 100svh;
|
|
398
|
+
height: calc(100svh + 2px);
|
|
352
399
|
max-height: 1000px;
|
|
353
400
|
}
|
|
354
401
|
@media (max-width: 1024px) {
|
|
@@ -368,6 +415,8 @@ header > img.background-image {
|
|
|
368
415
|
object-fit: cover;
|
|
369
416
|
opacity: 0.4;
|
|
370
417
|
z-index: 0;
|
|
418
|
+
border-top-left-radius: 0 !important;
|
|
419
|
+
border-top-right-radius: 0 !important;
|
|
371
420
|
}
|
|
372
421
|
header > .hero-container {
|
|
373
422
|
max-width: 1200px;
|
|
@@ -19,12 +19,18 @@
|
|
|
19
19
|
class="button extra small-margin"
|
|
20
20
|
:class="dark !== undefined ? 'surface' : 'primary'"
|
|
21
21
|
:href="primaryLink"
|
|
22
|
+
@click="
|
|
23
|
+
trackEvent(['CTA', 'Click', 'CTA Section Primary', primaryButton])
|
|
24
|
+
"
|
|
22
25
|
>{{ primaryButton }} <i class="mdi mdi-arrow-right"></i
|
|
23
26
|
></a>
|
|
24
27
|
<a
|
|
25
28
|
v-if="secondaryButton"
|
|
26
29
|
class="button extra small-margin secondary"
|
|
27
30
|
:href="secondaryLink"
|
|
31
|
+
@click="
|
|
32
|
+
trackEvent(['CTA', 'Click', 'CTA Section Secondary', secondaryButton])
|
|
33
|
+
"
|
|
28
34
|
>{{ secondaryButton }}<i class="mdi mdi-arrow-right"></i
|
|
29
35
|
></a>
|
|
30
36
|
<a
|
|
@@ -32,6 +38,7 @@
|
|
|
32
38
|
class="button border extra small-margin"
|
|
33
39
|
:class="dark !== undefined ? 'white-text' : ''"
|
|
34
40
|
:href="altLink"
|
|
41
|
+
@click="trackEvent(['CTA', 'Click', 'CTA Section Alt', altButton])"
|
|
35
42
|
>{{ altButton }}</a
|
|
36
43
|
>
|
|
37
44
|
</div>
|
|
@@ -42,6 +49,7 @@
|
|
|
42
49
|
</template>
|
|
43
50
|
|
|
44
51
|
<script setup>
|
|
52
|
+
import { trackEvent } from "../helpers";
|
|
45
53
|
const props = defineProps([
|
|
46
54
|
"dark",
|
|
47
55
|
"primaryButton",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="cookie-banner card surface medium-margin medium-padding medium-elevate no-round"
|
|
4
|
+
>
|
|
5
|
+
<p class="small-text">
|
|
6
|
+
We use optional cookies to improve your experience and for marketing. Read
|
|
7
|
+
our
|
|
8
|
+
<a
|
|
9
|
+
:href="theme.theme.brandConfig?.legal?.privacyPolicy"
|
|
10
|
+
target="_blank"
|
|
11
|
+
class="link"
|
|
12
|
+
>
|
|
13
|
+
privacy policy
|
|
14
|
+
</a>
|
|
15
|
+
or <a class="link" href="/cookie-settings">manage cookies</a>.
|
|
16
|
+
</p>
|
|
17
|
+
<nav>
|
|
18
|
+
<div class="max"></div>
|
|
19
|
+
<button class="small" @click="accept">Accept all</button>
|
|
20
|
+
<button class="small" @click="decline">Reject all</button>
|
|
21
|
+
</nav>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup>
|
|
26
|
+
import { onMounted } from "vue";
|
|
27
|
+
import { useData, useRouter } from "vitepress";
|
|
28
|
+
import {
|
|
29
|
+
acceptCookies,
|
|
30
|
+
declineCookies,
|
|
31
|
+
enableTracking,
|
|
32
|
+
showBanner,
|
|
33
|
+
} from "../helpers";
|
|
34
|
+
|
|
35
|
+
const { theme } = useData();
|
|
36
|
+
const router = useRouter();
|
|
37
|
+
|
|
38
|
+
const accept = () => acceptCookies(router);
|
|
39
|
+
const decline = () => declineCookies(router);
|
|
40
|
+
|
|
41
|
+
onMounted(() => {
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
// Basic tracking setup
|
|
44
|
+
if (
|
|
45
|
+
!document.cookie.includes("mtm_cookie_consent") &&
|
|
46
|
+
!document.cookie.includes("mtm_consent_removed")
|
|
47
|
+
) {
|
|
48
|
+
showBanner(true);
|
|
49
|
+
}
|
|
50
|
+
if (document.cookie.includes("mtm_cookie_consent")) {
|
|
51
|
+
enableTracking(true, router);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style>
|
|
58
|
+
.cookie-banner {
|
|
59
|
+
display: none;
|
|
60
|
+
position: fixed;
|
|
61
|
+
bottom: 0;
|
|
62
|
+
right: 0;
|
|
63
|
+
max-width: 512px;
|
|
64
|
+
z-index: 9999;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="VPPage">
|
|
3
|
+
<h1>Cookie Settings</h1>
|
|
4
|
+
<p>
|
|
5
|
+
We use cookies and similar technologies to improve your experience and for
|
|
6
|
+
marketing purposes. Review and manage your cookie settings below to
|
|
7
|
+
control your privacy. For more information on how we use cookies, please
|
|
8
|
+
see our
|
|
9
|
+
<a
|
|
10
|
+
class="link"
|
|
11
|
+
:href="
|
|
12
|
+
theme.theme.brandConfig?.legal?.privacyPolicy ||
|
|
13
|
+
'https://eox.at/privacy-notice/'
|
|
14
|
+
"
|
|
15
|
+
target="_blank"
|
|
16
|
+
>Privacy Policy</a
|
|
17
|
+
>.
|
|
18
|
+
</p>
|
|
19
|
+
<div
|
|
20
|
+
v-for="category in Object.keys(cookies)"
|
|
21
|
+
class="vertical-margin large-margin vertical-padding large-padding"
|
|
22
|
+
:id="category"
|
|
23
|
+
>
|
|
24
|
+
<nav>
|
|
25
|
+
<div class="max">
|
|
26
|
+
<h6 class="bold">{{ category }}</h6>
|
|
27
|
+
<p>
|
|
28
|
+
{{ cookies[category].description }}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
<label class="switch">
|
|
32
|
+
<input
|
|
33
|
+
type="checkbox"
|
|
34
|
+
:checked="cookies[category].required"
|
|
35
|
+
:disabled="cookies[category].required"
|
|
36
|
+
/>
|
|
37
|
+
<span></span>
|
|
38
|
+
</label>
|
|
39
|
+
</nav>
|
|
40
|
+
<details>
|
|
41
|
+
<summary class="middle-align">
|
|
42
|
+
<p class="primary-text bold">
|
|
43
|
+
<span class="view">View</span><span class="hide">Hide</span> cookies
|
|
44
|
+
</p>
|
|
45
|
+
<i class="small mdi mdi-chevron-down"></i>
|
|
46
|
+
</summary>
|
|
47
|
+
<table>
|
|
48
|
+
<thead>
|
|
49
|
+
<tr>
|
|
50
|
+
<th class="min">Name</th>
|
|
51
|
+
<th>Domain</th>
|
|
52
|
+
<th>Type</th>
|
|
53
|
+
<th>Duration</th>
|
|
54
|
+
</tr>
|
|
55
|
+
</thead>
|
|
56
|
+
<tbody>
|
|
57
|
+
<tr v-for="cookie in cookies[category].cookies">
|
|
58
|
+
<td class="min">
|
|
59
|
+
<code>{{ cookie.Name }}</code>
|
|
60
|
+
</td>
|
|
61
|
+
<td>{{ cookie.Domain }}</td>
|
|
62
|
+
<td>{{ cookie.Type }}</td>
|
|
63
|
+
<td>{{ cookie.Duration }}</td>
|
|
64
|
+
</tr>
|
|
65
|
+
</tbody>
|
|
66
|
+
</table>
|
|
67
|
+
</details>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="large-space"></div>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<style>
|
|
74
|
+
.page {
|
|
75
|
+
margin: auto;
|
|
76
|
+
width: 100%;
|
|
77
|
+
max-width: 1200px;
|
|
78
|
+
padding: 48px 24px 0;
|
|
79
|
+
}
|
|
80
|
+
details summary i {
|
|
81
|
+
transition: transform 0.3s ease-in-out;
|
|
82
|
+
}
|
|
83
|
+
details[open] summary i {
|
|
84
|
+
transform: rotate(180deg);
|
|
85
|
+
}
|
|
86
|
+
details summary p {
|
|
87
|
+
display: flex;
|
|
88
|
+
gap: 0.25rem;
|
|
89
|
+
}
|
|
90
|
+
details summary p span {
|
|
91
|
+
display: none;
|
|
92
|
+
}
|
|
93
|
+
details:not([open]) summary .view {
|
|
94
|
+
display: block;
|
|
95
|
+
}
|
|
96
|
+
details[open] summary .hide {
|
|
97
|
+
display: block;
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
100
|
+
|
|
101
|
+
<script setup>
|
|
102
|
+
import { onMounted } from "vue";
|
|
103
|
+
import { useData, useRouter } from "vitepress";
|
|
104
|
+
import { enableTracking, showBanner } from "../helpers.js";
|
|
105
|
+
const { theme } = useData();
|
|
106
|
+
const router = useRouter();
|
|
107
|
+
|
|
108
|
+
router.route.data.title = "Cookie Settings";
|
|
109
|
+
router.onBeforeRouteChange = (to) => {
|
|
110
|
+
if (to === "/cookie-settings") {
|
|
111
|
+
showBanner(false);
|
|
112
|
+
} else {
|
|
113
|
+
showBanner(
|
|
114
|
+
!document.cookie.includes("mtm_cookie_consent") &&
|
|
115
|
+
!document.cookie.includes("mtm_consent_removed"),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const cookies = {
|
|
121
|
+
Essential: {
|
|
122
|
+
description:
|
|
123
|
+
"Cookies that are strictly necessary for basic website or app functionality.",
|
|
124
|
+
required: true,
|
|
125
|
+
cookies: [
|
|
126
|
+
{
|
|
127
|
+
Name: "mtm_consent_removed",
|
|
128
|
+
Domain: `.${window.location.host}`,
|
|
129
|
+
Type: "Opt-out management",
|
|
130
|
+
Duration: "13 months",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
Name: "mtm_consent",
|
|
134
|
+
Domain: `.${window.location.host}`,
|
|
135
|
+
Type: "Consent management",
|
|
136
|
+
Duration: "13 months",
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
Analytics: {
|
|
141
|
+
description:
|
|
142
|
+
"Cookies that are required for analyzing website or app usage.",
|
|
143
|
+
cookies: [
|
|
144
|
+
{
|
|
145
|
+
Name: "_pk_id",
|
|
146
|
+
Domain: `.${window.location.host}`,
|
|
147
|
+
Type: "First-party website analytics",
|
|
148
|
+
Duration: "13 months",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
Name: "_pk_ses",
|
|
152
|
+
Domain: `.${window.location.host}`,
|
|
153
|
+
Type: "First-party website analytics",
|
|
154
|
+
Duration: "30 minutes",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
onMounted(() => {
|
|
161
|
+
setTimeout(() => {
|
|
162
|
+
showBanner(false);
|
|
163
|
+
|
|
164
|
+
const analyticsOpt = document.querySelector("#Analytics input");
|
|
165
|
+
analyticsOpt.checked = document.cookie.includes("mtm_cookie_consent");
|
|
166
|
+
|
|
167
|
+
analyticsOpt.addEventListener("input", () => {
|
|
168
|
+
if (analyticsOpt.checked) {
|
|
169
|
+
_paq.push(["forgetUserOptOut"]);
|
|
170
|
+
_paq.push(["setCookieConsentGiven"]);
|
|
171
|
+
_paq.push(["rememberCookieConsentGiven"]);
|
|
172
|
+
enableTracking(true, router);
|
|
173
|
+
} else {
|
|
174
|
+
_paq.push(["optUserOut"]);
|
|
175
|
+
enableTracking(false, router);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="VPPage">
|
|
3
|
+
<h1>404</h1>
|
|
4
|
+
<p>The page you requested was not found.</p>
|
|
5
|
+
<div class="small-space"></div>
|
|
6
|
+
<nav>
|
|
7
|
+
<a class="button" href="/">
|
|
8
|
+
<i class="mdi mdi-arrow-left"></i>
|
|
9
|
+
<span>Back to home</span>
|
|
10
|
+
</a>
|
|
11
|
+
</nav>
|
|
12
|
+
<div class="large-space"></div>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
package/src/helpers.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { watch } from "vue";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Track Matomo event with array of four primary components
|
|
5
|
+
*
|
|
6
|
+
* - Category (Required) – This describes the type of events you want to track. For example, Link Clicks, Videos, Outbound Links, and Form Events.
|
|
7
|
+
* - Action (Required) – This is the specific action that is taken. For example, with the Video category, you might have a Play, Pause and Complete action.
|
|
8
|
+
* - Name (Optional – Recommended) – This is usually the title of the element that is being interacted with, to aid with analysis. For example, it could be the name of a Video that was played or the specific form that is being submitted.
|
|
9
|
+
* - Value (Optional) – This is a numeric value and is often added dynamically. It could be the cost of a product that is added to a cart, or the completion percentage of a video.
|
|
10
|
+
*
|
|
11
|
+
* See https://matomo.org/faq/reports/the-anatomy-of-an-event/
|
|
12
|
+
*
|
|
13
|
+
* @param {Array<string>} eventDetails
|
|
14
|
+
*/
|
|
15
|
+
export const trackEvent = (eventDetails) => {
|
|
16
|
+
if (!import.meta.env.SSR) {
|
|
17
|
+
_paq.push(["trackEvent", ...eventDetails]);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Accept cookies
|
|
23
|
+
*/
|
|
24
|
+
export const acceptCookies = (router) => {
|
|
25
|
+
_paq.push(["rememberCookieConsentGiven"]);
|
|
26
|
+
showBanner(false);
|
|
27
|
+
enableTracking(true, router);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Decline cookies
|
|
32
|
+
*/
|
|
33
|
+
export const declineCookies = (router) => {
|
|
34
|
+
_paq.push(["forgetCookieConsentGiven"]);
|
|
35
|
+
_paq.push(["optUserOut"]);
|
|
36
|
+
showBanner(false);
|
|
37
|
+
enableTracking(false, router);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Show/hide banner
|
|
42
|
+
*
|
|
43
|
+
* @param show Boolean
|
|
44
|
+
*/
|
|
45
|
+
export const showBanner = (show) => {
|
|
46
|
+
document.querySelector(".cookie-banner").style.display = show
|
|
47
|
+
? "block"
|
|
48
|
+
: "none";
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Enables tracking listeners
|
|
53
|
+
*
|
|
54
|
+
* @param {Boolean} enabled
|
|
55
|
+
* @param {router} router
|
|
56
|
+
*/
|
|
57
|
+
export const enableTracking = (enabled, router) => {
|
|
58
|
+
trackPageScrolling(enabled, router);
|
|
59
|
+
trackRouterNavigation(router);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Track page scrolling depth
|
|
64
|
+
*
|
|
65
|
+
* @param enabled Boolean
|
|
66
|
+
*/
|
|
67
|
+
export const trackPageScrolling = (enabled, router) => {
|
|
68
|
+
function getScrollPercent() {
|
|
69
|
+
const h = document.documentElement,
|
|
70
|
+
b = document.body,
|
|
71
|
+
st = "scrollTop",
|
|
72
|
+
sh = "scrollHeight";
|
|
73
|
+
return ((h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight)) * 100;
|
|
74
|
+
}
|
|
75
|
+
const scrollTargets = {
|
|
76
|
+
25: [],
|
|
77
|
+
50: [],
|
|
78
|
+
75: [],
|
|
79
|
+
100: [],
|
|
80
|
+
};
|
|
81
|
+
const scrollListener = () => {
|
|
82
|
+
Object.keys(scrollTargets).forEach((target) => {
|
|
83
|
+
if (
|
|
84
|
+
getScrollPercent() >= parseInt(target) &&
|
|
85
|
+
!scrollTargets[target].includes(router.route.path)
|
|
86
|
+
) {
|
|
87
|
+
scrollTargets[target].push(router.route.path);
|
|
88
|
+
trackEvent([
|
|
89
|
+
"Interaction",
|
|
90
|
+
"Scroll Depth",
|
|
91
|
+
router.route.path,
|
|
92
|
+
`${target}%`,
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
if (enabled) {
|
|
98
|
+
document.addEventListener("scroll", scrollListener);
|
|
99
|
+
} else {
|
|
100
|
+
document.removeEventListener("scroll", scrollListener);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Track user navigation from one page to another
|
|
106
|
+
*
|
|
107
|
+
* @param enabled Boolean
|
|
108
|
+
*/
|
|
109
|
+
export const trackRouterNavigation = (router) => {
|
|
110
|
+
const trackNavigation = () => {
|
|
111
|
+
if (!document.cookie.includes("mtm_cookie_consent")) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
_paq.push(["setCustomUrl", router.route.path]);
|
|
115
|
+
_paq.push(["setDocumentTitle", router.route.data.title]);
|
|
116
|
+
_paq.push(["trackPageView"]);
|
|
117
|
+
_paq.push(["enableLinkTracking"]);
|
|
118
|
+
};
|
|
119
|
+
watch(() => router.route.data.relativePath, trackNavigation, {
|
|
120
|
+
immediate: true,
|
|
121
|
+
});
|
|
122
|
+
};
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,9 @@ import FeatureSection from "./components/FeatureSection.vue";
|
|
|
3
3
|
import FeaturesGallery from "./components/FeaturesGallery.vue";
|
|
4
4
|
import PricingTable from "./components/PricingTable.vue";
|
|
5
5
|
import CTASection from "./components/CTASection.vue";
|
|
6
|
+
import CookieBanner from "./components/CookieBanner.vue";
|
|
7
|
+
import CookieSettings from "./components/CookieSettings.vue";
|
|
8
|
+
import NotFound from "./components/NotFound.vue";
|
|
6
9
|
import Layout from "./Layout.vue";
|
|
7
10
|
import "./style.css";
|
|
8
11
|
|
|
@@ -14,6 +17,9 @@ export default {
|
|
|
14
17
|
app.component("FeaturesGallery", FeaturesGallery);
|
|
15
18
|
app.component("PricingTable", PricingTable);
|
|
16
19
|
app.component("CTASection", CTASection);
|
|
20
|
+
app.component("CookieBanner", CookieBanner);
|
|
21
|
+
app.component("CookieSettings", CookieSettings);
|
|
22
|
+
app.component("NotFound", NotFound);
|
|
17
23
|
|
|
18
24
|
router.onAfterRouteChanged = () => {
|
|
19
25
|
if (!import.meta.env.SSR) {
|
package/src/vitepressConfig.mjs
CHANGED
|
@@ -8,7 +8,88 @@ export const generate = (brandConfig) => ({
|
|
|
8
8
|
appearance: false,
|
|
9
9
|
cleanUrls: true,
|
|
10
10
|
description: brandConfig.meta?.description,
|
|
11
|
-
head: [
|
|
11
|
+
head: [
|
|
12
|
+
["link", { rel: "icon", href: brandConfig.meta?.favicon }],
|
|
13
|
+
// Open Graph / Facebook
|
|
14
|
+
["meta", { property: "og:type", content: "website" }],
|
|
15
|
+
[
|
|
16
|
+
"meta",
|
|
17
|
+
{
|
|
18
|
+
property: "og:url",
|
|
19
|
+
content: brandConfig.home,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
["meta", { property: "og:title", content: brandConfig.meta?.title }],
|
|
23
|
+
[
|
|
24
|
+
"meta",
|
|
25
|
+
{
|
|
26
|
+
property: "og:description",
|
|
27
|
+
content: brandConfig.meta?.description,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
// TODO
|
|
31
|
+
// [
|
|
32
|
+
// "meta",
|
|
33
|
+
// {
|
|
34
|
+
// property: "og:image",
|
|
35
|
+
// content:
|
|
36
|
+
// "https://earthcode.esa.int/img/EarthCODE_Herobanner_1920x1080.jpg",
|
|
37
|
+
// },
|
|
38
|
+
// ],
|
|
39
|
+
// Twitter
|
|
40
|
+
["meta", { property: "twitter:card", content: "summary_large_image" }],
|
|
41
|
+
[
|
|
42
|
+
"meta",
|
|
43
|
+
{
|
|
44
|
+
property: "twitter:url",
|
|
45
|
+
content: brandConfig.home,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
["meta", { property: "twitter:title", content: brandConfig.meta?.title }],
|
|
49
|
+
[
|
|
50
|
+
"meta",
|
|
51
|
+
{
|
|
52
|
+
property: "twitter:description",
|
|
53
|
+
content: brandConfig.meta?.description,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
// TODO
|
|
57
|
+
// [
|
|
58
|
+
// "meta",
|
|
59
|
+
// {
|
|
60
|
+
// property: "twitter:image",
|
|
61
|
+
// content:
|
|
62
|
+
// "https://earthcode.esa.int/img/EarthCODE_Herobanner_1920x1080.jpg",
|
|
63
|
+
// },
|
|
64
|
+
// ],
|
|
65
|
+
...(brandConfig.analytics
|
|
66
|
+
? [
|
|
67
|
+
[
|
|
68
|
+
"script",
|
|
69
|
+
{},
|
|
70
|
+
`
|
|
71
|
+
var _paq = (window._paq = window._paq || []);
|
|
72
|
+
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
|
73
|
+
_paq.push(["requireCookieConsent"]);
|
|
74
|
+
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
|
|
75
|
+
_paq.push(["trackPageView"]);
|
|
76
|
+
_paq.push(["enableLinkTracking"]);
|
|
77
|
+
(function () {
|
|
78
|
+
var u = "https://nix.eox.at/piwik/";
|
|
79
|
+
_paq.push(["setTrackerUrl", u + "matomo.php"]);
|
|
80
|
+
_paq.push(["setSiteId", "${brandConfig.analytics.siteId}"]);
|
|
81
|
+
var d = document,
|
|
82
|
+
g = d.createElement("script"),
|
|
83
|
+
s = d.getElementsByTagName("script")[0];
|
|
84
|
+
g.async = true;
|
|
85
|
+
g.src = u + "matomo.js";
|
|
86
|
+
s.parentNode.insertBefore(g, s);
|
|
87
|
+
})();
|
|
88
|
+
`,
|
|
89
|
+
],
|
|
90
|
+
]
|
|
91
|
+
: []),
|
|
92
|
+
],
|
|
12
93
|
srcExclude: ["README.md"],
|
|
13
94
|
themeConfig: {
|
|
14
95
|
siteTitle: false,
|
|
@@ -16,6 +97,7 @@ export const generate = (brandConfig) => ({
|
|
|
16
97
|
primaryColor: brandConfig.theme?.primary_color,
|
|
17
98
|
secondaryColor:
|
|
18
99
|
brandConfig.theme?.secondary_color || brandConfig.theme?.primary_color,
|
|
100
|
+
brandConfig,
|
|
19
101
|
},
|
|
20
102
|
logo: brandConfig.logo,
|
|
21
103
|
footer: {
|