Skip to content

Commit

Permalink
Add CookieScript implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tkjaergaard committed Apr 7, 2024
1 parent d2a9992 commit 1492d07
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This module currently supports the following providers

- CookieBot
- CookieInformation
- CookieScript

## Documentation

Expand Down
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export default defineConfig({
text: 'CookieInformation',
link: '/documentation/providers/cookieinformation',
},
{
text: 'CookieScript',
link: '/documentation/providers/cookiescript',
},
],
},
],
Expand Down
10 changes: 10 additions & 0 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,14 @@ export default defineNuxtConfig({
}
})
```

```typescript [CookieScript]
export default defineNuxtConfig({
modules: ['@weareheavy/nuxt-cookie-consent']
cookieConsent: {
provider: 'cookiescript',
id: '00000000000000000000000000000000' // Replace with you "id" from CookieScript
}
})
```
:::
10 changes: 5 additions & 5 deletions docs/documentation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

To start using the module you have to have [configured a provider](/documentation#configure-your-provider).

Currently this module supports [Cookieinformation](https://cookieinformation.com) and [CookieBot](https://cookiebot.com). An account for the respective service is required.
Currently this module supports [Cookieinformation](https://cookieinformation.com), [CookieBot](https://cookiebot.com) and [CookieScript](https://cookiescript.com). An account for the respective service is required.

## General configuration

| Property |  Type | Default |  Description |
| -------- | ---------- | ------- | -------------------------------------- |
| init | `Boolean` |  `true` | Initialize the provider script on load |
|  dev |  `Boolean` | `false` | Run code when in development mode |
| Property |  Type | Default |  Description |
| -------- | --------- | ------- | -------------------------------------- |
| dev | `Boolean` | `false` | Run code when in development mode |
| init | `Boolean` | `true` | Initialize the provider script on load |

## Type declaration
<<< @/../src/runtime/types/types.d.ts#moduleGeneralOptions{typescript}
Expand Down
9 changes: 5 additions & 4 deletions docs/documentation/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

This module aims to support as many providers as possible, and currently have implementations for these:

|  Provider | Alias |  Website |
| --------------------------------------------------------------- | ------------------- | ------------------------------------------------------ |
| [CookieBot](/documentation/providers/cookiebot) | `cookiebot` | [https://cookiebot.com](https://cookiebot.com) |
| [CookieInformation](/documentation/providers/cookieinformation) | `cookieinformation` | [https://cookieinformation.com](https://cookiebot.com) |
|  Provider | Alias |  Website |
| --------------------------------------------------------------- | ------------------- | -------------------------------------------------------------- |
| [CookieBot](/documentation/providers/cookiebot) | `cookiebot` | [https://cookiebot.com](https://cookiebot.com) |
| [CookieInformation](/documentation/providers/cookieinformation) | `cookieinformation` | [https://cookieinformation.com](https://cookieinformation.com) |
| [CookieScript](/documentation/providers/cookiescript) | `cookiescript` | [https://cookiescript.com](https://cookiescript.com) |

<div class="pt-4"></div>

Expand Down
23 changes: 23 additions & 0 deletions docs/documentation/providers/cookiescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# CookieScript

Websie: [cookiescript.com](https://cookiescript.com)


## Configuration

```typescript
export default defineNuxtConfig({
cookieConsent: {
provider: 'cookiescript',
id: '00000000000000000000000000000000', // Replace with you own id
}
})
```

## Consent mode
By default CookieScript enables Consent Mode (opt-out).

[Read more about Google Consent Mode in CookieScript &rarr;](https://help.cookie-script.com/en/google-analytics/google-consent-mode-implementation-instructions)

## Type Declaration
<<< @/../src/runtime/types/types.d.ts#moduleGeneralOptionsCookieScript{typescript}
3 changes: 2 additions & 1 deletion playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ export default defineNuxtConfig({
modules: ['../src/module'],
devtools: { enabled: true },
cookieConsent: {
provider: 'cookieinformation',
provider: 'cookiescript',
id: '00000000000000000000000000000000',
// cbid: '00000000-0000-0000-0000-000000000000',
dev: true,
scripts: {
Expand Down
6 changes: 5 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import type {
NuxtCookieConsentOptionsProviderCookieInformation,
} from './runtime/types/types'

export const nuxtConsentProviders = ['cookieinformation', 'cookiebot']
export const nuxtConsentProviders = [
'cookieinformation',
'cookiebot',
'cookiescript',
]

const module: NuxtModule<NuxtCookieConsentOptions> =
defineNuxtModule<NuxtCookieConsentOptions>({
Expand Down
30 changes: 30 additions & 0 deletions src/runtime/components/ConsentPolicy.cookiescript.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineComponent, h, Fragment } from 'vue'
import { useRuntimeConfig } from '#imports'

export default defineComponent(
() => {
return () => {
const { cookieConsent: config } = useRuntimeConfig().public

// @ts-ignore
const id = config.id

if (!id) {
return h(Fragment, { key: 'CookiePolicy' })
}

return h(Fragment, { key: 'CookiePolicy' }, [
h('script', {
id: 'CookiePolicy',
src: `https://report.cookie-script.com/r/${id}.js`,
type: 'text/javascript',
'data-cookiescriptreport': 'report',
charset: 'UTF-8',
}),
])
}
},
{
props: [],
},
)
12 changes: 10 additions & 2 deletions src/runtime/composables/useCookieConsent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ export function useCookieConsent(): NuxtCookieConsentUseCookieConsent {

export function cookieConsentRenew(): void {
if (import.meta.client) {
window?.CookieConsent?.renew?.()
if (typeof window?.CookieScript?.instance?.show === 'function') {
window?.CookieScript?.instance?.show?.()
} else {
window?.CookieConsent?.renew?.()
}
}
}

export function cookieConsentShow(): void {
if (import.meta.client) {
window?.CookieConsent?.show?.()
if (typeof window?.CookieScript?.instance?.show === 'function') {
window?.CookieScript?.instance?.show?.()
} else {
window?.CookieConsent?.show?.()
}
}
}
112 changes: 112 additions & 0 deletions src/runtime/plugins/cookiescript.plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {
defineNuxtPlugin,
useCookie,
useCookieConsent,
useHead,
useRuntimeConfig,
} from '#imports'
import consola from 'consola'
import type { CookieScriptPayload } from '../types/types'
import { loadScripts } from '../utils/script.loader'
import { updateState } from '../utils/update.state'

export default defineNuxtPlugin(() => {
const { cookieConsent: config } = useRuntimeConfig().public

if (!config.init || (!config.dev && process.dev)) {
return
}

if (config.init) {
// @ts-ignore
const id = config.id

if (!id) {
consola.warn(
'Unable to initialize CookieScript script: No CookieScript id provided. Please set the `id` option in "cookieConsent" in `nuxt.config.js`',
)
} else {
useHead({
script: [
{
id: 'CookieScript',
src: `https://cdn.cookie-script.com/s/${id}.js`,
type: 'text/javascript',
tagPriority: 5,
},
],
})
}
}

const cookie = useCookie<CookieScriptPayload | null>('CookieScriptConsent', {
decode: (value: string) =>
JSON.parse(
decodeURIComponent(value || '{ "categories": [] }'),
) as CookieScriptPayload | null,
})

const { state } = useCookieConsent()

if (cookie.value) {
updateState(state, {
necessary: true,
functional:
cookie.value.categories?.includes('functionality') ||
(cookie.value.categories == undefined &&
cookie.value.action === 'accept') ||
false,
statistic:
cookie.value.categories?.includes('performance') ||
(cookie.value.categories == undefined &&
cookie.value.action === 'accept') ||
false,
marketing:
cookie.value.categories?.includes('targeting') ||
(cookie.value.categories == undefined &&
cookie.value.action === 'accept') ||
false,
unclassified:
cookie.value.categories?.includes('unclassified') ||
(cookie.value.categories == undefined &&
cookie.value.action === 'accept') ||
false,
})
}

if (import.meta.client) {
window.addEventListener('CookieScriptAccept', (e: any) => {
const categories = e.detail?.categories || []

updateState(state, {
necessary: true,
functional: categories.includes('functionality') || false,
statistic: categories.includes('performance') || false,
marketing: categories.includes('targeting') || false,
unclassified: categories.includes('unclassified') || false,
})
})

window.addEventListener('CookieScriptReject', () => {
updateState(state, {
necessary: true,
functional: false,
statistic: false,
marketing: false,
unclassified: false,
})
})

window.addEventListener('CookieScriptAcceptAll', () => {
updateState(state, {
necessary: true,
functional: true,
statistic: true,
marketing: true,
unclassified: true,
})
})
}

loadScripts(config)
})
14 changes: 14 additions & 0 deletions src/runtime/types/dom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ interface Window {
CookieInformation: CookieInformation
CookieConsent: WindowCookieConsentInteractions
Cookiebot: CookieBot
CookieScript: CookieScript
}

// @see https://help.cookie-script.com/en/javascript-code-documentation/custom-functions
interface CookieScript {
instance: {
show: () => void
hide: () => void
currentState: () => void
categories: () => void
acceptAllAction: () => void
rejectAllAction: () => void
acceptAction: () => void
}
}

interface CookieInformation {
Expand Down
22 changes: 22 additions & 0 deletions src/runtime/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ interface CookieInformationPayload {
user_agent: string
}

interface CookieScriptPayload {
googleconsentmap: {
ad_storage: 'targeting'
analytics_storage: 'performance'
ad_personalization: 'targeting'
ad_user_data: 'targeting'
functionality_storage: 'functionality'
personalization_storage: 'functionality'
security_storage: 'functionality'
}
action?: 'accept' | 'reject'
categories?: string[]
}

// #region consentState
export interface NuxtCookieConsentState {
necessary: boolean
Expand Down Expand Up @@ -147,9 +161,17 @@ export type NuxtCookieConsentOptionsProviderCookieBot = {
}
// #endregion moduleGeneralOptionsCookieBot

// #region moduleGeneralOptionsCookieScript
export type NuxtCookieConsentOptionsCookieScript = {
provider: 'cookiescript'
id: string
}
// #endregion moduleGeneralOptionsCookieScript

export type NuxtCookieConsentOptionsProvider =
| NuxtCookieConsentOptionsProviderCookieBot
| NuxtCookieConsentOptionsProviderCookieInformation
| NuxtCookieConsentOptionsCookieScript

export type NuxtCookieConsentOptions = NuxtCookieConsentOptionsProvider &
NuxtCookieConsentOptionsScripts &
Expand Down

0 comments on commit 1492d07

Please sign in to comment.