Skip to content

Conversation

@Dprof-in-tech
Copy link
Collaborator

@Dprof-in-tech Dprof-in-tech commented Dec 18, 2025

Description

This pull request removes server-side analytics and event tracking endpoints, along with related error handling and environment configuration. It also includes minor UI and code style improvements. The most significant changes are grouped below:

Analytics and Tracking Removal:

  • Deleted the server-side analytics endpoints by removing the files app/api/v1/analytics/identify/route.ts and app/api/v1/analytics/track/route.ts, which handled user identification and event tracking, respectively. [1] [2]
  • Removed Sentry-related environment variables from .env.example and deleted the global error handler app/global-error.tsx that reported errors to Sentry. [1] [2]
  • Updated the logout tracking API (app/api/track-logout/route.ts) to remove the call to identifyServerUser, so user identification is no longer updated on logout. [1] [2]

Build and CI Configuration:

  • Removed the Node.js CI workflow file .github/workflows/node.js.yml, which previously handled automated testing and builds.

UI and Code Style Adjustments:

  • Fixed image dimensions in the TransferForm component to use 50x50 instead of 500x500 for recipient network images.
  • Minor code formatting and style improvements in Navbar.tsx, including className formatting and event tracking parameter style. [1] [2]

References

DUE TO THE CHANGES BEING REVERTED, WE HAVE BEEN UNABLE TO RELEASE A NE DEPLOYMENT OF THIS APP DUE TO IT RUNNING OUT OF MEMORY IN THE BUILD PROCESS. FOR THAT REASON, I AM REVERTIGN THESE CHANGES TO BE RECONSIDERED FOR A LIGHTWIGHT ALTERNATIVE TO THE SENTRY OBSERVABILITY SUITE.

WE TRIED THIS DEPLOYMENT AFTER ERROR FIXES ON A 1GB RAM AND 4GB RAM INSTANCE SIZE, BOTH FAILED.

Testing

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation and tests for new/changed functionality in this PR
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not main

By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.

Summary by CodeRabbit

  • New Features

    • Client-side analytics now initialize only with explicit user consent.
  • Style

    • Reduced recipient network avatar size for improved layout.
  • Chores

    • Removed Sentry/error-monitoring integration and simplified analytics infrastructure (server-side tracking routes and instrumentation removed).
  • Bug Fixes

    • Simplified analytics payloads to omit certain identifying fields and streamline events.

✏️ Tip: You can customize this high-level summary in your review settings.

sundayonah and others added 8 commits December 17, 2025 21:43
* feat: complete glitchtip integration with sentry wizard

* fix: add glitchtip url to env

* fix: resolve CodeRabbit review – harden PII handling,  env example & beforeSend parsing

* fix: harden beforeSend fallback

* fix: add base64url-safe JWT decoding in beforeSend for reliable Privy session extraction

* fix: update glitchtip public-url

* fix: add release to withSentryConfig

* refactor: migrate from GlitchTip to Sentry for error tracking

- Updated environment variables in .env.example to reflect Sentry configuration.
- Refactored Sentry initialization in instrumentation-client.ts, sentry.edge.config.ts, and sentry.server.config.ts to use Sentry DSN and environment variables.
- Adjusted config types and values in app/lib/config.ts to support Sentry integration.
- Updated package dependencies to use the latest version of @sentry/nextjs and related packages.
- Ensured proper handling of PII and traces sample rate based on the environment.
* feat: enhance user tracking with server-side event logging

- Added server-side user identification and event tracking in various components including Navbar, TransactionPreview, and TransactionStatus.
- Implemented `identifyServerUser` and `trackServerEvent` functions to log user actions such as login, logout, funding, and transaction events.
- Updated `trackUserEvent` helper function to streamline user identification and event tracking.
- Ensured backward compatibility with existing client-side tracking methods.

* feat: enhance analytics tracking with IP and User-Agent logging

