|
1 | | -import Script from 'next/script.js' |
| 1 | +import Script from 'next/script' |
2 | 2 |
|
| 3 | +/** |
| 4 | + * Props for the Umami component. |
| 5 | + */ |
3 | 6 | export interface UmamiProps { |
| 7 | + /** The unique Umami website ID. */ |
4 | 8 | umamiWebsiteId: string |
| 9 | + /** The Umami host URL. */ |
| 10 | + umamiHostUrl?: string |
| 11 | + /** Tag to identify the script. */ |
| 12 | + umamiTag?: string |
| 13 | + /** Enable or disable automatic tracking. Defaults to true. */ |
| 14 | + umamiAutoTrack?: boolean |
| 15 | + /** Exclude URL query parameters from tracking. Defaults to false. */ |
| 16 | + umamiExcludeSearch?: boolean |
| 17 | + /** A comma-separated list of domains to limit tracking to. */ |
| 18 | + umamiDomains?: string |
| 19 | + /** Source URL for the Umami script. Defaults to the official CDN. */ |
5 | 20 | src?: string |
| 21 | + /** Additional data attributes for the script tag. */ |
| 22 | + [key: `data${string}`]: any |
6 | 23 | } |
7 | 24 |
|
8 | | -export const Umami = ({ |
9 | | - umamiWebsiteId, |
10 | | - src = 'https://analytics.umami.is/script.js', |
11 | | -}: UmamiProps) => { |
12 | | - return ( |
13 | | - <Script |
14 | | - async |
15 | | - defer |
16 | | - data-website-id={umamiWebsiteId} |
17 | | - src={src} // Replace with your umami instance |
18 | | - /> |
19 | | - ) |
| 25 | +const propToDataAttributeMap: { [key: string]: string } = { |
| 26 | + umamiWebsiteId: 'data-website-id', |
| 27 | + umamiHostUrl: 'data-host-url', |
| 28 | + umamiTag: 'data-tag', |
| 29 | + umamiAutoTrack: 'data-auto-track', |
| 30 | + umamiExcludeSearch: 'data-exclude-search', |
| 31 | + umamiDomains: 'data-domains', |
| 32 | +} |
| 33 | + |
| 34 | +/** |
| 35 | + * A React component that integrates Umami analytics via a script tag. |
| 36 | + * |
| 37 | + * @param props - The props for the Umami component. |
| 38 | + * @returns A Script element with the Umami analytics script and dynamic data attributes. |
| 39 | + */ |
| 40 | +export const Umami = ({ src = 'https://analytics.umami.is/script.js', ...props }: UmamiProps) => { |
| 41 | + const dataAttributes: Record<string, any> = {} |
| 42 | + |
| 43 | + // Map known Umami props to data attributes |
| 44 | + Object.entries(propToDataAttributeMap).forEach(([propName, dataAttrName]) => { |
| 45 | + const value = props[propName as keyof UmamiProps] |
| 46 | + if (value !== undefined) { |
| 47 | + dataAttributes[dataAttrName] = typeof value === 'boolean' ? String(value) : value |
| 48 | + } |
| 49 | + }) |
| 50 | + |
| 51 | + // Include additional data attributes passed via props |
| 52 | + Object.entries(props).forEach(([key, value]) => { |
| 53 | + if (key.startsWith('data') && value !== undefined && !(key in propToDataAttributeMap)) { |
| 54 | + // Convert camelCase to kebab-case for HTML attributes |
| 55 | + const attributeName = key.replace(/([A-Z])/g, '-$1').toLowerCase() |
| 56 | + dataAttributes[attributeName] = value |
| 57 | + } |
| 58 | + }) |
| 59 | + |
| 60 | + return <Script async defer src={src} {...dataAttributes} /> |
20 | 61 | } |
0 commit comments