TLDR: Cookie consent in Nuxt 3 takes one config entry. Add to nuxt.config.ts, deploy, you're compliant. Full Google Consent Mode v2, no GTM needed.
Read full summary
Nuxt 3 makes configuration elegant. Cookie consent should match that elegance. One entry in nuxt.config.ts gives you GDPR compliance, Google Consent Mode v2, and script blocking. This guide covers the basics and advanced patterns.
*Summary by Claude AI*
## Nuxt's Philosophy Applied to Compliance
Nuxt 3 is opinionated about simplicity. Configuration lives in one file. Composables replace boilerplate. Auto-imports save keystrokes.
Cookie consent should work the same way.
Most consent tools fight against this philosophy. They want you to install npm packages, create plugins, configure external dashboards, and debug why things don't work in SSR mode.
GetCookies follows the Nuxt way: add to config, deploy, done.
## The 2-Minute Setup
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
src: 'https://getcookies.co/api/v1/widget/loader.js',
'data-domain-id': 'YOUR_DOMAIN_ID',
async: true
}
]
}
}
})
```
Deploy. Refresh. You have a cookie banner.
You also have:
- GDPR-compliant consent collection
- Google Consent Mode v2 (all four signals)
- Automatic script blocking until consent
- Third-party pixel support (Meta, TikTok, Google)
- Consent logging for audits
No npm install. No plugin file. No composable boilerplate.
## Environment Configuration
Use runtime config for different environments:
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
getCookiesDomainId: process.env.GETCOOKIES_DOMAIN_ID || ''
}
},
app: {
head: {
script: [
{
src: 'https://getcookies.co/api/v1/widget/loader.js',
'data-domain-id': process.env.GETCOOKIES_DOMAIN_ID || '',
async: true
}
]
}
}
})
```
```env
# .env
GETCOOKIES_DOMAIN_ID=dev-domain-id
# .env.production
GETCOOKIES_DOMAIN_ID=prod-domain-id
```
Create separate domains in GetCookies for localhost, staging, and production.
## A Composable for Consent State
Want reactive consent state throughout your app? Create a composable:
```typescript
// composables/useConsent.ts
export function useConsent() {
const hasAnalytics = ref(false)
const hasMarketing = ref(false)
const hasPreferences = ref(false)
const checkConsent = () => {
if (typeof window !== 'undefined' && window.GetCookies) {
hasAnalytics.value = window.GetCookies.hasConsent('analytics')
hasMarketing.value = window.GetCookies.hasConsent('marketing')
hasPreferences.value = window.GetCookies.hasConsent('preferences')
}
}
const showPreferences = () => {
window.GetCookies?.showPreferences()
}
const acceptAll = () => {
window.GetCookies?.acceptAll()
}
const rejectAll = () => {
window.GetCookies?.rejectAll()
}
onMounted(() => {
checkConsent()
window.addEventListener('getcookies:consent', checkConsent)
})
onUnmounted(() => {
window.removeEventListener('getcookies:consent', checkConsent)
})
return {
hasAnalytics: readonly(hasAnalytics),
hasMarketing: readonly(hasMarketing),
hasPreferences: readonly(hasPreferences),
showPreferences,
acceptAll,
rejectAll
}
}
```
Nuxt auto-imports composables from the `composables` folder. Use it anywhere:
```vue
Analytics: Enabled
Marketing: Enabled
```
## Conditional Script Loading
### Method 1: useHead
Load scripts reactively based on consent:
```vue
```
### Method 2: Data Attributes
Let GetCookies manage script activation:
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
src: 'https://getcookies.co/api/v1/widget/loader.js',
'data-domain-id': 'YOUR_DOMAIN_ID',
async: true
},
{
src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX',
type: 'text/plain',
'data-cookieconsent': 'analytics'
}
]
}
}
})
```
The `type: 'text/plain'` prevents execution. GetCookies activates it after consent.
## SSR: No Special Handling
GetCookies runs client-side. For SSR-safe components:
```vue
```
`` prevents hydration mismatches. The fallback shows during SSR.
## TypeScript Support
Add type definitions:
```typescript
// types/getcookies.d.ts
declare global {
interface Window {
GetCookies?: {
hasConsent: (category: 'analytics' | 'marketing' | 'preferences') => boolean
showPreferences: () => void
acceptAll: () => void
rejectAll: () => void
}
}
}
export {}
```
Reference in tsconfig:
```json
{
"compilerOptions": {
"types": ["./types/getcookies"]
}
}
```
## Common Patterns
### Footer Cookie Link
```vue
```
### Consent-Gated Analytics
```vue
```
## Optional: Creating a Module
For multi-project reuse, create a local Nuxt module:
```typescript
// modules/getcookies.ts
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'getcookies',
configKey: 'getCookies'
},
defaults: {
domainId: ''
},
setup(options, nuxt) {
if (!options.domainId) {
console.warn('[GetCookies] No domain ID provided')
return
}
nuxt.options.app.head.script = nuxt.options.app.head.script || []
nuxt.options.app.head.script.push({
src: 'https://getcookies.co/api/v1/widget/loader.js',
'data-domain-id': options.domainId,
async: true
})
}
})
```
Use it:
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['./modules/getcookies'],
getCookies: {
domainId: 'YOUR_DOMAIN_ID'
}
})
```
## Deployment
### Vercel
```bash
vercel --prod
```
### Netlify
```toml
# netlify.toml
[build]
command = "npm run build"
publish = ".output/public"
```
### Cloudflare Pages
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages'
}
})
```
## Troubleshooting
**Hydration mismatch warnings?**
Wrap consent-dependent content in ``.
**Script not loading?**
1. Check domain ID is correct
2. Verify domain is added in GetCookies dashboard
3. Check Network tab for script loading
**Consent not updating?**
Ensure event listeners are in `onMounted`:
```typescript
onMounted(() => {
window.addEventListener('getcookies:consent', handler)
})
```
## Performance Impact
| Metric | Impact |
|--------|--------|
| Bundle size | +1KB (loader only) |
| LCP | No impact |
| FID | No impact |
| CLS | No impact |
Your Lighthouse scores stay green.
## What You Don't Have to Do
- Install an npm package
- Create a plugin file
- Configure GTM triggers
- Read Consent Mode documentation
- Debug SSR timing issues
- Wonder if consent actually works
One config entry. Full compliance. The Nuxt way.
---
**Ready to add cookie consent to your Nuxt app?**
[Get your domain ID in 60 seconds](https://getcookies.co)
G
GetCookies Team
Redactor en GetCookies, especializado en cumplimiento de privacidad, gestión de consentimiento y optimización de marketing digital.