react-lgpd-consent 0.7.0 → 0.7.2

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/API.md CHANGED
@@ -17,7 +17,9 @@ Este documento é a referência técnica oficial para a API da biblioteca `react
17
17
  | `useOpenPreferencesModal` | Hook | Retorna uma função para abrir o modal de preferências de forma programática. |
18
18
  | `openPreferencesModal` | Função | Versão da função acima para ser usada fora do contexto React. |
19
19
  | `ConsentGate` | Componente | Renderiza componentes filhos apenas se uma categoria de cookie for consentida. |
20
- | `ConsentScriptLoader` | Componente | Carrega scripts de terceiros (como Google Analytics) com base no consentimento. |
20
+ | `ConsentScriptLoader` | Componente | Carrega scripts de terceiros (como Google Analytics) com base no consentimento. Suporta Consent Mode v2 automático. |
21
+ | `registerScript()` | Função | Registra um script na fila global para execução condicional ao consentimento. Retorna função de cleanup. |
22
+ | `RegisteredScript` | Tipo | Interface para scripts registrados programaticamente (id, category, execute, priority, onConsentUpdate). |
21
23
  | `buildConsentStorageKey` | Função | (v0.5.2) Gera nomes de cookies `namespace__vX` a partir de namespace/versão. |
22
24
  | `createGoogleAnalyticsIntegration` | Função | Factory para integração nativa com o Google Analytics. |
23
25
  | `createGoogleTagManagerIntegration` | Função | Factory para integração nativa com o Google Tag Manager. |
@@ -28,6 +30,7 @@ Este documento é a referência técnica oficial para a API da biblioteca `react
28
30
  | `createClarityIntegration` | Função | (v0.4.1) Integração nativa com Microsoft Clarity. |
29
31
  | `createIntercomIntegration` | Função | (v0.4.1) Integração nativa com Intercom (chat). |
30
32
  | `createZendeskChatIntegration` | Função | (v0.4.1) Integração nativa com Zendesk Chat. |
33
+ | `createSuggestedIntegration` | Função | (v0.7.2) Cria integração customizada com categoria sugerida automaticamente. |
31
34
  | `suggestCategoryForScript` | Função | (v0.4.1) Sugere categoria(s) LGPD para um script conhecido. |
32
35
  | `discoverRuntimeCookies` | Função | (v0.4.1) Descobre cookies em tempo real no navegador. |
33
36
  | `categorizeDiscoveredCookies` | Função | (v0.4.1) Categoriza cookies descobertos usando padrões LGPD. |
