Skip to content

Commit 08675d4

Browse files
authored
Merge branch 'main' into release/v0.2.10
2 parents f8af933 + fde4ae1 commit 08675d4

19 files changed

Lines changed: 5703 additions & 7617 deletions

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
timeout-minutes: 10
88
runs-on: ubuntu-latest
99
container:
10-
image: mcr.microsoft.com/playwright:v1.52.0-jammy
10+
image: mcr.microsoft.com/playwright:v1.57.0-jammy
1111

1212
strategy:
1313
matrix:

README.md

Lines changed: 112 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
---
1212

13-
A Nuxt 3 module for tracking UTM parameters.
13+
A Nuxt 3/4 module for tracking UTM parameters.
1414

1515
- [ Release Notes](/CHANGELOG.md)
1616
<!-- - [🏀 Online playground](https://stackblitz.com/github/stackbuilders/nuxt-utm?file=playground%2Fapp.vue) -->
@@ -53,26 +53,122 @@ That's it! You can now use Nuxt UTM in your Nuxt app ✨
5353

5454
## Usage
5555

56-
You can use `useNuxtUTM` composable to access the UTM object:
56+
### Configuration
57+
58+
You can configure the module by passing options in your `nuxt.config.ts`:
59+
60+
```js
61+
export default defineNuxtConfig({
62+
modules: ['nuxt-utm'],
63+
utm: {
64+
trackingEnabled: true, // defaults to true - initial tracking state
65+
},
66+
})
67+
```
68+
69+
#### Options
70+
71+
- `trackingEnabled`: Boolean (default: `true`) - Sets the initial state for UTM tracking. This can be changed at runtime.
72+
73+
### Runtime Tracking Control
74+
75+
The module provides runtime control over tracking, perfect for implementing cookie consent banners or user privacy preferences.
76+
77+
#### Using the Composable
5778

5879
```vue
5980
<script setup>
6081
const utm = useNuxtUTM()
82+
83+
// The composable returns:
84+
// - data: Reactive array of collected UTM data
85+
// - trackingEnabled: Reactive boolean indicating if tracking is active
86+
// - enableTracking(): Enable UTM tracking
87+
// - disableTracking(): Disable UTM tracking
88+
// - clearData(): Clear all stored UTM data
6189
</script>
6290
```
6391

64-
> Remember: You don't need to import the composable because nuxt imports it automatically.
92+
#### Example: Cookie Banner Integration
93+
94+
```vue
95+
<template>
96+
<div v-if="showBanner" class="cookie-banner">
97+
<p>We use tracking to improve your experience.</p>
98+
<button @click="acceptTracking">Accept</button>
99+
<button @click="rejectTracking">Reject</button>
100+
</div>
101+
</template>
65102
66-
Alternatively, you can get the UTM information through the Nuxt App with the following instructions:
103+
<script setup>
104+
import { ref } from 'vue'
105+
const utm = useNuxtUTM()
106+
const showBanner = ref(!utm.trackingEnabled.value)
107+
108+
const acceptTracking = () => {
109+
utm.enableTracking()
110+
showBanner.value = false
111+
}
112+
113+
const rejectTracking = () => {
114+
utm.disableTracking()
115+
utm.clearData() // Optional: clear any existing data
116+
showBanner.value = false
117+
}
118+
</script>
119+
```
120+
121+
#### Privacy Controls
122+
123+
```vue
124+
<template>
125+
<div class="privacy-settings">
126+
<h3>Privacy Settings</h3>
127+
<label>
128+
<input
129+
type="checkbox"
130+
:checked="utm.trackingEnabled.value"
131+
@change="toggleTracking"
132+
/>
133+
Enable UTM tracking
134+
</label>
135+
<button @click="utm.clearData" v-if="utm.data.value.length > 0">
136+
Clear tracking data ({{ utm.data.value.length }} entries)
137+
</button>
138+
</div>
139+
</template>
140+
141+
<script setup>
142+
const utm = useNuxtUTM()
143+
144+
const toggleTracking = (event) => {
145+
if (event.target.checked) {
146+
utm.enableTracking()
147+
} else {
148+
utm.disableTracking()
149+
}
150+
}
151+
</script>
152+
```
153+
154+
### Accessing UTM Data
155+
156+
You can use `useNuxtUTM` composable to access the UTM data:
67157

68158
```vue
69159
<script setup>
70-
import { useNuxtApp } from 'nuxt/app'
71-
const { $utm } = useNuxtApp()
160+
const utm = useNuxtUTM()
161+
162+
// Access the collected data
163+
console.log(utm.data.value)
72164
</script>
73165
```
74166

75-
Regardless of the option you choose to use the module, the `utm' object will contain an array of UTM parameters collected for use. Each element in the array represents a set of UTM parameters collected from a URL visit, and is structured as follows
167+
> Remember: You don't need to import the composable because Nuxt imports it automatically.
168+
169+
### Data Structure
170+
171+
The `data` property contains an array of UTM parameters collected. Each element in the array represents a set of UTM parameters collected from a URL visit, and is structured as follows
76172

77173
```json
78174
[
@@ -104,7 +200,15 @@ Regardless of the option you choose to use the module, the `utm' object will con
104200
]
105201
```
106202

107-
In the `$utm` array, each entry provides a `timestamp` indicating when the UTM parameters were collected, the `utmParams` object containing the UTM parameters, `additionalInfo` object with more context about the visit, and a `sessionId` to differentiate visits in different sessions.
203+
Each entry provides a `timestamp` indicating when the UTM parameters were collected, the `utmParams` object containing the UTM parameters, `additionalInfo` object with more context about the visit, and a `sessionId` to differentiate visits in different sessions.
204+
205+
### Key Features
206+
207+
- **Runtime Control**: Enable/disable tracking dynamically based on user consent
208+
- **Privacy Friendly**: Respects user preferences and provides clear data management
209+
- **Persistent Preferences**: Tracking preferences are saved and persist across sessions
210+
- **Data Clearing**: Ability to completely remove all collected data
211+
- **Session Management**: Automatically manages sessions to avoid duplicate tracking
108212

109213
## Development
110214

package.json

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "nuxt-utm",
33
"version": "0.2.10",
4-
"description": "A Nuxt 3 module for tracking UTM parameters.",
4+
"description": "A Nuxt 3/4 module for tracking UTM parameters.",
55
"keywords": [
66
"nuxt",
77
"nuxt3",
8+
"nuxt4",
89
"utm",
910
"utm tracking",
1011
"utm parameters",
@@ -54,26 +55,31 @@
5455
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
5556
},
5657
"dependencies": {
57-
"@nuxt/kit": "^3.17.2"
58+
"@nuxt/kit": "^3.17.2 || ^4.0.0"
59+
},
60+
"resolutions": {
61+
"node-forge": "^1.3.2",
62+
"vite": "^7.2.4",
63+
"tmp": "^0.2.4"
5864
},
5965
"devDependencies": {
60-
"@nuxt/devtools": "^2.4.0",
61-
"@nuxt/eslint": "1.3.1",
62-
"@nuxt/eslint-config": "^1.3.1",
63-
"@nuxt/module-builder": "^1.0.1",
64-
"@nuxt/schema": "^3.17.2",
65-
"@nuxt/test-utils": "^3.18.0",
66+
"@nuxt/devtools": "^3.1.1",
67+
"@nuxt/eslint": "^1.11.0",
68+
"@nuxt/eslint-config": "^1.11.0",
69+
"@nuxt/module-builder": "^1.0.2",
70+
"@nuxt/schema": "^4.2.1",
71+
"@nuxt/test-utils": "^3.20.1 || ^4.0.0",
6672
"@types/node": "latest",
6773
"changelogen": "^0.6.1",
68-
"eslint": "^9.26.0",
74+
"eslint": "^9.39.1",
6975
"eslint-config-prettier": "^10.1.5",
7076
"eslint-plugin-prettier": "^5.4.0",
71-
"nuxt": "^3.17.2",
72-
"playwright": "^1.52.0",
73-
"playwright-core": "^1.52.0",
77+
"nuxt": "^4.2.1",
78+
"playwright": "^1.57.0",
79+
"playwright-core": "^1.57.0",
7480
"prettier": "^3.5.3",
7581
"typescript": "~5.8.3",
76-
"vitest": "^3.1.2",
82+
"vitest": "^4.0.14",
7783
"vue-tsc": "^2.2.10"
7884
}
7985
}

playground/app.vue

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,146 @@
11
<template>
2-
<div>Nuxt 3 UTM module playground!</div>
3-
<pre>{{ utm }}</pre>
2+
<div class="container">
3+
<h1>Nuxt UTM Module Playground</h1>
4+
5+
<div class="controls">
6+
<h2>Tracking Controls</h2>
7+
<p>
8+
Tracking is currently:
9+
<strong :class="{ enabled: utm.trackingEnabled.value, disabled: !utm.trackingEnabled.value }">
10+
{{ utm.trackingEnabled.value ? 'ENABLED' : 'DISABLED' }}
11+
</strong>
12+
</p>
13+
14+
<div class="buttons">
15+
<button
16+
:disabled="utm.trackingEnabled.value"
17+
@click="utm.enableTracking"
18+
>
19+
Enable Tracking
20+
</button>
21+
<button
22+
:disabled="!utm.trackingEnabled.value"
23+
@click="utm.disableTracking"
24+
>
25+
Disable Tracking
26+
</button>
27+
<button
28+
class="danger"
29+
@click="utm.clearData"
30+
>
31+
Clear All Data
32+
</button>
33+
</div>
34+
35+
<div class="info">
36+
<p>Try visiting with UTM parameters:</p>
37+
<a href="/?utm_source=test&utm_medium=demo&utm_campaign=playground">
38+
Add UTM params to URL
39+
</a>
40+
</div>
41+
</div>
42+
43+
<div class="data">
44+
<h2>Collected UTM Data ({{ utm.data.value.length }} entries)</h2>
45+
<pre>{{ utm.data.value }}</pre>
46+
</div>
47+
</div>
448
</template>
549

650
<script setup>
751
import { useNuxtUTM } from '#imports'
852
953
const utm = useNuxtUTM()
1054
</script>
55+
56+
<style scoped>
57+
.container {
58+
max-width: 1200px;
59+
margin: 0 auto;
60+
padding: 2rem;
61+
font-family: system-ui, -apple-system, sans-serif;
62+
}
63+
64+
h1 {
65+
color: #00dc82;
66+
margin-bottom: 2rem;
67+
}
68+
69+
.controls {
70+
background: #f5f5f5;
71+
padding: 1.5rem;
72+
border-radius: 8px;
73+
margin-bottom: 2rem;
74+
}
75+
76+
.buttons {
77+
display: flex;
78+
gap: 1rem;
79+
margin: 1rem 0;
80+
}
81+
82+
button {
83+
padding: 0.5rem 1rem;
84+
border: none;
85+
border-radius: 4px;
86+
background: #00dc82;
87+
color: white;
88+
cursor: pointer;
89+
font-size: 1rem;
90+
}
91+
92+
button:hover:not(:disabled) {
93+
background: #00c76d;
94+
}
95+
96+
button:disabled {
97+
opacity: 0.5;
98+
cursor: not-allowed;
99+
}
100+
101+
button.danger {
102+
background: #dc3545;
103+
}
104+
105+
button.danger:hover {
106+
background: #c82333;
107+
}
108+
109+
.enabled {
110+
color: #28a745;
111+
}
112+
113+
.disabled {
114+
color: #dc3545;
115+
}
116+
117+
.info {
118+
margin-top: 1rem;
119+
padding-top: 1rem;
120+
border-top: 1px solid #ddd;
121+
}
122+
123+
.info a {
124+
color: #00dc82;
125+
text-decoration: none;
126+
}
127+
128+
.info a:hover {
129+
text-decoration: underline;
130+
}
131+
132+
.data {
133+
background: #f8f9fa;
134+
padding: 1.5rem;
135+
border-radius: 8px;
136+
}
137+
138+
pre {
139+
background: white;
140+
padding: 1rem;
141+
border-radius: 4px;
142+
overflow-x: auto;
143+
max-height: 400px;
144+
overflow-y: auto;
145+
}
146+
</style>

playground/nuxt.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
export default defineNuxtConfig({
22
modules: ['../src/module'],
33
devtools: { enabled: true },
4-
utm: {},
4+
app: {
5+
head: {
6+
title: 'Nuxt UTM Playground',
7+
},
8+
},
9+
utm: {
10+
trackingEnabled: true,
11+
},
512
})

playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
"generate": "nuxi generate"
99
},
1010
"devDependencies": {
11-
"nuxt": "^3.17.2"
11+
"nuxt": "^4.2.1"
1212
}
1313
}

0 commit comments

Comments
 (0)