Skip to content

Commit 3a5d28d

Browse files
committed
fix : script colors
1 parent 70b9502 commit 3a5d28d

File tree

9 files changed

+644
-294
lines changed

9 files changed

+644
-294
lines changed

apps/dashboard/app/(main)/websites/[id]/_components/tabs/settings-tab.tsx

Lines changed: 167 additions & 114 deletions
Large diffs are not rendered by default.

apps/dashboard/app/(main)/websites/[id]/_components/tabs/tracking-setup-tab.tsx

Lines changed: 339 additions & 174 deletions
Large diffs are not rendered by default.

apps/dashboard/app/(main)/websites/[id]/_components/utils/code-generators.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,49 @@ export function generateNpmComponentCode(
124124
return `<Databuddy
125125
clientId="${websiteId}"${propsString}/>`;
126126
}
127+
128+
/**
129+
* Generate NPM code for Vercel integration (auto-detects clientId)
130+
*/
131+
export function generateVercelNpmCode(
132+
trackingOptions: TrackingOptions
133+
): string {
134+
const meaningfulProps = Object.entries(trackingOptions)
135+
.filter(([key, value]) => {
136+
const actualDefault =
137+
ACTUAL_LIBRARY_DEFAULTS[key as keyof TrackingOptions];
138+
if (value === actualDefault) {
139+
return false;
140+
}
141+
if (typeof value === 'boolean' && !value && !actualDefault) {
142+
return false;
143+
}
144+
return true;
145+
})
146+
.map(([key, value]) => {
147+
if (typeof value === 'boolean') {
148+
return ` ${key}={${value}}`;
149+
}
150+
if (typeof value === 'string') {
151+
return ` ${key}="${value}"`;
152+
}
153+
return ` ${key}={${value}}`;
154+
});
155+
156+
const propsString =
157+
meaningfulProps.length > 0 ? `\n${meaningfulProps.join('\n')}\n ` : '';
158+
159+
return `import { Databuddy } from '@databuddy/sdk/react';
160+
161+
export default function RootLayout({ children }) {
162+
return (
163+
<html>
164+
<head>
165+
{/* No clientId needed - auto-detected from env vars */}
166+
<Databuddy${propsString}/>
167+
</head>
168+
<body>{children}</body>
169+
</html>
170+
);
171+
}`;
172+
}

packages/rpc/src/routers/websites.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,35 @@ export const websitesRouter = createTRPCRouter({
412412
isTrackingSetup: publicProcedure
413413
.input(z.object({ websiteId: z.string() }))
414414
.query(async ({ ctx, input }) => {
415-
await authorizeWebsiteAccess(ctx, input.websiteId, 'read');
415+
const website = await authorizeWebsiteAccess(
416+
ctx,
417+
input.websiteId,
418+
'read'
419+
);
420+
421+
// Check if website has Vercel integration (has NEXT_PUBLIC_DATABUDDY_CLIENT_ID env var)
422+
const hasVercelIntegration = !!(website.integrations as any)?.vercel
423+
?.environments;
424+
425+
// Always check for actual tracking events
416426
const trackingCheckResult = await chQuery<{ count: number }>(
417427
`SELECT COUNT(*) as count FROM analytics.events WHERE client_id = {websiteId:String} AND event_name = 'screen_view' LIMIT 1`,
418428
{ websiteId: input.websiteId }
419429
);
420-
return { tracking_setup: (trackingCheckResult[0]?.count ?? 0) > 0 };
430+
431+
const hasTrackingEvents = (trackingCheckResult[0]?.count ?? 0) > 0;
432+
433+
// Determine integration type
434+
let integrationType: 'vercel' | 'manual' | null = null;
435+
if (hasVercelIntegration) {
436+
integrationType = 'vercel';
437+
} else if (hasTrackingEvents) {
438+
integrationType = 'manual';
439+
}
440+
441+
return {
442+
tracking_setup: hasTrackingEvents,
443+
integration_type: integrationType,
444+
};
421445
}),
422446
});

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@databuddy/sdk",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"description": "Official Databuddy Analytics SDK",
55
"main": "./dist/core/index.mjs",
66
"types": "./dist/core/index.d.ts",

