[dyad] Adding a tracking tab to show tracking tools - wrote 4 file(s)

This commit is contained in:
[dyad]
2026-01-21 08:05:43 +01:00
parent 8c68562830
commit f51d90d9cc
4 changed files with 212 additions and 1 deletions

View File

@@ -32,6 +32,10 @@ export interface DetectedSystem {
name: string; name: string;
} }
export interface DetectedTracker {
name: string;
}
export async function extractMetaData(url: string, keyword?: string) { export async function extractMetaData(url: string, keyword?: string) {
if (!url) { if (!url) {
return { error: "URL is required." }; return { error: "URL is required." };
@@ -229,8 +233,8 @@ export async function extractMetaData(url: string, keyword?: string) {
links.push({ href: absoluteUrl, text, type, rel }); links.push({ href: absoluteUrl, text, type, rel });
}); });
const detectedSystems: DetectedSystem[] = [];
const htmlContent = $.html(); const htmlContent = $.html();
const detectedSystems: DetectedSystem[] = [];
const uniqueSystems = new Set<string>(); const uniqueSystems = new Set<string>();
// WordPress // WordPress
@@ -283,6 +287,70 @@ export async function extractMetaData(url: string, keyword?: string) {
detectedSystems.push({ name: system }); detectedSystems.push({ name: system });
}); });
const detectedTrackers: DetectedTracker[] = [];
const uniqueTrackers = new Set<string>();
// Google Analytics / Tag Manager
if (
htmlContent.includes("googletagmanager.com/gtag/js") ||
htmlContent.includes("google-analytics.com/analytics.js")
) {
uniqueTrackers.add("Google Analytics");
}
if (htmlContent.includes("googletagmanager.com/gtm.js")) {
uniqueTrackers.add("Google Tag Manager");
}
// Facebook Pixel
if (
htmlContent.includes("connect.facebook.net") ||
htmlContent.includes("fbq('init'")
) {
uniqueTrackers.add("Facebook Pixel");
}
// Hotjar
if (
htmlContent.includes("static.hotjar.com") ||
htmlContent.includes("window.hj=window.hj||function()")
) {
uniqueTrackers.add("Hotjar");
}
// HubSpot
if (htmlContent.includes("js.hs-scripts.com")) {
uniqueTrackers.add("HubSpot");
}
// Segment
if (htmlContent.includes("cdn.segment.com")) {
uniqueTrackers.add("Segment");
}
// Mixpanel
if (htmlContent.includes("cdn.mxpnl.com")) {
uniqueTrackers.add("Mixpanel");
}
// Vercel Analytics
if (htmlContent.includes("/_vercel/insights/")) {
uniqueTrackers.add("Vercel Analytics");
}
// Plausible
if (htmlContent.includes("plausible.io/js/")) {
uniqueTrackers.add("Plausible");
}
// Microsoft Clarity
if (htmlContent.includes("clarity.ms/tag/")) {
uniqueTrackers.add("Microsoft Clarity");
}
uniqueTrackers.forEach((tracker) => {
detectedTrackers.push({ name: tracker });
});
return { return {
data: { data: {
title, title,
@@ -300,6 +368,7 @@ export async function extractMetaData(url: string, keyword?: string) {
images: imageAltData.length > 0 ? imageAltData : null, images: imageAltData.length > 0 ? imageAltData : null,
links: links.length > 0 ? links : null, links: links.length > 0 ? links : null,
systems: detectedSystems.length > 0 ? detectedSystems : null, systems: detectedSystems.length > 0 ? detectedSystems : null,
trackers: detectedTrackers.length > 0 ? detectedTrackers : null,
}, },
}; };
} catch (error) { } catch (error) {

View File

@@ -16,6 +16,7 @@ import { AnalysisTab } from "./analysis-tab";
import { SocialTab } from "./social-tab"; import { SocialTab } from "./social-tab";
import { LinksDisplay } from "./links-display"; import { LinksDisplay } from "./links-display";
import { SystemDisplay } from "./system-display"; import { SystemDisplay } from "./system-display";
import { TrackingDisplay } from "./tracking-display";
import type { MetaData } from "@/lib/types"; import type { MetaData } from "@/lib/types";
export function MetaForm() { export function MetaForm() {
@@ -130,6 +131,10 @@ export function MetaForm() {
const systemColor: IndicatorColor = const systemColor: IndicatorColor =
metaData.systems && metaData.systems.length > 0 ? "green" : "gray"; metaData.systems && metaData.systems.length > 0 ? "green" : "gray";
// Tracking Tab
const trackingColor: IndicatorColor =
metaData.trackers && metaData.trackers.length > 0 ? "green" : "gray";
return { return {
analysis: analysisColor, analysis: analysisColor,
headlines: headlinesColor, headlines: headlinesColor,
@@ -139,6 +144,7 @@ export function MetaForm() {
faq: faqColor, faq: faqColor,
schema: schemaColor, schema: schemaColor,
system: systemColor, system: systemColor,
tracking: trackingColor,
}; };
}, [metaData, editableTitle, editableDescription]); }, [metaData, editableTitle, editableDescription]);
@@ -236,6 +242,12 @@ export function MetaForm() {
System System
</TabsTrigger> </TabsTrigger>
)} )}
{metaData.trackers && metaData.trackers.length > 0 && (
<TabsTrigger value="tracking">
{tabColors && <TabIndicator color={tabColors.tracking} />}
Tracking
</TabsTrigger>
)}
{metaData.faq && metaData.faq.length > 0 && ( {metaData.faq && metaData.faq.length > 0 && (
<TabsTrigger value="faq"> <TabsTrigger value="faq">
{tabColors && <TabIndicator color={tabColors.faq} />} {tabColors && <TabIndicator color={tabColors.faq} />}
@@ -331,6 +343,12 @@ export function MetaForm() {
<SystemDisplay systems={metaData.systems} /> <SystemDisplay systems={metaData.systems} />
</TabsContent> </TabsContent>
)} )}
{metaData.trackers && metaData.trackers.length > 0 && (
<TabsContent value="tracking">
<TrackingDisplay trackers={metaData.trackers} />
</TabsContent>
)}
</Tabs> </Tabs>
)} )}
</div> </div>