@@ -43,10 +46,63 @@ Este documento é a referência técnica oficial para a API da biblioteca `react
43
46
  | `createSaaSIntegrations` | Função | (v0.4.1) Cria integrações comuns para SaaS. |
44
47
  | `createCorporateIntegrations` | Função | (v0.4.1) Cria integrações comuns para ambientes corporativos. |
45
48
  | `INTEGRATION_TEMPLATES` | Constante | (v0.4.1) Presets com IDs essenciais/opcionais e categorias por tipo de negócio. |
49
+ | `SuggestedIntegrationConfig` | Tipo | (v0.7.2) Configuração para integração customizada com categoria sugerida. |
46
50
  | `setDebugLogging` | Função | Habilita/desabilita o logging de debug da biblioteca. |
47
51
 
48
52
  ---
49
53
 
54
+ ## ESM/CJS e Testes (Jest/Vitest)
55
+
56
+ O pacote publica **dual build** (ESM + CJS) via `exports`:
57
+
58
+ ```json
59
+ {
60
+ ".": { "import": "./dist/index.js", "require": "./dist/index.cjs" },
61
+ "./core": { "import": "./dist/core.js", "require": "./dist/core.cjs" },
62
+ "./mui": { "import": "./dist/mui.js", "require": "./dist/mui.cjs" },
63
+ "./integrations": { "import": "./dist/integrations.js", "require": "./dist/integrations.cjs" }
64
+ }
65
+ ```
66
+
67
+ ### Jest (CJS) com babel-jest
68
+
69
+ ```js
70
+ // jest.config.cjs
71
+ module.exports = {
72
+ testEnvironment: 'jsdom',
73
+ transform: {
74
+ '^.+\\.(t|j)sx?$': ['babel-jest', { presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'] }],
75
+ },
76
+ transformIgnorePatterns: ['/node_modules/(?!react-lgpd-consent|@react-lgpd-consent)/'],
77
+ }
78
+ ```
79
+
80
+ ### Vitest (Vite)
81
+
82
+ ```ts
83
+ // vitest.config.ts
84
+ import { defineConfig } from 'vitest/config'
85
+
86
+ export default defineConfig({
87
+ test: {
88
+ environment: 'jsdom',
89
+ deps: {
90
+ inline: ['react-lgpd-consent', '@react-lgpd-consent/core', '@react-lgpd-consent/mui'],
91
+ },
92
+ },
93
+ })
94
+ ```
95
+
96
+ ### Importações recomendadas
97
+
98
+ ```ts
99
+ import { ConsentProvider } from 'react-lgpd-consent'
100
+ import { ConsentProvider as ConsentProviderHeadless } from 'react-lgpd-consent/core'
101
+ import { createGoogleAnalyticsIntegration } from 'react-lgpd-consent/integrations'
102
+ ```
103
+
104
+ ---
105
+
50
106
  ## Componentes
51
107
 
52
108
  ### `<ConsentProvider />`
@@ -74,7 +130,9 @@ function App() {
74
130
  | Prop | Tipo | Descrição |
75
131
  | --- | --- | --- |
76
132
  | `categories` | `ProjectCategoriesConfig` | **Obrigatório.** Fonte única de verdade sobre as categorias habilitadas; usada por UI, hooks e integrações. |
77
- | `texts` | `Partial<ConsentTexts>` | Customiza todos os textos exibidos (banner, modal, botão). |
133
+ | `texts` | `Partial<AdvancedConsentTexts>` | Customiza todos os textos exibidos (banner, modal, botão). |
134
+ | `language` | `'pt' \| 'en' \| 'es' \| 'fr' \| 'de' \| 'it'` | Resolve textos via i18n no Provider. |
135
+ | `textVariant` | `'formal' \| 'casual' \| 'concise' \| 'detailed'` | Aplica variação de tom sobre os textos base. |
78
136
  | `designTokens` | `DesignTokens` | Ajuste visual granular (cores, spacing, tipografia, overlays). |
79
137
  | `blocking` | `boolean` | Ativa overlay bloqueante até o usuário decidir. Padrão: `false`. |
80
138
  | `blockingStrategy` | `'auto' \| 'provider' \| 'component'` | Controla quem desenha o overlay quando `blocking` está ativo. |
@@ -175,12 +233,35 @@ function MyComponent() {
175
233
 
176
234
  Gerencia o carregamento de scripts de terceiros (ex: Google Analytics) com base no consentimento do usuário. Veja o guia `INTEGRACOES.md` para mais detalhes.
177
235
 
236
+ **Novidades v0.7.1:**
237
+ - ✨ **Google Consent Mode v2 automático**: GA4 e GTM agora enviam `consent('default', 'denied')` no bootstrap e `consent('update', 'granted')` após consentimento
238
+ - 🎯 **Sistema de fila com prioridade**: Scripts são executados ordenadamente (necessary → categoria → prioridade → timestamp)
239
+ - 🔄 **Callbacks de atualização**: `onConsentUpdate` dispara quando preferências mudam
240
+
178
241
  ```tsx
179
- import { ConsentScriptLoader, createGoogleAnalyticsIntegration } from 'react-lgpd-consent'
242
+ import { ConsentScriptLoader, createGoogleAnalyticsIntegration, registerScript } from 'react-lgpd-consent'
180
243
 
244
+ // Uso padrão (Consent Mode v2 automático)
181
245
  const integrations = [createGoogleAnalyticsIntegration({ measurementId: 'G-XXXXXXXXXX' })]
246
+ <ConsentScriptLoader integrations={integrations} />
247
+
248
+ // Uso avançado: registro programático com prioridade
249
+ const cleanup = registerScript({
250
+ id: 'custom-analytics',
251
+ category: 'analytics',
252
+ priority: 10, // Maior = executa primeiro
253
+ execute: async () => {
254
+ console.log('Script carregado!')
255
+ },
256
+ onConsentUpdate: ({ consented, preferences }) => {
257
+ if (preferences.analytics) {
258
+ console.log('Analytics habilitado via update!')
259
+ }
260
+ }
261
+ })
182
262
 
183
- ;<ConsentScriptLoader integrations={integrations} />
263
+ // ℹ️ Estados da fila: pending → running → executed.
264
+ // Scripts só reexecutam se allowReload=true; sempre use o cleanup ao desmontar.
184
265
  ```
185
266
 
186
267
  ---
@@ -561,7 +642,7 @@ Para customizações avançadas e tipagem, você pode importar os seguintes tipo
561
642
  - `CustomPreferencesModalProps`: Props passadas para um modal de preferências customizado.
562
643
  - `ConsentState`: Objeto que representa o estado completo do consentimento do usuário.
563
644
  - `ConsentPreferences`: Objeto com as preferências de consentimento para cada categoria.
564
- - `ConsentTexts`: Objeto com todos os textos customizáveis da UI.
645
+ - `ConsentTexts`: Tipo base com textos essenciais da UI (pt-BR).
565
646
  - `Category`: Objeto que representa a definição de uma categoria de cookie.
566
647
  ### Exemplos de categorias (mínimo e completo)
567
648
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,250 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#134](https://github.com/lucianoedipo/react-lgpd-consent/pull/134) [`44b885b`](https://github.com/lucianoedipo/react-lgpd-consent/commit/44b885b7c81f1cb5822e2dcfde2975e69e8d4893) Thanks [@github-actions](https://github.com/apps/github-actions)! - ### Correções
8
+ - 1d15920 fix: corrigir formatação da verificação de múltiplas versões do React
9
+
10
+ ### Funcionalidades
11
+ - d641639 feat: adicionar gerenciamento de eventos para categorias obrigatórias no CategoriesProvider
12
+ - b04c00b feat: add tests for CookieBanner, FloatingPreferencesButton, and PreferencesModal components
13
+ - b04c00b Introduce interactive changeset script for easier versioning in monorepos.
14
+
15
+ ### Refactors e compatibilidade
16
+ - ef2968a refactor: replace direct document and window references with globalThis for better compatibility
17
+ - ef2968a Updated scriptLoader, cookieDiscovery, cookieUtils, dataLayerEvents, developerGuidance, peerDepsCheck, scriptIntegrations, and scriptLoader files to use globalThis.document and globalThis.window.
18
+ - ef2968a Improved cookie handling functions to check for document and window availability using globalThis.
19
+ - ef2968a Enhanced tests to reference globalThis for consistency.
20
+ - ef2968a Cleaned up code formatting and comments for clarity.
21
+ - b04c00b Refactor coverage check script to use node imports.
22
+ - b04c00b Adjust TypeDoc script for ESM compatibility.
23
+ - 3af2fcb Fix path resolution in tsconfig for better module imports.
24
+
25
+ ### Testes
26
+ - b04c00b Implement tests for CookieBanner to verify rendering based on consent and debug mode.
27
+ - b04c00b Enhance FloatingPreferencesButton tests to check for localized text via props.
28
+ - b04c00b Extend PreferencesModal tests to cover temporary preference resets, active scripts rendering, and custom text application.
29
+
30
+ ### Documentação
31
+ - d430eef docs: atualizar instruções para agentes com visão geral do projeto e comandos essenciais
32
+ - d430eef Updated documentation to reflect changes in globalThis usage.
33
+ - d430eef Update API documentation to include new integration functions and ESM/CJS testing configurations.
34
+
35
+ - Updated dependencies [[`44b885b`](https://github.com/lucianoedipo/react-lgpd-consent/commit/44b885b7c81f1cb5822e2dcfde2975e69e8d4893)]:
36
+ - @react-lgpd-consent/core@0.7.2
37
+ - @react-lgpd-consent/mui@0.7.2
38
+
39
+ ## 0.7.1
40
+
41
+ ### Patch Changes
42
+
43
+ - [#133](https://github.com/lucianoedipo/react-lgpd-consent/pull/133) [`33bc0eb`](https://github.com/lucianoedipo/react-lgpd-consent/commit/33bc0ebcb40ce65c70b02668d3c0a97efb1854f1) Thanks [@lucianoedipo](https://github.com/lucianoedipo)! - # 🧩 Fundamento Crítico de Consentimento — SUPER TASK v0.7.1
44
+
45
+ **Persistência + Loader + Consent Mode v2**
46
+
47
+ Esta release estabelece o **núcleo legal, técnico e funcional** da biblioteca react-lgpd-consent, garantindo um contrato sólido, seguro e auditável para uso institucional e governamental.
48
+
49
+ ***
50
+
51
+ ## 🔹 Bloco A — Persistência de Consentimento por Cookie
52
+
53
+ ### ✨ API Consolidada de Persistência
54
+
55
+ Nova API completa no `ConsentProvider`:
56
+
57
+ ```typescript
58
+ <ConsentProvider
59
+ cookie={{
60
+ name: 'lgpd-consent',
61
+ domain: '.example.com', // Compartilha entre subdomínios
62
+ path: '/',
63
+ sameSite: 'Lax', // Default seguro
64
+ secure: true, // Auto em HTTPS
65
+ maxAge: 31536000, // Segundos (substitui maxAgeDays)
66
+ }}
67
+ >
68
+ ```
69
+
70
+ **Regras Implementadas:**
71
+ - ✅ Defaults seguros: `SameSite=Lax`, `Secure=true` em HTTPS
72
+ - ✅ Categoria `necessary` **sempre forçada como true**
73
+ - ✅ Nenhuma gravação de cookie durante SSR
74
+ - ✅ Suporte completo a subdomínios via `domain`
75
+ - ✅ Nova opção `maxAge` (segundos, padrão moderno)
76
+ - ✅ Opção `maxAgeDays` deprecated mas mantida para compatibilidade
77
+
78
+ **Ambientes Suportados:**
79
+ - ✅ `localhost` (desenvolvimento)
80
+ - ✅ `dev` / `staging` (domínios customizados)
81
+ - ✅ `production` (HTTPS obrigatório)
82
+ - ✅ Comportamento **independente de NODE_ENV**
83
+
84
+ ***
85
+
86
+ ## 🔹 Bloco B — ConsentScriptLoader com Bloqueio Real
87
+
88
+ ### 🚫 Contrato de Bloqueio Garantido
89
+
90
+ > **Nenhum script não necessário executa antes do consentimento correspondente.**
91
+
92
+ ### ✨ Sistema de Fila e Priorização
93
+
94
+ Implementado `ConsentScriptLoader` com:
95
+
96
+ ```typescript
97
+ registerScript({
98
+ id: 'google-analytics',
99
+ category: 'analytics',
100
+ priority: 1, // Ordem de execução
101
+ execute: () => {
102
+ // Seu script aqui
103
+ },
104
+ onConsentUpdate: (granted) => {
105
+ // Reagir a mudanças de consentimento
106
+ },
107
+ })
108
+ ```
109
+
110
+ **Recursos Implementados:**
111
+ - ✅ **Fila interna de execução** com ordenação por:
112
+ - 1. Categoria (`necessary` → `analytics` → `marketing`, etc.)
113
+ - 2. Prioridade (numérica)
114
+ - 3. Timestamp (ordem de registro)
115
+ - ✅ Scripts `necessary` executam **imediatamente**
116
+ - ✅ Scripts de outras categorias aguardam **consentimento explícito**
117
+ - ✅ Suporte a `onConsentUpdate` para reconfiguração dinâmica
118
+ - ✅ Snapshot de consentimento para scripts que precisam do estado atual
119
+ - ✅ **Otimização anti-duplicação**: integrações não são reexecutadas a cada render quando criadas inline (ex.: `integrations={[createGoogleAnalyticsIntegration(...)]}`). Sistema mantém hash estrutural para detectar mudanças reais e prevenir múltiplas inicializações do mesmo script.
120
+
121
+ **Observabilidade em DEV:**
122
+ - ✅ Logs detalhados de ordem de execução
123
+ - ✅ Indicação clara de categoria liberada
124
+ - ✅ Rastreamento de status de cada script
125
+ - ⚠️ **Silencioso em produção** (performance otimizada)
126
+
127
+ ***
128
+
129
+ ## 🔹 Bloco C — Integração Nativa Google Consent Mode v2
130
+
131
+ ### 🎯 Implementação Automática
132
+
133
+ **Zero configuração manual necessária!**
134
+
135
+ ```typescript
136
+ import { createGoogleAnalyticsIntegration } from '@react-lgpd-consent/core'
137
+
138
+ const ga4 = createGoogleAnalyticsIntegration({
139
+ measurementId: 'G-XXXXXXXXXX'
140
+ })
141
+
142
+ <ConsentScriptLoader integrations={[ga4]} />
143
+ ```
144
+
145
+ **O que a biblioteca faz automaticamente:**
146
+ 1. ✅ Inicializa `dataLayer` se não existir
147
+ 2. ✅ Define `gtag('consent', 'default', denied)` **antes** de qualquer tag
148
+ 3. ✅ Mapeia categorias corretamente:
149
+ - `analytics` → `analytics_storage`
150
+ - `marketing` → `ad_storage`, `ad_user_data`, `ad_personalization`
151
+ 4. ✅ Envia `gtag('consent', 'update')` quando usuário escolhe preferências
152
+ 5. ✅ Dispara eventos de ciclo de vida:
153
+ ```javascript
154
+ { event: 'consent_initialized' }
155
+ { event: 'consent_updated', preferences: {...} }
156
+ ```
157
+
158
+ **Factories Implementadas:**
159
+ - ✅ `createGoogleAnalyticsIntegration` (GA4)
160
+ - ✅ `createGoogleTagManagerIntegration` (GTM)
161
+ - ✅ Suporte a `bootstrap()` para inicialização pré-consentimento
162
+ - ✅ Suporte a `onConsentUpdate()` para reconfiguração dinâmica
163
+
164
+ ### 🔒 Ordem de Inicialização Segura
165
+
166
+ Fluxo garantido pela implementação:
167
+
168
+ ```
169
+ 1. dataLayer criado
170
+ 2. gtag('consent', 'default', denied)
171
+ 3. Loader bloqueia tags
172
+ 4. Usuário consente
173
+ 5. gtag('consent', 'update', granted/denied)
174
+ 6. Tags disparam conforme consentimento
175
+ ```
176
+
177
+ ### ⚡ Compatibilidade Next.js (SSR)
178
+ - ✅ Nenhum acesso a `window` fora de `useEffect`
179
+ - ✅ App Router (Next.js 13+)
180
+ - ✅ Pages Router (Next.js 12+)
181
+ - ✅ **Zero hydration mismatch**
182
+ - ✅ Estratégia de renderização: `client-only` quando necessário
183
+
184
+ ***
185
+
186
+ ## 🆕 Novas APIs Públicas
187
+
188
+ ### Core Package (`@react-lgpd-consent/core`):
189
+
190
+ ```typescript
191
+ // Registro de scripts
192
+ registerScript(config: RegisteredScript): void
193
+
194
+ // Factories de integrações
195
+ createGoogleAnalyticsIntegration(config): ScriptIntegration
196
+ createGoogleTagManagerIntegration(config): ScriptIntegration
197
+
198
+ // Utilitários de cookie
199
+ readConsentCookie(name?: string): ConsentState | null
200
+ writeConsentCookie(state: ConsentState, options?: CookieOptions): void
201
+
202
+ // Novos tipos
203
+ type RegisteredScript = { ... }
204
+ type ScriptIntegration = { ... }
205
+ interface LoadScriptOptions = { ... }
206
+ ```
207
+
208
+ ***
209
+
210
+ ## 📚 Documentação Atualizada
211
+ - ✅ **API.md** - Novas APIs de `registerScript` e Consent Mode v2
212
+ - ✅ **INTEGRACOES.md** - Guias completos de GA4, GTM, Facebook Pixel
213
+ - ✅ **MIGRATION.md** - Guia de migração v0.7.0 → v0.7.1
214
+ - ✅ **SUPER_TASK_VALIDATION.md** - Relatório técnico de validação completo
215
+
216
+ ***
217
+
218
+ ## 🔄 Breaking Changes
219
+
220
+ **Nenhum!** Esta release é 100% backward-compatible:
221
+ - ✅ Opção `maxAgeDays` deprecated mas funcional
222
+ - ✅ Comportamento padrão preservado
223
+ - ✅ APIs antigas continuam funcionando
224
+ - ✅ Migração gradual suportada
225
+
226
+ ***
227
+
228
+ ## 🎯 Melhorias Complementares
229
+
230
+ ### Sistema de i18n para Diagnósticos
231
+
232
+ Sistema básico de internacionalização para mensagens de peer dependencies:
233
+ - ✅ Suporte a pt-BR (padrão) e en
234
+ - ✅ API para customização: `setPeerDepsLocale()`, `setPeerDepsMessages()`
235
+ - ✅ Mensagens extraídas para constantes (melhor manutenibilidade)
236
+
237
+ ### Refatorações e Otimizações
238
+ - ✅ Strings de mensagens extraídas para constantes
239
+ - ✅ Separação de concerns (lógica vs conteúdo)
240
+ - ✅ Type safety aprimorado em toda API
241
+ - ✅ Performance otimizada (sem logs em produção)
242
+ - ✅ **Fix crítico**: Prevenção de reexecução de integrações a cada render quando `integrations` prop muda referência (inline array). Sistema agora usa hash estrutural para detectar mudanças reais e manter scripts já registrados estáveis.
243
+
244
+ - Updated dependencies [[`33bc0eb`](https://github.com/lucianoedipo/react-lgpd-consent/commit/33bc0ebcb40ce65c70b02668d3c0a97efb1854f1)]:
245
+ - @react-lgpd-consent/core@0.7.1
246
+ - @react-lgpd-consent/mui@0.7.1
247
+
3
248
  ## 0.7.0
4
249
 
5
250
  ### Minor Changes
@@ -153,7 +398,7 @@
153
398
  - **Correção crítica**: `loadScript` agora aguarda dinamicamente o consentimento em vez de rejeitar imediatamente, permitindo que scripts carreguem quando preferências mudarem
154
399
  - Cleanup automático do registro ao completar/falhar carregamento
155
400
  - Adicionados testes extensivos: `ConsentScriptLoader.strictmode.test.tsx` e `scriptLoader.strictmode.test.ts`
156
- - Documentação completa em `docs/REACT19-STRICTMODE.md`
401
+ - Documentação completa em `REACT19-STRICTMODE.md`
157
402
  - Todos os 302 testes passando, incluindo 5 novos testes de StrictMode
158
403
 
159
404
  **Breaking Changes:** Nenhuma - totalmente retrocompatível
package/INTEGRACOES.md CHANGED
@@ -6,6 +6,42 @@ A biblioteca oferece integrações nativas para as ferramentas mais comuns, elim
6
6
 
7
7
  O componente `ConsentScriptLoader` gerencia o carregamento desses scripts automaticamente, disparando-os apenas quando o usuário concede consentimento para a categoria correspondente.
8
8
 
9
+ ### ✅ Regras de Configuração (RN)
10
+
11
+ - **Categoria padrão com override**: cada integração define uma categoria padrão, mas o consumidor pode sobrescrever via `category` no config.
12
+ - **Config obrigatória**: se um campo obrigatório estiver vazio (ex.: `measurementId`, `containerId`, `pixelId`), a integração **não executa**. Em **dev** é logado erro; em **prod** não há log.
13
+ - **DataLayer**: se `globalThis.window.dataLayer` não existir, a biblioteca cria `[]`; se existir e tiver `push`, usa como está; se existir sem `push`, não sobrescreve e avisa em dev.
14
+
15
+ ### ✨ Novidades v0.7.1
16
+
17
+ - **🎯 Google Consent Mode v2 Automático**: GA4 e GTM agora implementam Consent Mode v2 automaticamente:
18
+ - `bootstrap`: Seta `consent('default', 'denied')` antes de qualquer carregamento
19
+ - `onConsentUpdate`: Envia `consent('update', 'granted')` quando usuário consente
20
+ - Zero configuração manual necessária!
21
+
22
+ - **🔄 Sistema de Fila com Prioridade**: Scripts são executados ordenadamente:
23
+ 1. Categoria `necessary` sempre primeiro
24
+ 2. Dentro da mesma categoria: maior `priority` primeiro
25
+ 3. Mesmo priority: ordem de registro (timestamp)
26
+
27
+ - **📝 API `registerScript()`**: Registre scripts programaticamente fora do JSX:
28
+
29
+ ```tsx
30
+ import { registerScript } from 'react-lgpd-consent'
31
+
32
+ const cleanup = registerScript({
33
+ id: 'my-script',
34
+ category: 'analytics',
35
+ priority: 5,
36
+ execute: async () => {
37
+ /* carrega script */
38
+ },
39
+ onConsentUpdate: ({ preferences }) => {
40
+ /* reage a mudanças */
41
+ },
42
+ })
43
+ ```
44
+
9
45
  > 💡 **Procurando exemplos práticos?** Veja [RECIPES.md](../../RECIPES.md) para receitas passo a passo de Google Consent Mode v2, Next.js App Router e CSP/nonce.
10
46
 
11
47
  ## 🎯 Integrações Nativas Disponíveis
@@ -15,6 +51,7 @@ O componente `ConsentScriptLoader` gerencia o carregamento desses scripts automa
15
51
  - **Categoria**: `analytics`
16
52
  - **Função**: `createGoogleAnalyticsIntegration(config)`
17
53
  - **Descrição**: Integração completa com o Google Analytics 4. Suporta `measurementId` e configurações adicionais para o `gtag`.
54
+ - **✨ Novo v0.7.1**: Google Consent Mode v2 automático (sem configuração manual)
18
55
 
19
56
  ```tsx
20
57
  import { createGoogleAnalyticsIntegration, ConsentScriptLoader } from 'react-lgpd-consent'
@@ -27,20 +64,28 @@ const integrations = [
27
64
  ]
28
65
 
29
66
  <ConsentScriptLoader integrations={integrations} />
67
+ // ✅ Consent Mode v2 implementado automaticamente:
68
+ // - bootstrap: consent('default', 'denied') antes do script
69
+ // - onConsentUpdate: consent('update', 'granted') após consentimento
30
70
  ```
31
71
 
32
72
  ### 2. Google Tag Manager (GTM)
33
73
 
34
74
  - **Categoria**: `analytics`
35
75
  - **Função**: `createGoogleTagManagerIntegration(config)`
36
- - **Descrição**: Carrega o container do Google Tag Manager. Suporta `gtmId` e `dataLayerName`.
76
+ - **Descrição**: Carrega o container do Google Tag Manager. Suporta `containerId` (ou `gtmId` legado) e `dataLayerName`.
77
+ - **✨ Novo v0.7.1**: Google Consent Mode v2 automático com dataLayer customizado
37
78
 
38
79
  ```tsx
39
80
  import { createGoogleTagManagerIntegration } from 'react-lgpd-consent'
40
81
 
41
82
  const integrations = [
42
- createGoogleTagManagerIntegration({ gtmId: 'GTM-XXXXXXX' })
83
+ createGoogleTagManagerIntegration({
84
+ containerId: 'GTM-XXXXXXX',
85
+ dataLayerName: 'dataLayer', // opcional
86
+ }),
43
87
  ]
88
+ // ✅ Consent Mode v2 no dataLayer customizado automaticamente
44
89
  ```
45
90
 
46
91
  ### 3. Facebook Pixel
@@ -52,9 +97,7 @@ const integrations = [
52
97
  ```tsx
53
98
  import { createFacebookPixelIntegration } from 'react-lgpd-consent'
54
99
 
55
- const integrations = [
56
- createFacebookPixelIntegration({ pixelId: 'YOUR_PIXEL_ID', autoTrack: true })
57
- ]
100
+ const integrations = [createFacebookPixelIntegration({ pixelId: 'YOUR_PIXEL_ID', autoTrack: true })]
58
101
  ```
59
102
 
60
103
  ### 4. Hotjar
@@ -136,13 +179,18 @@ const integrations = [createUserWayIntegration({ accountId: 'USERWAY_ACCOUNT_ID'
136
179
  Para simplificar a configuração de múltiplas integrações, a biblioteca oferece templates e funções de ajuda.
137
180
 
138
181
  - `suggestCategoryForScript(name: string)`: Sugere a categoria LGPD apropriada para um nome de script conhecido.
182
+ - `createSuggestedIntegration(config)`: Cria integração customizada com categoria sugerida automaticamente (pode sobrescrever com `category`).
139
183
  - `createECommerceIntegrations`, `createSaaSIntegrations`, `createCorporateIntegrations`: Templates de negócio que agrupam as integrações mais comuns para cada setor.
140
184
  - `INTEGRATION_TEMPLATES`: Constante com presets de IDs e categorias para cada template.
141
185
 
142
186
  ### Exemplo de Template (E-commerce)
143
187
 
144
188
  ```tsx
145
- import { ConsentProvider, ConsentScriptLoader, createECommerceIntegrations } from 'react-lgpd-consent'
189
+ import {
190
+ ConsentProvider,
191
+ ConsentScriptLoader,
192
+ createECommerceIntegrations,
193
+ } from 'react-lgpd-consent'
146
194
 
147
195
  function App() {
148
196
  const integrations = createECommerceIntegrations({
@@ -160,6 +208,19 @@ function App() {
160
208
  }
161
209
  ```
162
210
 
211
+ ### Exemplo de integração sugerida (custom)
212
+
213
+ ```tsx
214
+ import { createSuggestedIntegration } from 'react-lgpd-consent'
215
+
216
+ const integrations = [
217
+ createSuggestedIntegration({
218
+ id: 'custom-chat',
219
+ src: 'https://example.com/chat.js',
220
+ }),
221
+ ]
222
+ ```
223
+
163
224
  ---
164
225
 
165
226
  ## 🔎 Descoberta Automática de Cookies (Experimental v0.4.1)
@@ -185,6 +246,7 @@ categorizeDiscoveredCookies(discovered, true)
185
246
  ## 🧱 Nota SSR/Next.js (App Router)
186
247
 
187
248
  Para evitar hydration mismatch e vazamento de scripts:
249
+
188
250
  - Coloque o `ConsentProvider` dentro de um Client Component e carregue-o com `dynamic(..., { ssr: false })` a partir do `RootLayout` (Server Component).
189
251
  - Use o `ConsentScriptLoader` para carregar GTM/GA4 somente após consentimento e inicialize o Consent Mode v2 com `gtag('consent','default', denied)` antes de qualquer script.
190
252
  - Consulte a seção “SSR/Next.js (App Router) — Padrões seguros” em `QUICKSTART.md` para ordem dos provedores/estilos (MUI/Emotion) e checklist SSR.
@@ -211,6 +273,12 @@ interface ScriptIntegration {
211
273
 
212
274
  A partir da versão **0.4.5**, a biblioteca dispara automaticamente eventos padronizados no `dataLayer` para facilitar rastreamento, auditoria LGPD e integrações com o Google Tag Manager.
213
275
 
276
+ ### Comportamento do `dataLayer`
277
+
278
+ - Se `globalThis.window.dataLayer` não existir, a biblioteca cria `[]`.
279
+ - Se existir e tiver `push`, o array/objeto é usado como está.
280
+ - Se existir sem `push`, a biblioteca não sobrescreve e avisa em dev.
281
+
214
282
  ### Eventos Disponíveis
215
283
 
216
284
  #### 1. `consent_initialized`
@@ -218,6 +286,7 @@ A partir da versão **0.4.5**, a biblioteca dispara automaticamente eventos padr
218
286
  Disparado quando o sistema de consentimento é inicializado (após hidratação).
219
287
 
220
288
  **Payload:**
289
+
221
290
  ```typescript
222
291
  {
223
292
  event: 'consent_initialized',
@@ -232,6 +301,7 @@ Disparado quando o sistema de consentimento é inicializado (após hidratação)
232
301
  ```
233
302
 
234
303
  **Exemplo de uso no GTM:**
304
+
235
305
  - **Tipo de acionador**: Evento personalizado
236
306
  - **Nome do evento**: `consent_initialized`
237
307
  - **Variáveis**: `{{categories.analytics}}`, `{{categories.marketing}}`, etc.
@@ -241,6 +311,7 @@ Disparado quando o sistema de consentimento é inicializado (após hidratação)
241
311
  Disparado sempre que o usuário atualiza suas preferências de consentimento.
242
312
 
243
313
  **Payload:**
314
+
244
315
  ```typescript
245
316
  {
246
317
  event: 'consent_updated',
@@ -257,6 +328,7 @@ Disparado sempre que o usuário atualiza suas preferências de consentimento.
257
328
  ```
258
329
 
259
330
  **Exemplo de uso no GTM:**
331
+
260
332
  - **Tipo de acionador**: Evento personalizado
261
333
  - **Nome do evento**: `consent_updated`
262
334
  - **Condição**: `{{changed_categories}}` contém `analytics`
@@ -313,7 +385,7 @@ Crie uma tag para registrar mudanças de consentimento em um sistema de auditori
313
385
  categories: {{DLV - Consent Categories}},
314
386
  changed: {{DLV - Changed Categories}}
315
387
  };
316
-
388
+
317
389
  // Enviar para seu sistema de auditoria
318
390
  fetch('/api/consent-audit', {
319
391
  method: 'POST',
@@ -336,9 +408,9 @@ const handleCustomUpdate = () => {
336
408
  const newPreferences = {
337
409
  necessary: true,
338
410
  analytics: true,
339
- marketing: false
411
+ marketing: false,
340
412
  }
341
-
413
+
342
414
  pushConsentUpdatedEvent(newPreferences, 'programmatic')
343
415
  }
344
416
  ```
@@ -350,7 +422,7 @@ import type {
350
422
  ConsentEvent,
351
423
  ConsentEventOrigin,
352
424
  ConsentInitializedEvent,
353
- ConsentUpdatedEvent
425
+ ConsentUpdatedEvent,
354
426
  } from 'react-lgpd-consent'
355
427
 
356
428
  // Origem da ação
@@ -389,7 +461,6 @@ interface ConsentUpdatedEvent {
389
461
  | Live Chat | `functional` | Funcionalidade de suporte |
390
462
  | YouTube/Vimeo | `social` | Conteúdo de redes sociais |
391
463
 
392
-
393
464
  ---
394
465
 
395
466
  ## 🆕 Recursos Avançados v0.7.0
@@ -402,7 +473,7 @@ Integre sistemas de auditoria monitorando eventos de consentimento:
402
473
  import { ConsentProvider, ConsentScriptLoader } from 'react-lgpd-consent'
403
474
  import { googleAnalytics4Integration } from './integrations'
404
475
 
405
- <ConsentProvider
476
+ ;<ConsentProvider
406
477
  categories={{ enabledCategories: ['analytics', 'marketing'] }}
407
478
  onConsentInit={(state) => {
408
479
  // Disparado na inicialização (útil para analytics)
@@ -411,19 +482,19 @@ import { googleAnalytics4Integration } from './integrations'
411
482
  onConsentChange={(current, previous) => {
412
483
  // Disparado em toda mudança de preferências
413
484
  console.log('Mudança:', { current, previous })
414
-
485
+
415
486
  // Exemplo: disparar evento no dataLayer
416
- window.dataLayer?.push({
487
+ globalThis.window?.dataLayer?.push({
417
488
  event: 'consent_preferences_updated',
418
489
  consent_analytics: current.preferences.analytics,
419
- consent_marketing: current.preferences.marketing
490
+ consent_marketing: current.preferences.marketing,
420
491
  })
421
492
  }}
422
493
  onAuditLog={(entry) => {
423
494
  // Enviar para backend de compliance
424
495
  fetch('/api/consent-audit', {
425
496
  method: 'POST',
426
- body: JSON.stringify(entry)
497
+ body: JSON.stringify(entry),
427
498
  })
428
499
  }}
429
500
  >
@@ -460,6 +531,7 @@ const customConfig = createAnpdCategories({
460
531
  ```
461
532
 
462
533
  **Vantagens dos presets:**
534
+
463
535
  - ✅ Conformidade com diretrizes ANPD
464
536
  - ✅ Nomes e descrições em pt-BR revisadas
465
537
  - ✅ Tipagem forte para evitar erros
package/QUICKSTART.en.md CHANGED
@@ -273,13 +273,13 @@ function MyComponent() {
273
273
  }
274
274
  ```
275
275
 
276
- ### Global: `window.openPreferencesModal` (for plain JS)
276
+ ### Global: `globalThis.window.openPreferencesModal` (for plain JS)
277
277
 
278
278
  ```html
279
- <button onclick="window.openPreferencesModal?.()">Configure cookies</button>
279
+ <button onclick="globalThis.window?.openPreferencesModal?.()">Configure cookies</button>
280
280
 
281
281
  <script>
282
- if (typeof window.openPreferencesModal === 'function') {
282
+ if (typeof globalThis.window?.openPreferencesModal === 'function') {
283
283
  console.log('Consent system available')
284
284
  }
285
285
  </script>
package/QUICKSTART.md CHANGED
@@ -257,7 +257,13 @@ function BootstrapConsentMode() {
257
257
  React.useEffect(() => {
258
258
  const w = window as any
259
259
  w.dataLayer = w.dataLayer ?? []
260
- w.gtag = w.gtag ?? ((...args: any[]) => w.dataLayer.push(args))
260
+ w.gtag =
261
+ w.gtag ??
262
+ ((...args: any[]) => {
263
+ if (typeof w.dataLayer?.push === 'function') {
264
+ w.dataLayer.push(args)
265
+ }
266
+ })
261
267
  w.gtag('consent', 'default', {
262
268
  ad_storage: 'denied',
263
269
  ad_user_data: 'denied',
@@ -486,7 +492,11 @@ function ComplianceWrapper({ children }: { children: React.ReactNode }) {
486
492
  }}
487
493
  onConsentVersionChange={({ previousKey, nextKey, resetConsent }) => {
488
494
  console.info('[consent] versão atualizada', { previousKey, nextKey })
489
- window.dataLayer?.push({ event: 'consent_version_bumped', previousKey, nextKey })
495
+ globalThis.window?.dataLayer?.push({
496
+ event: 'consent_version_bumped',
497
+ previousKey,
498
+ nextKey,
499
+ })
490
500
  localStorage.removeItem('marketing-optins')
491
501
  resetConsent()
492
502
  }}
@@ -948,24 +958,24 @@ function MeuComponente() {
948
958
  }
949
959
  ```
950
960
 
951
- ### window.openPreferencesModal (JavaScript Puro)
961
+ ### globalThis.window.openPreferencesModal (JavaScript Puro)
952
962
 
953
963
  ```html
954
964
  <!-- Em templates HTML, emails ou widgets externos -->
955
- <button onclick="window.openPreferencesModal?.()">Configurar Cookies</button>
965
+ <button onclick="globalThis.window?.openPreferencesModal?.()">Configurar Cookies</button>
956
966
 
957
967
  <script>
958
968
  // Ou em JavaScript puro
959
969
  function abrirConfiguracoesCookies() {
960
- if (window.openPreferencesModal) {
961
- window.openPreferencesModal()
970
+ if (globalThis.window?.openPreferencesModal) {
971
+ globalThis.window.openPreferencesModal()
962
972
  } else {
963
973
  console.warn('Sistema de consentimento não carregado')
964
974
  }
965
975
  }
966
976
 
967
977
  // Verificar se função está disponível
968
- if (typeof window.openPreferencesModal === 'function') {
978
+ if (typeof globalThis.window?.openPreferencesModal === 'function') {
969
979
  console.log('✅ Sistema de consentimento disponível')
970
980
  }
971
981
  </script>
package/README.en.md CHANGED
@@ -76,7 +76,7 @@ function Analytics() {
76
76
  src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
77
77
  strategy="afterInteractive"
78
78
  >
79
- {`window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID');`}
79
+ {`globalThis.window && (globalThis.window.dataLayer = globalThis.window.dataLayer || []); function gtag(){ if (typeof globalThis.window?.dataLayer?.push === 'function') { globalThis.window.dataLayer.push(arguments) } } gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID');`}
80
80
  </ConsentScriptLoader>
81
81
  )
82
82
  }
@@ -174,4 +174,3 @@ MIT © Luciano Edipo — see the `LICENSE` file.
174
174
  ---
175
175
 
176
176
  If you want the Portuguese README, see `README.md` in the same package.
177
-
package/README.md CHANGED
@@ -13,7 +13,7 @@ Gerenciamento de consentimento de cookies em conformidade com a LGPD — pacote
13
13
 
14
14
  ## Descrição
15
15
 
16
- `react-lgpd-consent` é o pacote agregador compatível com versões anteriores (v0.4.x → v0.5.x). Ele re-exporta os componentes prontos em MUI e facilita a migração. Para projetos mais otimizados, considere importar diretamente `@react-lgpd-consent/core` (headless) ou `@react-lgpd-consent/mui` (componentes MUI).
16
+ `react-lgpd-consent` é o pacote agregador compatível com versões anteriores (v0.4.x → v0.5.x). Ele re-exporta os componentes prontos em MUI e facilita a migração. Para projetos mais otimizados, considere importar diretamente `@react-lgpd-consent/core` (headless) ou `@react-lgpd-consent/mui/ui` (apenas UI, sem re-export do core).
17
17
 
18
18
  Principais características:
19
19
 
@@ -76,7 +76,7 @@ function Analytics() {
76
76
  src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
77
77
  strategy="afterInteractive"
78
78
  >
79
- {`window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID');`}
79
+ {`globalThis.window && (globalThis.window.dataLayer = globalThis.window.dataLayer ?? []); function gtag(){ if (typeof globalThis.window?.dataLayer?.push === 'function') { globalThis.window.dataLayer.push(arguments) } } gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID');`}
80
80
  </ConsentScriptLoader>
81
81
  )
82
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-lgpd-consent",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Biblioteca de consentimento LGPD, integrações nativas e sistema extensível para React.",
5
5
  "keywords": [
6
6
  "lgpd",
@@ -94,8 +94,8 @@
94
94
  }
95
95
  },
96
96
  "dependencies": {
97
- "@react-lgpd-consent/core": "^0.7.0",
98
- "@react-lgpd-consent/mui": "^0.7.0"
97
+ "@react-lgpd-consent/core": "^0.7.2",
98
+ "@react-lgpd-consent/mui": "^0.7.2"
99
99
  },
100
100
  "size-limit": [
101
101
  {
@@ -117,7 +117,7 @@
117
117
  "name": "Complete Package Import",
118
118
  "path": "dist/index.js",
119
119
  "import": "{ ConsentProvider, useConsent, ConsentScriptLoader }",
120
- "limit": "70 KB"
120
+ "limit": "80 KB"
121
121
  }
122
122
  ],
123
123
  "scripts": {