packages/sdk/src/core/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { detectClientId } from '../utils';
12
export * from './script';
23
export * from './tracker';
34
export * from './types';

packages/sdk/src/core/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
*/
55
export interface DatabuddyConfig {
66
/**
7-
* Your Databuddy project client ID (required).
7+
* Your Databuddy project client ID.
8+
* If not provided, will automatically detect from NEXT_PUBLIC_DATABUDDY_CLIENT_ID environment variable.
89
* Get this from your Databuddy dashboard.
910
* Example: '3ed1fce1-5a56-4cbc-a917-66864f6d18e3'
1011
*/
11-
clientId: string;
12+
clientId?: string;
1213

1314
/**
1415
* (Advanced) Your Databuddy client secret for server-side operations.

packages/sdk/src/react/Databuddy.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
import { createScript, isScriptInjected } from '../core/script';
22
import type { DatabuddyConfig } from '../core/types';
3+
import { detectClientId } from '../utils';
34

45
/**
56
* <Databuddy /> component for Next.js/React apps
67
* Injects the databuddy.js script with all config as data attributes
78
* Usage: <Databuddy clientId="..." trackScreenViews trackPerformance ... />
9+
* Or simply: <Databuddy /> (auto-detects clientId from environment variables)
810
*/
911
export function Databuddy(props: DatabuddyConfig) {
12+
const clientId = detectClientId(props.clientId);
13+
14+
// Don't inject if no client ID is available
15+
if (!clientId) {
16+
if (typeof window !== 'undefined' && !props.disabled) {
17+
console.warn(
18+
'Databuddy: No client ID found. Please provide clientId prop or set NEXT_PUBLIC_DATABUDDY_CLIENT_ID environment variable.'
19+
);
20+
}
21+
return null;
22+
}
23+
1024
// Only inject script on client-side and if not already injected
1125
if (typeof window !== 'undefined' && !props.disabled && !isScriptInjected()) {
12-
const script = createScript(props);
26+
const script = createScript({ ...props, clientId });
1327
document.head.appendChild(script);
1428
}
1529

packages/sdk/src/utils.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,49 @@ export type IsOptional<T> = IsAny<T> extends true
44
: Extract<T, undefined> extends never
55
? false
66
: true;
7+
8+
/**
9+
* Auto-detect Databuddy client ID from environment variables
10+
* Supports Next.js, Nuxt, and other frameworks
11+
*/
12+
export function detectClientId(providedClientId?: string): string | undefined {
13+
if (providedClientId) {
14+
return providedClientId;
15+
}
16+
17+
// Try to get from environment variables
18+
if (typeof process !== 'undefined' && process.env) {
19+
return (
20+
process.env.NEXT_PUBLIC_DATABUDDY_CLIENT_ID ||
21+
process.env.NUXT_PUBLIC_DATABUDDY_CLIENT_ID ||
22+
process.env.VITE_DATABUDDY_CLIENT_ID ||
23+
process.env.REACT_APP_DATABUDDY_CLIENT_ID
24+
);
25+
}
26+
27+
// Fallback for browser environments where process.env might not be available
28+
if (typeof window !== 'undefined') {
29+
// Next.js runtime config
30+
// @ts-expect-error - This might be injected by build tools
31+
const nextEnv = window.__NEXT_DATA__?.env?.NEXT_PUBLIC_DATABUDDY_CLIENT_ID;
32+
if (nextEnv) {
33+
return nextEnv;
34+
}
35+
36+
// Nuxt runtime config
37+
// @ts-expect-error - This might be injected by build tools
38+
const nuxtEnv = window.__NUXT__?.env?.NUXT_PUBLIC_DATABUDDY_CLIENT_ID;
39+
if (nuxtEnv) {
40+
return nuxtEnv;
41+
}
42+
43+
// Vite/other build tools might inject env vars differently
44+
// @ts-expect-error - This might be injected by build tools
45+
const viteEnv = window.__VITE_ENV__?.VITE_DATABUDDY_CLIENT_ID;
46+
if (viteEnv) {
47+
return viteEnv;
48+
}
49+
}
50+
51+
return;
52+
}

0 commit comments

Comments
 (0)