View File

@@ -0,0 +1,122 @@
"use client";
import type { DetectedTracker } from "@/app/actions";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
BarChart3,
MousePointerClick,
Target,
Users,
Database,
Code,
Eye,
} from "lucide-react";
interface TrackingDisplayProps {
trackers: DetectedTracker[];
}
const trackerInfo: {
[key: string]: { icon: React.ElementType; description: string };
} = {
"Google Analytics": {
icon: BarChart3,
description: "Web analytics service that tracks and reports website traffic.",
},
"Google Tag Manager": {
icon: Code,
description:
"Tag management system to easily deploy and manage marketing tags.",
},
"Facebook Pixel": {
icon: Target,
description:
"Analytics tool to measure the effectiveness of advertising by understanding actions people take on a website.",
},
Hotjar: {
icon: MousePointerClick,
description:
"Behavior analytics tool that reveals the online behavior and voice of users.",
},
HubSpot: {
icon: Users,
description: "Inbound marketing, sales, and service software.",
},
Segment: {
icon: Database,
description:
"Customer data platform that collects, cleans, and controls customer data.",
},
Mixpanel: {
icon: BarChart3,
description:
"Product analytics tool for tracking user interactions with web and mobile applications.",
},
"Vercel Analytics": {
icon: BarChart3,
description: "Privacy-friendly analytics for websites deployed on Vercel.",
},
Plausible: {
icon: BarChart3,
description:
"A simple, lightweight and privacy-friendly web analytics tool.",
},
"Microsoft Clarity": {
icon: Eye,
description:
"A free user behavior analytics tool that helps you understand how users are interacting with your website.",
},
Default: {
icon: Code,
description: "A detected tracking or analytics tool.",
},
};
export function TrackingDisplay({ trackers }: TrackingDisplayProps) {
return (
<Card className="w-full shadow-lg rounded-lg">
<CardHeader>
<CardTitle>Tracking Analysis</CardTitle>
<CardDescription>
Tracking and analytics tools detected on the page.
</CardDescription>
</CardHeader>
<CardContent>
{trackers && trackers.length > 0 ? (
<div className="space-y-4">
{trackers.map((tracker, index) => {
const info = trackerInfo[tracker.name] || trackerInfo["Default"];
const Icon = info.icon;
return (
<div
key={index}
className="flex items-start gap-4 p-4 border rounded-lg bg-muted/50"
>
<div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground">
<Icon className="h-6 w-6" />
</div>
<div>
<h4 className="font-semibold text-lg">{tracker.name}</h4>
<p className="text-sm text-muted-foreground">
{info.description}
</p>
</div>
</div>
);
})}
</div>
) : (
<div className="text-center py-8 text-muted-foreground">
<p>No specific tracking tools detected.</p>
</div>
)}
</CardContent>
</Card>
);
}

View File

@@ -3,6 +3,7 @@ import type {
ImageAltData, ImageAltData,
LinkData, LinkData,
DetectedSystem, DetectedSystem,
DetectedTracker,
} from "@/app/actions"; } from "@/app/actions";
export interface OpenGraphData { export interface OpenGraphData {
@@ -39,4 +40,5 @@ export interface MetaData {
twitter?: TwitterData; twitter?: TwitterData;
links?: LinkData[] | null; links?: LinkData[] | null;
systems?: DetectedSystem[] | null; systems?: DetectedSystem[] | null;
trackers?: DetectedTracker[] | null;
} }