- Updated the analytics identify and track routes to include IP address and User-Agent in tracking requests.
- Refactored event tracking functions to utilize common properties for improved consistency and clarity.
- Ensured that sensitive data is sanitized before being sent to analytics services for geo-inference and device detection.

* refactor: streamline server event tracking and IP inclusion logic

- Removed redundant trackServerEvent call in analytics tracking.
- Updated trackServerEvent invocation to standardize the event name format.
- Enhanced IP address inclusion logic to respect privacy settings, ensuring compliance with user privacy preferences.

* refactor: remove trackUserEvent function

* refactor: improve wallet address handling and event tracking logic

- Updated wallet address retrieval to use undefined instead of null for better type handling.
- Streamlined event tracking by ensuring wallet address is only included when present, allowing for generic event tracking when absent.
- Enhanced the handling of transaction, funding, and authentication events to ensure they are tracked appropriately based on wallet address availability.
- Removed redundant server-side tracking calls in favor of a more consistent client-side approach.

* refactor: remove wallet address retrieval for server-side tracking

* refactor: standardize properties handling in event tracking functions

- Updated event tracking functions to use default empty object for properties parameter, improving consistency and reducing the need for undefined checks.
- This change applies to multiple tracking functions including trackPageView, trackBlogCardClick, and trackSearch.

* Update app/hooks/analytics/useMixpanel.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Chibuotu Amadi <chibuotu@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Removed unused import of config and replaced it with environment variables for Sentry URL and auth token.
- Standardized formatting in serverExternalPackages and webpack configuration for consistency.
- Ensured proper structure in the rules section of the webpack configuration.
- Minor adjustments to maintain code clarity and organization.
…fig.mjs

- Introduced a new configuration option to disable source map uploads in low-memory environments.
- Added a script in package.json for building in low-memory mode, setting appropriate Node options.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

Walkthrough

Removes Sentry instrumentation and server-side analytics endpoints, refactors client-side analytics to a consent-driven Mixpanel implementation, removes related dependencies/config, and makes small UI/formatting adjustments across components and pages.

Changes

Cohort / File(s) Summary
Sentry integration removal
\.env\.example, instrumentation-client.ts, instrumentation.ts, next.config.mjs, sentry.edge.config.ts, sentry.server.config.ts
Removes Sentry DSN/env vars, initialization, runtime registration, and Next.js Sentry wrapper/configuration.
Server-side analytics endpoints removed
app/api/v1/analytics/identify/route.ts, app/api/v1/analytics/track/route.ts, app/api/track-logout/route.ts
Deletes server POST handlers for identify/track/logout analytics and removes identifyServerUser/trackServerEvent usage.
Client analytics refactor
app/hooks/analytics/useMixpanel.ts, app/hooks/analytics/useServerTracking.ts
Replaces server-side tracking with client-side, consent-gated Mixpanel flows; removes useServerTracking and updates many tracking helper signatures and behavior.
Server analytics library changes
app/lib/server-analytics.ts, app/lib/server-config.ts
Simplifies sanitization and removes explicit ip/user-agent propagation; narrows Mixpanel server token fallback.
Config & types
app/lib/config.ts, app/types.ts
Removes Sentry-related config fields (sentryDsn, sentryUrl, sentryAuthToken, nodeEnv) from exported config/type surfaces.
Global error boundary & instrumentation UI
app/global-error.tsx, app/components/Navbar.tsx, app/components/TransferForm.tsx
Removes GlobalError component (Sentry capture); minor Navbar formatting; reduces recipient network image size (500×500 → 50×50).
Analytics call adjustments in pages
app/pages/TransactionPreview.tsx, app/pages/TransactionStatus.tsx, app/hooks/useFundWalletHandler.ts
Removes observable fields from swap events (network/token/amount, transaction_status) and a comment-only change near a funding track call.
Build, deps & CI
package.json, .github/workflows/node.js.yml
Removes @sentry/nextjs and other deps; deletes build script override entries; minor CI YAML quote/spacing edits.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus:
    • app/hooks/analytics/useMixpanel.ts — major behavioural refactor, consent logic, changed signatures across many helpers.
    • Removal of server endpoints — verify no client code still calls removed routes.
    • next.config.mjs / instrumentation files — ensure build-time config and exports remain correct after removing Sentry wrapper.
    • app/lib/server-analytics.ts & server-config — check sanitization and token fallback changes for server-side uses (if any remain).

