Skip to content

feat: integrate @vercel/analytics for enhanced tracking and analytics#57

Open
ej020586 wants to merge 1 commit into
mainfrom
feat/web-spec-0.2.0
Open

feat: integrate @vercel/analytics for enhanced tracking and analytics#57
ej020586 wants to merge 1 commit into
mainfrom
feat/web-spec-0.2.0

Conversation

@ej020586

Copy link
Copy Markdown
Collaborator

vercel analytics with abstract layer and intent from anyclick-protocol

… capabilities; refactor layout and components for improved structure and UX
@ej020586 ej020586 added the ai label Dec 14, 2025
@vercel

vercel Bot commented Dec 14, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
anyclick-website Ready Ready Preview, Comment Dec 14, 2025 9:39pm

@github-actions

github-actions Bot commented Dec 14, 2025

Copy link
Copy Markdown
Contributor

🗺️ Roadmap Sync Preview

Total items: 22
  - GitHub: 0
  - Plans: 1

Items by era:
  - Short-term: 9
  - Mid-term: 6
  - Later: 7

This is a dry-run preview. Changes will be applied when merged to main.

@greptile-apps

greptile-apps Bot commented Dec 14, 2025

Copy link
Copy Markdown
Contributor

Greptile Overview

Greptile Summary

Integrates Vercel Analytics with a custom extensible tracking abstraction layer and anyclick-protocol intent system for comprehensive homepage analytics.

Key Changes:

  • Built custom tracking infrastructure with provider pattern (supports Vercel, console, and future providers)
  • Implemented engagement tracking hooks (useScrollDepth, useTimeOnPage, useSectionView)
  • Created homepage-specific intent enum following protocol convention (web.<page>.<section>.<action>)
  • Refactored homepage to client component with extensive intent tracking on all interactions
  • Added session management with sessionStorage persistence

Architecture:

  • Singleton tracking manager handles provider registration, event batching, and session lifecycle
  • React hooks provide declarative tracking API with IntersectionObserver for passive events
  • IntentProvider wraps app at root level, registers providers, and manages global engagement metrics

Confidence Score: 4/5

  • This PR is safe to merge with one minor logic issue in hover tracking
  • The implementation is well-architected with comprehensive types, proper cleanup, and good separation of concerns. One logic issue exists in useTrackIntent.trackHover where closure-scoped tracking state could cause duplicate events on re-renders, but this is easily fixable and won't cause runtime errors
  • Review apps/web/src/lib/tracking/hooks/useTrackIntent.ts for the hover tracking closure issue

Important Files Changed

File Analysis

Filename Score Overview
apps/web/src/lib/tracking/manager.ts 5/5 Added tracking manager singleton with provider registration, event batching, and session management
apps/web/src/lib/tracking/types.ts 5/5 Defined comprehensive type system for tracking events, providers, configurations, and engagement data
apps/web/src/lib/tracking/hooks/useTrackIntent.ts 4/5 Added intent tracking hook with click and hover handlers; hover tracking has closure issue with tracked variable
apps/web/src/components/IntentProvider.tsx 5/5 Created context provider for intent tracking with provider registration and engagement metrics
apps/web/src/lib/intents/homepage.ts 5/5 Defined comprehensive homepage intent enum following protocol convention
apps/web/src/components/HomePageClient.tsx 5/5 Refactored homepage into client component with extensive intent tracking on navigation, sections, and interactions

Sequence Diagram

sequenceDiagram
    participant User
    participant HomePage as HomePageClient
    participant IntentProvider
    participant TrackingManager
    participant VercelProvider
    participant Analytics as @vercel/analytics

    User->>HomePage: Page loads
    HomePage->>IntentProvider: Mount
    IntentProvider->>TrackingManager: configure() + registerProvider()
    IntentProvider->>TrackingManager: Register vercelProvider
    IntentProvider->>TrackingManager: Register consoleProvider (dev only)
    
    IntentProvider->>IntentProvider: useScrollDepth()
    IntentProvider->>IntentProvider: useTimeOnPage()
    
    User->>HomePage: Clicks nav link
    HomePage->>TrackingManager: track(NAV_DOCS_CLICK)
    TrackingManager->>VercelProvider: track(event)
    VercelProvider->>Analytics: track("web.homepage.nav.docs.click", properties)
    
    User->>HomePage: Scrolls page
    Note over HomePage: IntersectionObserver detects hero section
    HomePage->>TrackingManager: track(HERO_VIEW)
    TrackingManager->>VercelProvider: track(event)
    VercelProvider->>Analytics: track("web.homepage.hero.view", engagement)
    
    Note over HomePage: Scroll reaches 50%
    HomePage->>TrackingManager: track(SCROLL_DEPTH_50)
    TrackingManager->>VercelProvider: track(event)
    VercelProvider->>Analytics: track("web.homepage.scroll.depth.50", scrollDepth)
    
    User->>HomePage: Hovers feature card
    HomePage->>TrackingManager: track(FEATURES_CARD_HOVER)
    TrackingManager->>VercelProvider: track(event)
    VercelProvider->>Analytics: track("web.homepage.features.card.hover", properties)
    
    User->>HomePage: Page unload
    HomePage->>TrackingManager: flush()
    TrackingManager->>VercelProvider: flush()
Loading

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

25 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +54 to +66
const trackHover = useCallback(
(intent: string, properties?: Record<string, unknown>) => {
let tracked = false;
return () => {
// Only track once per mount
if (!tracked) {
tracked = true;
getTrackingManager().track(intent, { properties });
}
};
},
[]
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: trackHover creates a new closure on every call, each with its own tracked variable. If the same hover handler is created multiple times (e.g., on re-renders), each instance tracks independently, potentially causing duplicate events.

Suggested change
const trackHover = useCallback(
(intent: string, properties?: Record<string, unknown>) => {
let tracked = false;
return () => {
// Only track once per mount
if (!tracked) {
tracked = true;
getTrackingManager().track(intent, { properties });
}
};
},
[]
);
const trackHover = useCallback(
(intent: string, properties?: Record<string, unknown>) => {
const trackedRef = { current: false };
return () => {
// Only track once per handler instance
if (!trackedRef.current) {
trackedRef.current = true;
getTrackingManager().track(intent, { properties });
}
};
},
[]
);
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/lib/tracking/hooks/useTrackIntent.ts
Line: 54:66

Comment:
**logic:** `trackHover` creates a new closure on every call, each with its own `tracked` variable. If the same hover handler is created multiple times (e.g., on re-renders), each instance tracks independently, potentially causing duplicate events.

```suggestion
  const trackHover = useCallback(
    (intent: string, properties?: Record<string, unknown>) => {
      const trackedRef = { current: false };
      return () => {
        // Only track once per handler instance
        if (!trackedRef.current) {
          trackedRef.current = true;
          getTrackingManager().track(intent, { properties });
        }
      };
    },
    []
  );
```

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant