@dub/analytics
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -8,6 +8,2 @@ type AllowedPropertyValues = string | number | boolean | null; | ||
type TrackEventProperties = Record<string, AllowedPropertyValues>; | ||
type SaleEventProperties = TrackEventProperties & { | ||
value: number; | ||
currency: string; | ||
}; | ||
declare global { | ||
@@ -25,23 +21,8 @@ interface Window { | ||
*/ | ||
declare function inject(props?: AnalyticsProps): void; | ||
/** | ||
* Tracks a click event. | ||
* @param [properties] - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
*/ | ||
declare function trackClick(url: string): void; | ||
declare const track: { | ||
click: typeof trackClick; | ||
lead: (properties: TrackEventProperties) => void; | ||
sale: (properties: SaleEventProperties) => void; | ||
}; | ||
declare function inject(): void; | ||
declare const _default: { | ||
inject: typeof inject; | ||
track: { | ||
click: typeof trackClick; | ||
lead: (properties: TrackEventProperties) => void; | ||
sale: (properties: SaleEventProperties) => void; | ||
}; | ||
}; | ||
export { AnalyticsProps, _default as default, inject, track }; | ||
export { AnalyticsProps, _default as default, inject }; |
// package.json | ||
var version = "0.0.4"; | ||
var version = "0.0.5"; | ||
// src/utils.tsx | ||
function getScriptSrc() { | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_SCRIPT_SRC || process.env.DUB_ANALYTICS_SCRIPT_SRC || "https://dubcdn.com/analytics/dubScript.js"; | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_SCRIPT_SRC || process.env.DUB_ANALYTICS_SCRIPT_SRC || "https://dubcdn.com/analytics/script.js"; | ||
} | ||
function getTrackEndpoint() { | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_TRACK_ENDPOINT || process.env.DUB_ANALYTICS_TRACK_ENDPOINT || "https://api.dub.co/track"; | ||
} | ||
function isBrowser() { | ||
return typeof window !== "undefined"; | ||
} | ||
function detectEnvironment() { | ||
try { | ||
const env = process.env.NODE_ENV; | ||
if (env === "development" || env === "test") { | ||
return "development"; | ||
} | ||
} catch (e) { | ||
} | ||
return "production"; | ||
} | ||
function isProduction() { | ||
return detectEnvironment() === "production"; | ||
} | ||
function removeKey(key, { [key]: _, ...rest }) { | ||
return rest; | ||
} | ||
function parseProperties(properties, options) { | ||
if (!properties) | ||
return void 0; | ||
let props = properties; | ||
const errorProperties = []; | ||
for (const [key, value] of Object.entries(properties)) { | ||
if (typeof value === "object" && value !== null) { | ||
if (options.strip) { | ||
props = removeKey(key, props); | ||
} else { | ||
errorProperties.push(key); | ||
} | ||
} | ||
} | ||
if (errorProperties.length > 0 && !options.strip) { | ||
throw Error( | ||
`The following properties are not valid: ${errorProperties.join( | ||
", " | ||
)}. Only strings, numbers, booleans, and null are allowed.` | ||
); | ||
} | ||
return props; | ||
} | ||
// src/generic.ts | ||
function inject(props = {}) { | ||
function inject() { | ||
if (!isBrowser()) | ||
return; | ||
const apiKey = props.apiKey || process.env.NEXT_PUBLIC_DUB_ANALYTICS_API_KEY || process.env.DUB_ANALYTICS_API_KEY; | ||
if (!apiKey) { | ||
throw new Error("[Dub Web Analytics] Please provide an API key to use."); | ||
} | ||
const src = getScriptSrc(); | ||
const trackEndpoint = props.trackEndpoint || getTrackEndpoint(); | ||
if (document.head.querySelector(`script[src*="${src}"]`)) | ||
@@ -70,7 +23,2 @@ return; | ||
script.setAttribute("data-sdkv", version); | ||
script.setAttribute("data-api-key", apiKey); | ||
script.setAttribute("data-track-endpoint", trackEndpoint); | ||
if (props.affiliateParamKey) { | ||
script.setAttribute("data-affiliate-param-key", props.affiliateParamKey); | ||
} | ||
script.onerror = () => { | ||
@@ -81,55 +29,9 @@ console.log(`[Dub Web Analytics] failed to load script from ${src}.`); | ||
} | ||
function trackClick(url) { | ||
var _a; | ||
if (!isBrowser()) { | ||
const msg = "[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon."; | ||
console.warn(msg); | ||
return; | ||
} | ||
try { | ||
(_a = window.da) == null ? void 0 : _a.trackClick(url); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
function _trackConversion(eventName, properties) { | ||
var _a, _b; | ||
if (!isBrowser()) { | ||
const msg = "[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon."; | ||
console.warn(msg); | ||
return; | ||
} | ||
if (!properties) { | ||
(_a = window.da) == null ? void 0 : _a.trackConversion(eventName, {}); | ||
return; | ||
} | ||
try { | ||
const cleanedProperties = parseProperties(properties, { | ||
strip: isProduction() | ||
}); | ||
(_b = window.da) == null ? void 0 : _b.trackConversion(eventName, cleanedProperties); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
var lead = (properties) => { | ||
_trackConversion("lead", properties); | ||
}; | ||
var sale = (properties) => { | ||
_trackConversion("sale", properties); | ||
}; | ||
var track = { | ||
click: trackClick, | ||
lead, | ||
sale | ||
}; | ||
var generic_default = { | ||
inject, | ||
track | ||
inject | ||
}; | ||
export { | ||
generic_default as default, | ||
inject, | ||
track | ||
inject | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -8,6 +8,2 @@ type AllowedPropertyValues = string | number | boolean | null; | ||
type TrackEventProperties = Record<string, AllowedPropertyValues>; | ||
type SaleEventProperties = TrackEventProperties & { | ||
value: number; | ||
currency: string; | ||
}; | ||
declare global { | ||
@@ -23,18 +19,4 @@ interface Window { | ||
/** | ||
* Tracks a click event. | ||
* @param [properties] - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
*/ | ||
declare function trackClick(url: string): void; | ||
declare const track: { | ||
click: typeof trackClick; | ||
lead: (properties: TrackEventProperties) => void; | ||
sale: (properties: SaleEventProperties) => void; | ||
}; | ||
/** | ||
* Injects the Dub Web Analytics script into the page head. | ||
* @param props - Analytics options. | ||
* @param props.apiKey - Your project's API key. If not provided, the API key will be read from the `NEXT_PUBLIC_DUB_ANALYTICS_API_KEY` environment variable. | ||
* @param props.trackEndpoint - The endpoint to send tracking events to. If not provided, the endpoint will be read from the `NEXT_PUBLIC_DUB_ANALYTICS_TRACK_ENDPOINT` environment variable or fall back to the default. | ||
* @param props.affiliateParamKey - The query parameter key to use for affiliate tracking. If not provided, it will default to `via`. | ||
* ```js | ||
@@ -45,12 +27,12 @@ * import { Analytics as DubAnalytics } from '@dub/analytics/react'; | ||
* return ( | ||
* <div> | ||
* <DubAnalytics apiKey={API_KEY} /> | ||
* <h1>My App</h1> | ||
* </div> | ||
* ); | ||
* <div> | ||
* <DubAnalytics /> | ||
* <h1>My App</h1> | ||
* </div> | ||
* ); | ||
* } | ||
* ``` | ||
*/ | ||
declare function Analytics({ apiKey, trackEndpoint, affiliateParamKey, }: AnalyticsProps): null; | ||
declare function Analytics(): null; | ||
export { Analytics, AnalyticsProps, track }; | ||
export { Analytics, AnalyticsProps }; |
@@ -7,64 +7,17 @@ "use client"; | ||
// package.json | ||
var version = "0.0.4"; | ||
var version = "0.0.5"; | ||
// src/utils.tsx | ||
function getScriptSrc() { | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_SCRIPT_SRC || process.env.DUB_ANALYTICS_SCRIPT_SRC || "https://dubcdn.com/analytics/dubScript.js"; | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_SCRIPT_SRC || process.env.DUB_ANALYTICS_SCRIPT_SRC || "https://dubcdn.com/analytics/script.js"; | ||
} | ||
function getTrackEndpoint() { | ||
return process.env.NEXT_PUBLIC_DUB_ANALYTICS_TRACK_ENDPOINT || process.env.DUB_ANALYTICS_TRACK_ENDPOINT || "https://api.dub.co/track"; | ||
} | ||
function isBrowser() { | ||
return typeof window !== "undefined"; | ||
} | ||
function detectEnvironment() { | ||
try { | ||
const env = process.env.NODE_ENV; | ||
if (env === "development" || env === "test") { | ||
return "development"; | ||
} | ||
} catch (e) { | ||
} | ||
return "production"; | ||
} | ||
function isProduction() { | ||
return detectEnvironment() === "production"; | ||
} | ||
function removeKey(key, { [key]: _, ...rest }) { | ||
return rest; | ||
} | ||
function parseProperties(properties, options) { | ||
if (!properties) | ||
return void 0; | ||
let props = properties; | ||
const errorProperties = []; | ||
for (const [key, value] of Object.entries(properties)) { | ||
if (typeof value === "object" && value !== null) { | ||
if (options.strip) { | ||
props = removeKey(key, props); | ||
} else { | ||
errorProperties.push(key); | ||
} | ||
} | ||
} | ||
if (errorProperties.length > 0 && !options.strip) { | ||
throw Error( | ||
`The following properties are not valid: ${errorProperties.join( | ||
", " | ||
)}. Only strings, numbers, booleans, and null are allowed.` | ||
); | ||
} | ||
return props; | ||
} | ||
// src/generic.ts | ||
function inject(props = {}) { | ||
function inject() { | ||
if (!isBrowser()) | ||
return; | ||
const apiKey = props.apiKey || process.env.NEXT_PUBLIC_DUB_ANALYTICS_API_KEY || process.env.DUB_ANALYTICS_API_KEY; | ||
if (!apiKey) { | ||
throw new Error("[Dub Web Analytics] Please provide an API key to use."); | ||
} | ||
const src = getScriptSrc(); | ||
const trackEndpoint = props.trackEndpoint || getTrackEndpoint(); | ||
if (document.head.querySelector(`script[src*="${src}"]`)) | ||
@@ -76,7 +29,2 @@ return; | ||
script.setAttribute("data-sdkv", version); | ||
script.setAttribute("data-api-key", apiKey); | ||
script.setAttribute("data-track-endpoint", trackEndpoint); | ||
if (props.affiliateParamKey) { | ||
script.setAttribute("data-affiliate-param-key", props.affiliateParamKey); | ||
} | ||
script.onerror = () => { | ||
@@ -87,62 +35,13 @@ console.log(`[Dub Web Analytics] failed to load script from ${src}.`); | ||
} | ||
function trackClick(url) { | ||
var _a; | ||
if (!isBrowser()) { | ||
const msg = "[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon."; | ||
console.warn(msg); | ||
return; | ||
} | ||
try { | ||
(_a = window.da) == null ? void 0 : _a.trackClick(url); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
function _trackConversion(eventName, properties) { | ||
var _a, _b; | ||
if (!isBrowser()) { | ||
const msg = "[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon."; | ||
console.warn(msg); | ||
return; | ||
} | ||
if (!properties) { | ||
(_a = window.da) == null ? void 0 : _a.trackConversion(eventName, {}); | ||
return; | ||
} | ||
try { | ||
const cleanedProperties = parseProperties(properties, { | ||
strip: isProduction() | ||
}); | ||
(_b = window.da) == null ? void 0 : _b.trackConversion(eventName, cleanedProperties); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
var lead = (properties) => { | ||
_trackConversion("lead", properties); | ||
}; | ||
var sale = (properties) => { | ||
_trackConversion("sale", properties); | ||
}; | ||
var track = { | ||
click: trackClick, | ||
lead, | ||
sale | ||
}; | ||
// src/react.tsx | ||
function Analytics({ | ||
apiKey, | ||
trackEndpoint, | ||
affiliateParamKey | ||
}) { | ||
function Analytics() { | ||
useEffect(() => { | ||
inject({ apiKey, trackEndpoint, affiliateParamKey }); | ||
}, [apiKey, trackEndpoint, affiliateParamKey]); | ||
inject(); | ||
}, []); | ||
return null; | ||
} | ||
export { | ||
Analytics, | ||
track | ||
Analytics | ||
}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@dub/analytics", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "", | ||
@@ -26,9 +26,2 @@ "keywords": [ | ||
"require": "./dist/react/index.cjs" | ||
}, | ||
"./server": { | ||
"node": "./dist/server/index.js", | ||
"edge-light": "./dist/server/index.js", | ||
"import": "./dist/server/index.js", | ||
"require": "./dist/server/index.cjs", | ||
"default": "./dist/server/index.cjs" | ||
} | ||
@@ -45,5 +38,2 @@ }, | ||
"dist/react/index.d.ts" | ||
], | ||
"server": [ | ||
"dist/server/index.d.ts" | ||
] | ||
@@ -50,0 +40,0 @@ } |
@@ -24,3 +24,3 @@ <div align="center"><strong>Dub Web Analytics</strong></div> | ||
<body>{children}</body> | ||
<DubAnalytics apiKey="apiKey" /> | ||
<DubAnalytics /> | ||
</html> | ||
@@ -30,34 +30,2 @@ ); | ||
``` | ||
You can all use the `inject({ apiKey })` function to add the tracking script to other frameworks. | ||
5. Use the `sale` and `lead` functions to track conversions. | ||
Client side: | ||
```tsx | ||
import { track } from '@dub/analytics'; | ||
export const LeadButton = () => ( | ||
<button onClick={() => track.lead({ property: 'value' })}> | ||
Track Lead | ||
</button> | ||
); | ||
export const SaleButton = () => ( | ||
<button onClick={() => track.sale({ value: 100, currency: 'USD' })}> | ||
Track Sale | ||
</button> | ||
); | ||
``` | ||
Server side: | ||
```ts | ||
import { track } from '@dub/analytics/server'; | ||
export async function GET(request: Request) { | ||
track.lead(request, 'apiKey', { property: 'value' }); | ||
return Response.json({ message: 'Event tracked' }); | ||
} | ||
``` | ||
Note: the SKD also has automatic tracking of "clicks" for affiliate attribution when the via query parameter is present in the URL. It will automatically track the click, store the affiliate ID in a cookie, and be able to associate future leads and sales with the affiliate. | ||
You can all use the `inject()` function to add the tracking script to other frameworks. |
import { version } from '../package.json'; | ||
import type { | ||
AllowedPropertyValues, | ||
AnalyticsProps, | ||
SaleEventProperties, | ||
TrackEventProperties, | ||
} from './types'; | ||
import { | ||
getScriptSrc, | ||
getTrackEndpoint, | ||
isBrowser, | ||
isProduction, | ||
parseProperties, | ||
} from './utils'; | ||
import type { AnalyticsProps } from './types'; | ||
import { getScriptSrc, isBrowser } from './utils'; | ||
@@ -19,15 +8,6 @@ /** | ||
*/ | ||
function inject(props: AnalyticsProps = {}): void { | ||
function inject(): void { | ||
if (!isBrowser()) return; | ||
const apiKey = | ||
props.apiKey || | ||
process.env.NEXT_PUBLIC_DUB_ANALYTICS_API_KEY || | ||
process.env.DUB_ANALYTICS_API_KEY; | ||
if (!apiKey) { | ||
throw new Error('[Dub Web Analytics] Please provide an API key to use.'); | ||
} | ||
const src = getScriptSrc(); | ||
const trackEndpoint = props.trackEndpoint || getTrackEndpoint(); | ||
@@ -40,7 +20,2 @@ if (document.head.querySelector(`script[src*="${src}"]`)) return; | ||
script.setAttribute('data-sdkv', version); | ||
script.setAttribute('data-api-key', apiKey); | ||
script.setAttribute('data-track-endpoint', trackEndpoint); | ||
if (props.affiliateParamKey) { | ||
script.setAttribute('data-affiliate-param-key', props.affiliateParamKey); | ||
} | ||
@@ -55,100 +30,3 @@ script.onerror = (): void => { | ||
/** | ||
* Tracks a click event. | ||
* @param [properties] - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
*/ | ||
function trackClick(url: string): void { | ||
if (!isBrowser()) { | ||
const msg = | ||
'[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon.'; | ||
// eslint-disable-next-line no-console -- Logging to console is intentional | ||
console.warn(msg); | ||
return; | ||
} | ||
try { | ||
window.da?.trackClick(url); | ||
} catch (err) { | ||
// eslint-disable-next-line no-console -- Logging to console is intentional | ||
console.error(err); | ||
} | ||
} | ||
/** | ||
* Tracks a conversion event. | ||
* @param eventName - The name of the event. | ||
* @param [properties] - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
*/ | ||
function _trackConversion( | ||
eventName: string, | ||
properties?: Record<string, AllowedPropertyValues>, | ||
): void { | ||
if (!isBrowser()) { | ||
const msg = | ||
'[Dub Web Analytics] is currently only supported in the browser environment. The server tracking is coming soon.'; | ||
// eslint-disable-next-line no-console -- Logging to console is intentional | ||
console.warn(msg); | ||
return; | ||
} | ||
if (!properties) { | ||
window.da?.trackConversion(eventName, {}); | ||
return; | ||
} | ||
try { | ||
const cleanedProperties = parseProperties(properties, { | ||
strip: isProduction(), | ||
}); | ||
window.da?.trackConversion(eventName, cleanedProperties); | ||
} catch (err) { | ||
// eslint-disable-next-line no-console -- Logging to console is intentional | ||
console.error(err); | ||
} | ||
} | ||
/** | ||
* Tracks a lead event. | ||
* @param properties - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
* | ||
* @example | ||
* ```ts | ||
* import { track } from '@dub/analytics'; | ||
* | ||
* track.lead({ | ||
* cta: 'Sign Up', | ||
* }); | ||
* ``` | ||
*/ | ||
const lead = (properties: TrackEventProperties): void => { | ||
_trackConversion('lead', properties); | ||
}; | ||
/** | ||
* Tracks a sale event. | ||
* @param properties - Additional properties of the event. Nested objects are not supported. Allowed values are `string`, `number`, `boolean`, and `null`. | ||
* @param properties.value - The value of the sale in cents. | ||
* @param properties.currency - The currency of the sale. | ||
* @example | ||
* ```ts | ||
* import { track } from '@dub/analytics'; | ||
* | ||
* track.sale({ | ||
* value: 1000, // $10.00 | ||
* currency: 'USD', | ||
* }); | ||
* ``` | ||
*/ | ||
const sale = (properties: SaleEventProperties): void => { | ||
_trackConversion('sale', properties); | ||
}; | ||
const track = { | ||
click: trackClick, | ||
lead, | ||
sale, | ||
}; | ||
export { inject, track }; | ||
export { inject }; | ||
export type { AnalyticsProps }; | ||
@@ -159,3 +37,2 @@ | ||
inject, | ||
track, | ||
}; |
@@ -34,9 +34,2 @@ import { defineConfig } from 'tsup'; | ||
}, | ||
{ | ||
...cfg, | ||
entry: { | ||
index: 'src/server.ts', | ||
}, | ||
outDir: 'dist/server', | ||
}, | ||
]); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
5
1
41520
20
457
30