Possibly related PRs

Suggested reviewers

  • chibie
  • sundayonah
  • jeremy0x

Poem

🐰 I hopped through code at break of dawn,

Sentry nets untied and gone.
Mixpanel waits when cookies say yes,
Quiet servers, lighter stress.
🥕 Hooray — a tidy, springtime refress!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main objective: reverting to the last stable commit before Sentry was added, which aligns with the extensive removal of Sentry configuration, error handling, and related analytics infrastructure throughout the changeset.
Description check ✅ Passed The description covers key changes (analytics removal, Sentry cleanup, UI fixes) and provides clear business context (memory exhaustion during deployment). However, it lacks specific testing details and leaves Testing/Checklist sections mostly incomplete, which are required by the template.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch revert-to-last-stable-commit

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29859b5 and a921f7d.

📒 Files selected for processing (1)
  • .github/workflows/node.js.yml (2 hunks)
🔇 Additional comments (1)
.github/workflows/node.js.yml (1)

8-8: Inconsistency: PR objectives state this file should be removed, but it's only been reformatted.

The PR description explicitly states "Removed the Node.js CI workflow file .github/workflows/node.js.yml," but the file is still present with only minor formatting changes (quote style and whitespace). Please clarify whether this workflow file should be deleted entirely as part of the Sentry/analytics revert, or if it should be retained.

Also applies to: 10-10, 33-33


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
app/components/TransferForm.tsx (1)

415-416: Good fix—image dimensions now more appropriate.

Reducing from 500×500 to 50×50 improves performance without affecting the 24×24 display size.

Optional: align with dropdown dimensions for consistency

The dropdown network images (lines 458–464) use width={24} height={24} for the same content type displayed at the same size. Consider using 24 here as well for perfect consistency:

-                height={50}
-                width={50}
+                height={24}
+                width={24}
app/pages/TransactionPreview.tsx (1)

613-615: Minor formatting change - functionally equivalent.

Switching from classNames() utility to template literal for the conditional class is equivalent behavior. Consider using classNames() consistently throughout the file for uniformity, as it's used elsewhere (e.g., line 599-602).

app/lib/server-analytics.ts (1)

197-202: Consider sanitizing user properties for privacy consistency.

The userData is constructed directly from properties without sanitization, unlike trackServerEvent which uses sanitizeProperties(). If properties may contain sensitive fields like wallet_address, they won't be hashed here.

🔎 Proposed fix to sanitize user properties
     const userData = {
-      ...properties,
+      ...sanitizeProperties(properties),
       $last_seen: new Date().toISOString(),
       app: "Noblocks",
       server_side: true,
     };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eae5321 and 29859b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • .env.example (0 hunks)
  • .github/workflows/node.js.yml (0 hunks)
  • app/api/track-logout/route.ts (1 hunks)
  • app/api/v1/analytics/identify/route.ts (0 hunks)
  • app/api/v1/analytics/track/route.ts (0 hunks)
  • app/components/Navbar.tsx (2 hunks)
  • app/components/TransferForm.tsx (1 hunks)
  • app/global-error.tsx (0 hunks)
  • app/hooks/analytics/useMixpanel.ts (11 hunks)
  • app/hooks/analytics/useServerTracking.ts (0 hunks)
  • app/hooks/useFundWalletHandler.ts (0 hunks)
  • app/lib/config.ts (0 hunks)
  • app/lib/server-analytics.ts (3 hunks)
  • app/lib/server-config.ts (1 hunks)
  • app/pages/TransactionPreview.tsx (1 hunks)
  • app/pages/TransactionStatus.tsx (5 hunks)
  • app/types.ts (0 hunks)
  • instrumentation-client.ts (0 hunks)
  • instrumentation.ts (0 hunks)
  • next.config.mjs (3 hunks)
  • package.json (1 hunks)
  • sentry.edge.config.ts (0 hunks)
  • sentry.server.config.ts (0 hunks)
