Skip to content

Commit

Permalink
fix: change useTrackingScript to createConsentPromise
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Mar 17, 2024
1 parent 0367917 commit 921acd4
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 60 deletions.
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ All the features from Unhead [useScript](https://unhead.unjs.io/usage/composable

Plus Nuxt goodies:

- 🕵️ `useTrackingScript` - Load a tracking script while respecting privacy and consent
- 🕵️ `createConsentTrigger` - Create a script trigger that you can resolve with a ref or a promise.
- 🪵 DevTools integration - see all your loaded scripts with function logs

## Installation
Expand Down Expand Up @@ -58,27 +58,33 @@ Nuxt Scripts was created to solve these issues and more with the goal of making

Please see the [useScript](https://unhead.unjs.io/usage/composables/use-script) documentation.

### `useTrackingScript`
### `createConsentTrigger`

This composables is a wrapper around `useScript` that respects privacy and cookie consent.
This composable is a wrapper around `useScript` that respects privacy and cookie consent.

For the script to load you must provide a `consent` option. This can be promise, ref, or boolean.

```ts
const agreedToCookies = ref(false)
useTrackingScript('https://www.google-analytics.com/analytics.js', {
useScript('https://www.google-analytics.com/analytics.js', {
// will be loaded in when the ref is true
consent: agreedToCookies
trigger: createConsentTrigger({
consent: agreedToCookies
})
})
```

If the user has enabled `DoNotTrack` within their browser, the script will not be loaded, unless
explicitly ignoring.
You can respect the end-users browser Do Not Track option by providing the opt-in `honourDoNotTrack: true` config.

This is not enabled by default as most Analytics ignore this by default.

```ts
const agreedToCookies = ref(false)
useTrackingScript('https://www.google-analytics.com/analytics.js', {
ignoreDoNotTrack: true
useScript('https://www.google-analytics.com/analytics.js', {
trigger: createConsentTrigger({
honourDoNotTrack: true,
consent: agreedToCookies
})
})
```

Expand Down
14 changes: 9 additions & 5 deletions playground/app.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<script lang="ts" setup>
import { useTrackedPage } from '../src/runtime/composables/useTrackedPage'
import { useTrackingScript } from '../src/runtime/composables/useTrackingScript'
import { createConsentPromise, useScript, useTrackedPage } from '#imports'
const { track } = useTrackingScript<{ track: (title: string, path: string) => void }>('https://example.com/script.js', {
ignoreDoNotTrack: true,
consent: true,
interface GenericTrackingScript {
track: (title: string, path: string) => void
}
const { track } = useScript<GenericTrackingScript>('https://example.com/script.js?nuxt-scripts=inline', {
trigger: createConsentPromise({
consent: true,
}),
})!
useTrackedPage((payload) => {
track(payload)
Expand Down
10 changes: 6 additions & 4 deletions playground/pages/tracking.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script lang="ts" setup>
import { ref, useTrackingScript } from '#imports'
import { createConsentPromise, ref, useScript } from '#imports'
const cookiesEnabled = ref(false)
useTrackingScript('https://www.googletagmanager.com/gtag/js?id=GTM-5ZQZJZ', {
consent: cookiesEnabled,
ignoreDoNotTrack: true,
useScript('https://www.googletagmanager.com/gtag/js?id=GTM-5ZQZJZ', {
trigger: createConsentPromise({
consent: cookiesEnabled,
}),
assetStrategy: 'bundle',
})
</script>

Expand Down
36 changes: 36 additions & 0 deletions src/runtime/composables/createConsentTrigger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ConsentPromiseOptions } from '../types'
import { isDoNotTrackEnabled, isRef, onNuxtReady, ref, toValue, watch } from '#imports'

export function createConsentTrigger(options: ConsentPromiseOptions) {
return new Promise<void>((resolve) => {
onNuxtReady(() => {
const consented = ref<boolean>(false)
// check if DNT is enabled, never consent
if (options?.honourDoNotTrack && isDoNotTrackEnabled())
return
if (options?.consent) {
// check for boolean primitive
if (typeof options?.consent === 'boolean') {
consented.value = true
}
// consent is a promise
else if (options?.consent instanceof Promise) {
options?.consent.then((res) => {
consented.value = typeof res === 'boolean' ? res : true
})
}
else if (isRef(options?.consent)) {
watch(options.consent, (_val) => {
const val = toValue(_val)
if (typeof val === 'boolean')
consented.value = val
}, { immediate: true })
}
}
watch(consented, (ready) => {
if (ready)
resolve()
})
})
})
}
40 changes: 0 additions & 40 deletions src/runtime/composables/useTrackingScript.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface TrackedPage {
path: string
}

export type NuxtUseTrackingScriptOptions<T = any> = Omit<NuxtUseScriptOptions<T>, 'trigger'> & {
export interface ConsentPromiseOptions {
consent: Promise<boolean | void> | Ref<boolean> | boolean
ignoreDoNotTrack?: boolean
honourDoNotTrack?: boolean
}

0 comments on commit 921acd4

Please sign in to comment.