@jwiedeman/gtm-kit-react-legacy 1.0.1
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/README.md +256 -0
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# @react-gtm-kit/react-legacy
|
|
2
|
+
|
|
3
|
+
[](https://github.com/jwiedeman/react-gtm-kit/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/jwiedeman/react-gtm-kit)
|
|
5
|
+
[](https://www.npmjs.com/package/@react-gtm-kit/react-legacy)
|
|
6
|
+
[](https://bundlephobia.com/package/@react-gtm-kit/react-legacy)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://reactjs.org/)
|
|
10
|
+
|
|
11
|
+
**React Higher-Order Component (HOC) for Google Tag Manager. For class components and pre-hooks React.**
|
|
12
|
+
|
|
13
|
+
The legacy React adapter for GTM Kit - uses HOC pattern for class component compatibility.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @react-gtm-kit/core @react-gtm-kit/react-legacy
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add @react-gtm-kit/core @react-gtm-kit/react-legacy
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @react-gtm-kit/core @react-gtm-kit/react-legacy
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## When to Use This Package
|
|
34
|
+
|
|
35
|
+
Use `@react-gtm-kit/react-legacy` if:
|
|
36
|
+
|
|
37
|
+
- You're using class components
|
|
38
|
+
- Your project uses React < 16.8 (no hooks)
|
|
39
|
+
- You prefer the HOC pattern
|
|
40
|
+
- You're maintaining a legacy codebase
|
|
41
|
+
|
|
42
|
+
**For new projects**, we recommend [`@react-gtm-kit/react-modern`](https://www.npmjs.com/package/@react-gtm-kit/react-modern) which uses hooks.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### Step 1: Wrap Your App
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { withGtm } from '@react-gtm-kit/react-legacy';
|
|
52
|
+
|
|
53
|
+
class App extends React.Component {
|
|
54
|
+
render() {
|
|
55
|
+
return <YourApp />;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default withGtm(App, { containers: 'GTM-XXXXXX' });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Step 2: Push Events
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { withGtmPush } from '@react-gtm-kit/react-legacy';
|
|
66
|
+
|
|
67
|
+
class BuyButton extends React.Component {
|
|
68
|
+
handleClick = () => {
|
|
69
|
+
this.props.gtmPush({ event: 'purchase', value: 49.99 });
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
render() {
|
|
73
|
+
return <button onClick={this.handleClick}>Buy Now</button>;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default withGtmPush(BuyButton);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Features
|
|
83
|
+
|
|
84
|
+
| Feature | Description |
|
|
85
|
+
|---------|-------------|
|
|
86
|
+
| **HOC Pattern** | Works with class components |
|
|
87
|
+
| **React 16.0+** | Compatible with older React versions |
|
|
88
|
+
| **StrictMode-Safe** | No double-fires in development mode |
|
|
89
|
+
| **TypeScript** | Full type definitions included |
|
|
90
|
+
| **Consent Mode v2** | Built-in GDPR compliance support |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Available HOCs
|
|
95
|
+
|
|
96
|
+
### `withGtm(Component, config)`
|
|
97
|
+
|
|
98
|
+
Wraps your root component and initializes GTM.
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { withGtm } from '@react-gtm-kit/react-legacy';
|
|
102
|
+
|
|
103
|
+
class App extends React.Component {
|
|
104
|
+
render() {
|
|
105
|
+
return <div>{this.props.children}</div>;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export default withGtm(App, {
|
|
110
|
+
containers: 'GTM-XXXXXX',
|
|
111
|
+
dataLayerName: 'dataLayer', // optional
|
|
112
|
+
onBeforeInit: (client) => {
|
|
113
|
+
// Set consent defaults here
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `withGtmPush(Component)`
|
|
119
|
+
|
|
120
|
+
Injects a `gtmPush` prop for pushing events.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { withGtmPush } from '@react-gtm-kit/react-legacy';
|
|
124
|
+
|
|
125
|
+
class TrackableButton extends React.Component {
|
|
126
|
+
handleClick = () => {
|
|
127
|
+
this.props.gtmPush({ event: 'button_click', button_id: 'main-cta' });
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
render() {
|
|
131
|
+
return <button onClick={this.handleClick}>Click Me</button>;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default withGtmPush(TrackableButton);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### `withGtmConsent(Component)`
|
|
139
|
+
|
|
140
|
+
Injects consent management props.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { withGtmConsent } from '@react-gtm-kit/react-legacy';
|
|
144
|
+
|
|
145
|
+
class CookieBanner extends React.Component {
|
|
146
|
+
acceptAll = () => {
|
|
147
|
+
this.props.updateConsent({
|
|
148
|
+
ad_storage: 'granted',
|
|
149
|
+
analytics_storage: 'granted',
|
|
150
|
+
ad_user_data: 'granted',
|
|
151
|
+
ad_personalization: 'granted'
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
render() {
|
|
156
|
+
return <button onClick={this.acceptAll}>Accept All</button>;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export default withGtmConsent(CookieBanner);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### `withGtmClient(Component)`
|
|
164
|
+
|
|
165
|
+
Injects the raw GTM client instance.
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import { withGtmClient } from '@react-gtm-kit/react-legacy';
|
|
169
|
+
|
|
170
|
+
class AdvancedComponent extends React.Component {
|
|
171
|
+
componentDidMount() {
|
|
172
|
+
this.props.gtmClient.whenReady().then(() => {
|
|
173
|
+
console.log('GTM is ready!');
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
render() {
|
|
178
|
+
return <div>Advanced GTM usage</div>;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export default withGtmClient(AdvancedComponent);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Consent Mode v2 (GDPR)
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import { withGtm, withGtmConsent } from '@react-gtm-kit/react-legacy';
|
|
191
|
+
import { consentPresets } from '@react-gtm-kit/core';
|
|
192
|
+
|
|
193
|
+
// Root component with consent defaults
|
|
194
|
+
class App extends React.Component {
|
|
195
|
+
render() {
|
|
196
|
+
return <div>{this.props.children}</div>;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export default withGtm(App, {
|
|
201
|
+
containers: 'GTM-XXXXXX',
|
|
202
|
+
onBeforeInit: (client) => {
|
|
203
|
+
client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Cookie banner component
|
|
208
|
+
class CookieBanner extends React.Component {
|
|
209
|
+
render() {
|
|
210
|
+
return (
|
|
211
|
+
<div>
|
|
212
|
+
<button onClick={() => this.props.updateConsent({ analytics_storage: 'granted' })}>
|
|
213
|
+
Accept Analytics
|
|
214
|
+
</button>
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default withGtmConsent(CookieBanner);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Migrating to react-modern
|
|
226
|
+
|
|
227
|
+
If you're upgrading your codebase to use hooks, migration is straightforward:
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
// Before (react-legacy)
|
|
231
|
+
class Button extends React.Component {
|
|
232
|
+
render() {
|
|
233
|
+
return <button onClick={() => this.props.gtmPush({ event: 'click' })}>Click</button>;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export default withGtmPush(Button);
|
|
237
|
+
|
|
238
|
+
// After (react-modern)
|
|
239
|
+
function Button() {
|
|
240
|
+
const push = useGtmPush();
|
|
241
|
+
return <button onClick={() => push({ event: 'click' })}>Click</button>;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Requirements
|
|
248
|
+
|
|
249
|
+
- React 16.0+
|
|
250
|
+
- `@react-gtm-kit/core` (peer dependency)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var gtmKit = require('@jwiedeman/gtm-kit');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
var m=o=>({client:o,push:t=>o.push(t),setConsentDefaults:(t,e)=>o.setConsentDefaults(t,e),updateConsent:(t,e)=>o.updateConsent(t,e)}),c=o=>{let{config:t,propName:e}=o,i=e!=null?e:"gtm";return function(n){class s extends react.Component{constructor(p){super(p);this.client=gtmKit.createGtmClient(t),this.api=m(this.client);}componentDidMount(){this.client.init();}componentWillUnmount(){this.client.teardown();}render(){let p={[i]:this.api};return jsxRuntime.jsx(n,{...this.props,...p})}}return s.displayName=`withGtm(${n.displayName||n.name||"Component"})`,s}};
|
|
8
|
+
|
|
9
|
+
exports.withGtm = c;
|
|
10
|
+
//# sourceMappingURL=out.js.map
|
|
11
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-gtm.tsx"],"names":["Component","createGtmClient","jsx","createLegacyApi","client","value","state","options","withGtm","config","propName","resolvedPropName","WrappedComponent","WithGtmComponent","props","injectedProps"],"mappings":"AAAA,OAAS,aAAAA,MAAqD,QAC9D,OACE,mBAAAC,MAMK,qBA6DQ,cAAAC,MAAA,oBA3Cf,IAAMC,EAAmBC,IAAqC,CAC5D,OAAAA,EACA,KAAOC,GAAUD,EAAO,KAAKC,CAAK,EAClC,mBAAoB,CAACC,EAAOC,IAAYH,EAAO,mBAAmBE,EAAOC,CAAO,EAChF,cAAe,CAACD,EAAOC,IAAYH,EAAO,cAAcE,EAAOC,CAAO,CACxE,GAEaC,EAA4CD,GAAsC,CAC7F,GAAM,CAAE,OAAAE,EAAQ,SAAAC,CAAS,EAAIH,EACvBI,EAAoBD,GAAA,KAAAA,EAAY,MAItC,OAAO,SACLE,EAC6C,CAG7C,MAAMC,UAAyBb,CAAsB,CAMnD,YAAYc,EAAmB,CAC7B,MAAMA,CAAK,EACX,KAAK,OAASb,EAAgBQ,CAAM,EACpC,KAAK,IAAMN,EAAgB,KAAK,MAAM,CACxC,CAEA,mBAA0B,CACxB,KAAK,OAAO,KAAK,CACnB,CAEA,sBAA6B,CAC3B,KAAK,OAAO,SAAS,CACvB,CAEA,QAAoB,CAClB,IAAMY,EAAgB,CACpB,CAACJ,CAAgB,EAAG,KAAK,GAC3B,EAEA,OAAOT,EAACU,EAAA,CAAkB,GAAI,KAAK,MAAyB,GAAGG,EAAe,CAChF,CACF,CAEA,OAAAF,EAAiB,YAAc,WAAWD,EAAiB,aAAeA,EAAiB,MAAQ,WAAW,IAEvGC,CACT,CACF","sourcesContent":["import { Component, type ComponentType, type ReactNode } from 'react';\nimport {\n createGtmClient,\n type ConsentRegionOptions,\n type ConsentState,\n type CreateGtmClientOptions,\n type DataLayerValue,\n type GtmClient\n} from '@jwiedeman/gtm-kit';\n\nexport interface LegacyGtmApi {\n client: GtmClient;\n push: (value: DataLayerValue) => void;\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n}\n\nexport interface WithGtmOptions<PropName extends string = 'gtm'> {\n config: CreateGtmClientOptions;\n propName?: PropName;\n}\n\nexport type LegacyGtmProps<PropName extends string = 'gtm'> = {\n [Key in PropName]: LegacyGtmApi;\n};\n\nconst createLegacyApi = (client: GtmClient): LegacyGtmApi => ({\n client,\n push: (value) => client.push(value),\n setConsentDefaults: (state, options) => client.setConsentDefaults(state, options),\n updateConsent: (state, options) => client.updateConsent(state, options)\n});\n\nexport const withGtm = <PropName extends string = 'gtm'>(options: WithGtmOptions<PropName>) => {\n const { config, propName } = options;\n const resolvedPropName = (propName ?? 'gtm') as PropName;\n\n type InjectedProps = LegacyGtmProps<PropName>;\n\n return function wrapWithGtm<WrappedProps extends InjectedProps>(\n WrappedComponent: ComponentType<WrappedProps>\n ): ComponentType<Omit<WrappedProps, PropName>> {\n type OuterProps = Omit<WrappedProps, PropName>;\n\n class WithGtmComponent extends Component<OuterProps> {\n static displayName: string;\n\n private client: GtmClient;\n private api: LegacyGtmApi;\n\n constructor(props: OuterProps) {\n super(props);\n this.client = createGtmClient(config);\n this.api = createLegacyApi(this.client);\n }\n\n componentDidMount(): void {\n this.client.init();\n }\n\n componentWillUnmount(): void {\n this.client.teardown();\n }\n\n render(): ReactNode {\n const injectedProps = {\n [resolvedPropName]: this.api\n } as InjectedProps;\n\n return <WrappedComponent {...(this.props as WrappedProps)} {...injectedProps} />;\n }\n }\n\n WithGtmComponent.displayName = `withGtm(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n\n return WithGtmComponent;\n };\n};\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, CreateGtmClientOptions } from '@jwiedeman/gtm-kit';
|
|
3
|
+
|
|
4
|
+
interface LegacyGtmApi {
|
|
5
|
+
client: GtmClient;
|
|
6
|
+
push: (value: DataLayerValue) => void;
|
|
7
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
8
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
9
|
+
}
|
|
10
|
+
interface WithGtmOptions<PropName extends string = 'gtm'> {
|
|
11
|
+
config: CreateGtmClientOptions;
|
|
12
|
+
propName?: PropName;
|
|
13
|
+
}
|
|
14
|
+
type LegacyGtmProps<PropName extends string = 'gtm'> = {
|
|
15
|
+
[Key in PropName]: LegacyGtmApi;
|
|
16
|
+
};
|
|
17
|
+
declare const withGtm: <PropName extends string = "gtm">(options: WithGtmOptions<PropName>) => <WrappedProps extends LegacyGtmProps<PropName>>(WrappedComponent: ComponentType<WrappedProps>) => ComponentType<Omit<WrappedProps, PropName>>;
|
|
18
|
+
|
|
19
|
+
export { LegacyGtmApi, LegacyGtmProps, WithGtmOptions, withGtm };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, CreateGtmClientOptions } from '@jwiedeman/gtm-kit';
|
|
3
|
+
|
|
4
|
+
interface LegacyGtmApi {
|
|
5
|
+
client: GtmClient;
|
|
6
|
+
push: (value: DataLayerValue) => void;
|
|
7
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
8
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
9
|
+
}
|
|
10
|
+
interface WithGtmOptions<PropName extends string = 'gtm'> {
|
|
11
|
+
config: CreateGtmClientOptions;
|
|
12
|
+
propName?: PropName;
|
|
13
|
+
}
|
|
14
|
+
type LegacyGtmProps<PropName extends string = 'gtm'> = {
|
|
15
|
+
[Key in PropName]: LegacyGtmApi;
|
|
16
|
+
};
|
|
17
|
+
declare const withGtm: <PropName extends string = "gtm">(options: WithGtmOptions<PropName>) => <WrappedProps extends LegacyGtmProps<PropName>>(WrappedComponent: ComponentType<WrappedProps>) => ComponentType<Omit<WrappedProps, PropName>>;
|
|
18
|
+
|
|
19
|
+
export { LegacyGtmApi, LegacyGtmProps, WithGtmOptions, withGtm };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Component } from 'react';
|
|
2
|
+
import { createGtmClient } from '@jwiedeman/gtm-kit';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var m=o=>({client:o,push:t=>o.push(t),setConsentDefaults:(t,e)=>o.setConsentDefaults(t,e),updateConsent:(t,e)=>o.updateConsent(t,e)}),c=o=>{let{config:t,propName:e}=o,i=e!=null?e:"gtm";return function(n){class s extends Component{constructor(p){super(p);this.client=createGtmClient(t),this.api=m(this.client);}componentDidMount(){this.client.init();}componentWillUnmount(){this.client.teardown();}render(){let p={[i]:this.api};return jsx(n,{...this.props,...p})}}return s.displayName=`withGtm(${n.displayName||n.name||"Component"})`,s}};
|
|
6
|
+
|
|
7
|
+
export { c as withGtm };
|
|
8
|
+
//# sourceMappingURL=out.js.map
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-gtm.tsx"],"names":["Component","createGtmClient","jsx","createLegacyApi","client","value","state","options","withGtm","config","propName","resolvedPropName","WrappedComponent","WithGtmComponent","props","injectedProps"],"mappings":"AAAA,OAAS,aAAAA,MAAqD,QAC9D,OACE,mBAAAC,MAMK,qBA6DQ,cAAAC,MAAA,oBA3Cf,IAAMC,EAAmBC,IAAqC,CAC5D,OAAAA,EACA,KAAOC,GAAUD,EAAO,KAAKC,CAAK,EAClC,mBAAoB,CAACC,EAAOC,IAAYH,EAAO,mBAAmBE,EAAOC,CAAO,EAChF,cAAe,CAACD,EAAOC,IAAYH,EAAO,cAAcE,EAAOC,CAAO,CACxE,GAEaC,EAA4CD,GAAsC,CAC7F,GAAM,CAAE,OAAAE,EAAQ,SAAAC,CAAS,EAAIH,EACvBI,EAAoBD,GAAA,KAAAA,EAAY,MAItC,OAAO,SACLE,EAC6C,CAG7C,MAAMC,UAAyBb,CAAsB,CAMnD,YAAYc,EAAmB,CAC7B,MAAMA,CAAK,EACX,KAAK,OAASb,EAAgBQ,CAAM,EACpC,KAAK,IAAMN,EAAgB,KAAK,MAAM,CACxC,CAEA,mBAA0B,CACxB,KAAK,OAAO,KAAK,CACnB,CAEA,sBAA6B,CAC3B,KAAK,OAAO,SAAS,CACvB,CAEA,QAAoB,CAClB,IAAMY,EAAgB,CACpB,CAACJ,CAAgB,EAAG,KAAK,GAC3B,EAEA,OAAOT,EAACU,EAAA,CAAkB,GAAI,KAAK,MAAyB,GAAGG,EAAe,CAChF,CACF,CAEA,OAAAF,EAAiB,YAAc,WAAWD,EAAiB,aAAeA,EAAiB,MAAQ,WAAW,IAEvGC,CACT,CACF","sourcesContent":["import { Component, type ComponentType, type ReactNode } from 'react';\nimport {\n createGtmClient,\n type ConsentRegionOptions,\n type ConsentState,\n type CreateGtmClientOptions,\n type DataLayerValue,\n type GtmClient\n} from '@jwiedeman/gtm-kit';\n\nexport interface LegacyGtmApi {\n client: GtmClient;\n push: (value: DataLayerValue) => void;\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n}\n\nexport interface WithGtmOptions<PropName extends string = 'gtm'> {\n config: CreateGtmClientOptions;\n propName?: PropName;\n}\n\nexport type LegacyGtmProps<PropName extends string = 'gtm'> = {\n [Key in PropName]: LegacyGtmApi;\n};\n\nconst createLegacyApi = (client: GtmClient): LegacyGtmApi => ({\n client,\n push: (value) => client.push(value),\n setConsentDefaults: (state, options) => client.setConsentDefaults(state, options),\n updateConsent: (state, options) => client.updateConsent(state, options)\n});\n\nexport const withGtm = <PropName extends string = 'gtm'>(options: WithGtmOptions<PropName>) => {\n const { config, propName } = options;\n const resolvedPropName = (propName ?? 'gtm') as PropName;\n\n type InjectedProps = LegacyGtmProps<PropName>;\n\n return function wrapWithGtm<WrappedProps extends InjectedProps>(\n WrappedComponent: ComponentType<WrappedProps>\n ): ComponentType<Omit<WrappedProps, PropName>> {\n type OuterProps = Omit<WrappedProps, PropName>;\n\n class WithGtmComponent extends Component<OuterProps> {\n static displayName: string;\n\n private client: GtmClient;\n private api: LegacyGtmApi;\n\n constructor(props: OuterProps) {\n super(props);\n this.client = createGtmClient(config);\n this.api = createLegacyApi(this.client);\n }\n\n componentDidMount(): void {\n this.client.init();\n }\n\n componentWillUnmount(): void {\n this.client.teardown();\n }\n\n render(): ReactNode {\n const injectedProps = {\n [resolvedPropName]: this.api\n } as InjectedProps;\n\n return <WrappedComponent {...(this.props as WrappedProps)} {...injectedProps} />;\n }\n }\n\n WithGtmComponent.displayName = `withGtm(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n\n return WithGtmComponent;\n };\n};\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jwiedeman/gtm-kit-react-legacy",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Legacy React HOC adapter for GTM Kit - Google Tag Manager integration.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/jwiedeman/GTM-Kit.git",
|
|
8
|
+
"directory": "packages/react-legacy"
|
|
9
|
+
},
|
|
10
|
+
"author": "jwiedeman",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"gtm",
|
|
13
|
+
"google-tag-manager",
|
|
14
|
+
"react",
|
|
15
|
+
"hoc"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "dist/index.cjs",
|
|
23
|
+
"module": "dist/index.js",
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"require": "./dist/index.cjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"clean": "rm -rf dist",
|
|
38
|
+
"lint": "eslint --max-warnings=0 \"src/**/*.{ts,tsx}\"",
|
|
39
|
+
"test": "jest --config ./jest.config.cjs --runInBand",
|
|
40
|
+
"typecheck": "tsc --noEmit"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@jwiedeman/gtm-kit": "^1.0.1"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@testing-library/jest-dom": "^6.4.2",
|
|
50
|
+
"@testing-library/react": "^14.2.1",
|
|
51
|
+
"@types/react": "^18.3.0",
|
|
52
|
+
"@types/react-dom": "^18.3.0",
|
|
53
|
+
"react": "^18.3.1",
|
|
54
|
+
"react-dom": "^18.3.1",
|
|
55
|
+
"tslib": "^2.6.2"
|
|
56
|
+
}
|
|
57
|
+
}
|