💤 Files with no reviewable changes (13)
  • app/hooks/useFundWalletHandler.ts
  • .env.example
  • app/types.ts
  • .github/workflows/node.js.yml
  • instrumentation-client.ts
  • app/hooks/analytics/useServerTracking.ts
  • app/api/v1/analytics/identify/route.ts
  • sentry.edge.config.ts
  • app/api/v1/analytics/track/route.ts
  • instrumentation.ts
  • sentry.server.config.ts
  • app/global-error.tsx
  • app/lib/config.ts
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/pages/TransactionPreview.tsx
  • app/components/TransferForm.tsx
  • app/pages/TransactionStatus.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.

Applied to files:

  • app/pages/TransactionPreview.tsx
  • app/components/TransferForm.tsx
  • app/pages/TransactionStatus.tsx
📚 Learning: 2025-11-06T07:08:54.593Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.593Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/TransferForm.tsx
  • app/pages/TransactionStatus.tsx
📚 Learning: 2025-07-23T07:30:23.720Z
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 177
File: app/utils.ts:179-196
Timestamp: 2025-07-23T07:30:23.720Z
Learning: The `normalizeNetworkName` function in app/utils.ts has been updated to be dynamic and scalable, converting any network identifier to sentence case with hyphens replaced by spaces and proper handling of acronyms like "BNB".

Applied to files:

  • app/components/TransferForm.tsx
📚 Learning: 2025-10-13T14:59:46.723Z
Learnt from: jeremy0x
Repo: paycrest/noblocks PR: 251
File: app/components/blockfest/BlockFestCashbackComponent.tsx:191-191
Timestamp: 2025-10-13T14:59:46.723Z
Learning: In app/components/blockfest/BlockFestCashbackComponent.tsx, the social share URLs intentionally mention "2% cashback" even though the component's cashbackPercentage prop defaults to "1%". The 2% represents the total potential cashback (1% instant + 1% bonus from showing the post at the booth), while the prop represents only the automatic portion.

Applied to files:

  • app/pages/TransactionStatus.tsx
🧬 Code graph analysis (2)
app/components/Navbar.tsx (3)
app/hooks/analytics/useMixpanel.ts (1)
  • trackEvent (91-110)
app/hooks/analytics/analytics-utils.ts (1)
  • trackEvent (231-231)
app/utils.ts (1)
  • IS_MAIN_PRODUCTION_DOMAIN (700-702)
app/hooks/analytics/useMixpanel.ts (1)
app/hooks/analytics/analytics-utils.ts (3)
  • trackEvent (231-231)
  • trackPageView (116-127)
  • trackGetStartedClick (236-236)
🔇 Additional comments (20)
app/api/track-logout/route.ts (2)

4-70: LGTM — Implementation is solid.

The logout tracking endpoint is well-implemented with:

  • Proper JSON parsing and validation (lines 6-12)
  • CSRF protection via origin check in production (lines 14-27)
  • Correct Ethereum address validation using regex (lines 34-42)
  • Comprehensive error handling throughout

The remaining trackServerEvent call maintains logout visibility while the heavier identifyServerUser has been removed per PR objectives.


2-2: Confirm the partial analytics removal strategy is intentional.

The removal of identifyServerUser is clean—no orphaned references remain in the codebase. However, trackServerEvent continues to be imported and used, indicating a deliberate partial removal of server-side analytics.

Please clarify:

  1. Is keeping trackServerEvent intentional, or should it also be removed to fully achieve the memory reduction goal?
  2. If partial removal is intentional, document the reasoning—whether this preserves lightweight event tracking while eliminating user profile overhead, or if trackServerEvent will be addressed in a follow-up.
package.json (1)

107-114: LGTM - Sentry and related dependencies removed.

The removal of @sentry/nextjs and build-time middleware packages (import-in-the-middle, require-in-the-middle) aligns with the PR objective to reduce memory consumption during deployments. The pnpm overrides section remains properly formatted.

app/pages/TransactionPreview.tsx (2)

271-274: LGTM - Analytics payload simplified for privacy.

Removing network, token, and amount fields from the "Swap started" event aligns with the PR's shift toward privacy-focused client-side analytics.


336-339: LGTM - Consistent analytics payload for smart wallet path.

The same privacy-focused simplification applied to the smart wallet tracking event.

app/components/Navbar.tsx (2)

70-70: LGTM - Formatting change only.

The "Login completed" tracking payload is unchanged; this is just a single-line formatting adjustment.


226-228: LGTM - Formatting change only.

The className logic is functionally identical; this is a multi-line reformatting of the template literal.

app/pages/TransactionStatus.tsx (5)

270-275: LGTM - Formatting change only.

The union type literal formatting is purely cosmetic with no functional change.


363-365: LGTM - Analytics payload simplified.

Removing the transaction_status field from the "Swap completed" event is consistent with the PR's analytics simplification approach. The status is already implied by the event name.


492-500: LGTM - Formatting change only.

The className template literal reformatting has no functional impact.


637-641: LGTM - Formatting change only.

Method chaining reformatted across multiple lines for readability.


845-855: LGTM - Formatting change only.

The BlockFestCashbackComponent wrapper formatting is purely cosmetic.

app/lib/server-analytics.ts (2)

151-156: LGTM - Simplified event data construction.

The refactored code directly spreads sanitized properties while maintaining the same privacy-aware behavior through sanitizeProperties(). IP address and user-agent handling is now consistent with the privacy configuration flags.


389-390: LGTM - Formatting change only.

Trailing newline adjustment has no functional impact.

next.config.mjs (3)

55-55: LGTM - Server external packages properly configured.

Adding mixpanel and https-proxy-agent to serverExternalPackages ensures these Node.js-specific packages are not bundled into client-side code, which is necessary after removing Sentry's build wrapper.


74-84: LGTM - Webpack configuration maintained.

The Mixpanel externalization for server-side builds is preserved. Minor formatting changes (whitespace, quote style) have no functional impact.


117-127: Sentry integration successfully removed.

The withSentryConfig wrapper has been removed from next.config.mjs, exporting nextConfig directly. This eliminates Sentry from the build pipeline, addressing the memory issues mentioned in the PR objectives. All orphaned Sentry configuration files and @sentry imports have been removed from the codebase.

app/hooks/analytics/useMixpanel.ts (3)

52-89: LGTM - Consent-gated user identification with conditional PII handling.

Good privacy-conscious implementation:

  • Double-checks initialization and consent
  • Conditionally includes email based on feature flag
  • Proper error handling

The same JSON.parse issue applies here (lines 67-68) - consider the defensive parsing suggested for initMixpanel.


91-110: LGTM - Consent-gated event tracking.

Properly guards against tracking without consent and handles errors gracefully. Same JSON.parse consideration applies (lines 101-102).


112-230: LGTM - Helper functions with optional properties.

All tracking helpers properly delegate to trackEvent and use optional Dict parameters for flexibility. The implementation is consistent with the analytics-utils.ts patterns shown in the relevant code snippets.

Comment on lines 10 to 30
export const initMixpanel = () => {
// Server-side tracking - no client-side initialization needed
if (initialized) return;

const consent = Cookies.get("cookieConsent");
if (!consent || !JSON.parse(consent).analytics) {
return;
}

if (mixpanelToken) {
mixpanel.init(mixpanelToken, {
track_pageview: false,
persistence: "localStorage",
ignore_dnt: false,
verbose: process.env.NODE_ENV === "development",
});

initialized = true;
} else {
console.warn("Mixpanel token is not defined");
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add error handling for malformed consent cookie.

JSON.parse(consent) will throw if the cookie value is malformed, causing silent failures. Consider wrapping in try/catch.

🔎 Proposed fix for safer JSON parsing
 export const initMixpanel = () => {
   if (initialized) return;

   const consent = Cookies.get("cookieConsent");
-  if (!consent || !JSON.parse(consent).analytics) {
-    return;
-  }
+  try {
+    if (!consent || !JSON.parse(consent).analytics) {
+      return;
+    }
+  } catch {
+    console.warn("Invalid cookie consent format");
+    return;
+  }

   if (mixpanelToken) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const initMixpanel = () => {
// Server-side tracking - no client-side initialization needed
if (initialized) return;
const consent = Cookies.get("cookieConsent");
if (!consent || !JSON.parse(consent).analytics) {
return;
}
if (mixpanelToken) {
mixpanel.init(mixpanelToken, {
track_pageview: false,
persistence: "localStorage",
ignore_dnt: false,
verbose: process.env.NODE_ENV === "development",
});
initialized = true;
} else {
console.warn("Mixpanel token is not defined");
}
};
export const initMixpanel = () => {
if (initialized) return;
const consent = Cookies.get("cookieConsent");
try {
if (!consent || !JSON.parse(consent).analytics) {
return;
}
} catch {
console.warn("Invalid cookie consent format");
return;
}
if (mixpanelToken) {
mixpanel.init(mixpanelToken, {
track_pageview: false,
persistence: "localStorage",
ignore_dnt: false,
verbose: process.env.NODE_ENV === "development",
});
initialized = true;
} else {
console.warn("Mixpanel token is not defined");
}
};
🤖 Prompt for AI Agents
In app/hooks/analytics/useMixpanel.ts around lines 10 to 30, the code calls
JSON.parse(consent) directly which will throw on malformed cookie and break
initialization; wrap the parsing in a try/catch, safely parse and validate that
the parsed value is an object with an analytics boolean (treat missing/invalid
as no consent), log a warning when parsing fails (but do not throw), and proceed
to init Mixpanel only when consent is truthy and token exists.

Comment on lines 32 to 50
export const useMixpanel = () => {
// Server-side tracking - no client-side initialization needed
useEffect(() => {
// Empty effect - kept for backward compatibility
const handleConsentChange = () => {
const consent = Cookies.get("cookieConsent");
if (consent && JSON.parse(consent).analytics) {
initMixpanel();
}
};

window.addEventListener("cookieConsentChange", handleConsentChange);
window.addEventListener("cookieConsent", handleConsentChange);
handleConsentChange();

return () => {
window.removeEventListener("cookieConsentChange", handleConsentChange);
window.removeEventListener("cookieConsent", handleConsentChange);
};
}, []);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for dispatchEvent calls with the cookie consent event names
echo "=== Searching for dispatchEvent with cookieConsent events ==="
rg "dispatchEvent.*cookieConsent|new.*Event.*cookieConsent|new.*CustomEvent.*cookieConsent" --type ts --type tsx -g "!node_modules" -A 2 -B 2

echo ""
echo "=== Searching for window.dispatchEvent patterns ==="
rg "dispatchEvent" --type ts --type tsx -g "!node_modules" | head -20

Repository: paycrest/noblocks

Length of output: 248


🏁 Script executed:

#!/bin/bash
# Search for dispatchEvent or CustomEvent patterns more broadly
echo "=== Searching for dispatchEvent patterns ==="
rg -i "dispatchEvent" --max-count 50 -g "!node_modules" -B 2 -A 2

echo ""
echo "=== Searching for CustomEvent patterns ==="
rg -i "new.*Event.*cookieConsent" -g "!node_modules" -B 2 -A 2

echo ""
echo "=== Searching for cookie-related file locations ==="
find . -type f \( -name "*cookie*" -o -name "*consent*" \) -not -path "*/node_modules/*" | head -20

Repository: paycrest/noblocks

Length of output: 1855


🏁 Script executed:

#!/bin/bash
# Specifically search for cookieConsentChange
echo "=== Searching for cookieConsentChange dispatch ==="
rg "cookieConsentChange" -g "!node_modules" -B 2 -A 2

echo ""
echo "=== Examine the CookieConsent component ==="
cat app/components/CookieConsent.tsx

Repository: paycrest/noblocks

Length of output: 10687


Remove the unused cookieConsentChange event listener.

Only the cookieConsent event is dispatched from the CookieConsent component. The cookieConsentChange event is never dispatched anywhere in the codebase, making that listener dead code.

🤖 Prompt for AI Agents
In app/hooks/analytics/useMixpanel.ts around lines 32 to 50, remove the unused
window.addEventListener and window.removeEventListener calls for the
"cookieConsentChange" event (they are dead code); keep the handler and the
existing "cookieConsent" event listener and cleanup as-is so initMixpanel still
runs when the actual "cookieConsent" event is dispatched.

Comment on lines 57 to 61
return validateConfig(
"MIXPANEL_SERVER_TOKEN",
process.env.MIXPANEL_SERVER_TOKEN || process.env.MIXPANEL_TOKEN || "",
process.env.MIXPANEL_SERVER_TOKEN || "",
false, // Optional - analytics can fail gracefully
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for environment variable documentation and examples
find . -type f \( -name ".env*" -o -name "*.example" -o -name "*.md" \) ! -path "*/node_modules/*" | head -20

Repository: paycrest/noblocks

Length of output: 436


🏁 Script executed:

# Search for MIXPANEL token references in config files and documentation
rg "MIXPANEL_SERVER_TOKEN|MIXPANEL_TOKEN" -g "*.env*" -g "*.md" -g "*.example" --max-count=20

Repository: paycrest/noblocks

Length of output: 455


🏁 Script executed:

# Check the actual server-config.ts file to understand the change context
cat -n app/lib/server-config.ts | head -70

Repository: paycrest/noblocks

Length of output: 2527


🏁 Script executed:

# Search for MIXPANEL_SERVER_TOKEN usage throughout the codebase
rg "MIXPANEL_SERVER_TOKEN" --max-count=20

Repository: paycrest/noblocks

Length of output: 184


🏁 Script executed:

# Check if .env.example has been updated to include MIXPANEL_SERVER_TOKEN
cat -n .env.example

Repository: paycrest/noblocks

Length of output: 5478


🏁 Script executed:

# Check environment variables documentation in detail
cat -n docs/environment-variables.md | grep -A 5 -B 5 "MIXPANEL"

Repository: paycrest/noblocks

Length of output: 1739


Update environment variable name from MIXPANEL_TOKEN to MIXPANEL_SERVER_TOKEN in configuration files and documentation.

The code now expects MIXPANEL_SERVER_TOKEN, but .env.example and docs/environment-variables.md still reference MIXPANEL_TOKEN. This mismatch will cause server-side Mixpanel tracking to silently fail on all deployments unless environment variables are manually updated. Update both the .env.example file (line 56) and documentation (lines 28, 128, 153 in docs/environment-variables.md) to reflect the new variable name.

🤖 Prompt for AI Agents
In app/lib/server-config.ts around lines 57 to 61 the code expects
MIXPANEL_SERVER_TOKEN but .env.example (line 56) and
docs/environment-variables.md (lines 28, 128, 153) still reference
MIXPANEL_TOKEN; update .env.example line 56 to use MIXPANEL_SERVER_TOKEN and
replace the three occurrences in docs/environment-variables.md (lines 28, 128,
153) with MIXPANEL_SERVER_TOKEN, and run a quick repo-wide search to ensure no
other references to MIXPANEL_TOKEN remain so deployments pick up the correct env
var.

@5ran6 5ran6 force-pushed the main branch 2 times, most recently from 06dafbf to 5b287b7 Compare December 19, 2025 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants