-
Notifications
You must be signed in to change notification settings - Fork 559
posthog migration #7340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
posthog migration #7340
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
|
WalkthroughThis change removes all React-based PostHog analytics integration from the dashboard, portal, and playground-web apps, including providers, pageview tracking, and identifier components. It introduces new instrumentation-client modules for PostHog initialization, updates environment variables and Next.js rewrites for proxying analytics requests, and refactors analytics identification and reset logic into dedicated client modules. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App
participant instrumentation-client.ts
participant PostHog Cloud
User->>App: Loads application
App->>instrumentation-client.ts: Imports and runs PostHog initialization
instrumentation-client.ts->>PostHog Cloud: Initializes analytics (if env vars set)
User->>App: Navigates, logs in/out, interacts
App->>instrumentation-client.ts: (Events tracked via PostHog JS, not React context)
instrumentation-client.ts->>PostHog Cloud: Sends analytics events (pageviews, etc.)
App->>dashboard.client.tsx: Calls AccountIdentifier/TeamIdentifier/reset as needed
dashboard.client.tsx->>PostHog Cloud: Identifies user/team or resets analytics state
Possibly related PRs
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
fb4e1ed
to
0fe09bd
Compare
0fe09bd
to
d24c171
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #7340 +/- ##
=======================================
Coverage 55.58% 55.58%
=======================================
Files 909 909
Lines 58683 58683
Branches 4158 4158
=======================================
Hits 32617 32617
Misses 25959 25959
Partials 107 107
🚀 New features to boost your workflow:
|
size-limit report 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🔭 Outside diff range comments (1)
apps/portal/src/components/others/Feedback.tsx (1)
31-63
: 🛠️ Refactor suggestion
⚠️ Potential issueFeedback is collected but never stored or transmitted
feedback
state is updated, yet the value is discarded when the user presses Submit – no API call, analytics event, or log occurs. This results in dead code and a misleading UI (users expect their input to be sent somewhere).- <Button - onClick={() => { - setIsSubmitted(true); - }} - > + <Button + onClick={async () => { + await fetch("/api/feedback", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ source: "portal-docs", feedback }), + }).catch(() => {/* silently fail */}); + setIsSubmitted(true); + }} + >If no backend endpoint exists, remove the unused
feedback
state entirely to avoid confusing future maintainers.
♻️ Duplicate comments (1)
apps/portal/instrumentation-client.ts (1)
1-17
: Same SSR & host issues as playground implementation
- Importing
posthog-js
unguarded risks server crashes – apply the guarded dynamic import pattern suggested for the playground file.ui_host
again usesus.posthog.com
, whereas rewrites forward tous.i.posthog.com
; reconcile the domains.
🧹 Nitpick comments (4)
apps/dashboard/src/app/nebula-app/layout.tsx (1)
38-49
: Removal of PHProvider looks good – minor nitLayout is cleaner without the nested PostHog wrappers and the body class setup remains intact.
Optional: if you still need automatic page-view events, consider adding a smalluseEffect
inNebulaProviders
that callsposthog?.capture('$pageview')
instead of re-introducing a heavy provider wrapper.apps/dashboard/.env.example (1)
111-116
: Remove legacyNEXT_PUBLIC_POSTHOG_API_KEY
and consolidate naming
The.env.example
addsNEXT_PUBLIC_POSTHOG_KEY
/_HOST
but still retains the outdatedNEXT_PUBLIC_POSTHOG_API_KEY
at line 40. To avoid confusion, drop the oldPOSTHOG_API_KEY
entry and standardize onNEXT_PUBLIC_POSTHOG_KEY
(and its host variable).🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 111-111: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 114-114: [QuoteCharacter] The value has quote characters (', ")
[warning] 115-115: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
apps/portal/next.config.mjs (1)
73-90
: Duplicate rewrite & property supportReplicate the comments given for the dashboard config:
• Combine the wildcard and
/decide
rules – the latter is shadowed.
• ValidateskipTrailingSlashRedirect
against the project’s Next.js version.These small clean-ups reduce config noise and potential upgrade friction.
apps/dashboard/src/hooks/analytics/useTrack.ts (1)
3-8
: TightenTrackingParams
to avoid accidental key overlapsBecause
category
,action
, andlabel
share the same key space as the index signature, TypeScript will allow callers to re-declare them with the wrong type.Consider omitting them from the index signature via an intersection:
export type TrackingParams = { category: string; action: string; label?: string; } & Record<string, unknown>;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (36)
apps/dashboard/.env.example
(1 hunks)apps/dashboard/instrumentation-client.tsx
(1 hunks)apps/dashboard/knip.json
(1 hunks)apps/dashboard/next.config.ts
(2 hunks)apps/dashboard/package.json
(1 hunks)apps/dashboard/src/app/(app)/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
(0 hunks)apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/layout.tsx
(1 hunks)apps/dashboard/src/app/pay/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
(0 hunks)apps/dashboard/src/hooks/analytics/useTrack.ts
(1 hunks)apps/dashboard/src/lib/posthog/Posthog.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/dashboard/src/utils/errorParser.tsx
(0 hunks)apps/playground-web/instrumentation-client.ts
(1 hunks)apps/playground-web/knip.json
(1 hunks)apps/playground-web/next.config.mjs
(1 hunks)apps/playground-web/package.json
(1 hunks)apps/playground-web/src/app/layout.tsx
(1 hunks)apps/playground-web/src/lib/posthog/Posthog.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/portal/instrumentation-client.ts
(1 hunks)apps/portal/knip.json
(1 hunks)apps/portal/next.config.mjs
(1 hunks)apps/portal/package.json
(1 hunks)apps/portal/src/app/layout.tsx
(1 hunks)apps/portal/src/components/AI/chat.tsx
(1 hunks)apps/portal/src/components/others/Feedback.tsx
(1 hunks)apps/portal/src/lib/env.ts
(0 hunks)apps/portal/src/lib/posthog/Posthog.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogPageView.tsx
(0 hunks)
💤 Files with no reviewable changes (14)
- apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
- apps/dashboard/src/utils/errorParser.tsx
- apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
- apps/portal/src/lib/env.ts
- apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
- apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
- apps/portal/src/lib/posthog/Posthog.tsx
- apps/portal/src/lib/posthog/PosthogPageView.tsx
- apps/playground-web/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
- apps/playground-web/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/PosthogPageView.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/src/app/nebula-app/layout.tsx (1)
apps/dashboard/src/app/nebula-app/providers.tsx (1)
NebulaProviders
(13-31)
🪛 dotenv-linter (3.3.0)
apps/dashboard/.env.example
[warning] 111-111: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 114-114: [QuoteCharacter] The value has quote characters (', ")
[warning] 115-115: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (15)
apps/dashboard/knip.json (2)
16-16
: Verify necessity of ignoringfast-xml-parser
.
fast-xml-parser
was added to theignoreDependencies
list. Please confirm this dependency is actually used elsewhere and that suppressing knip warnings for it is intentional.
17-18
: Ignore new PostHog dependencies for knip analysis.Adding
posthog-js
andposthog-node
toignoreDependencies
prevents knip from flagging these instrumentation packages as unused at analysis time.apps/playground-web/package.json (1)
39-40
: Upgrade and add PostHog dependencies.You've upgraded
posthog-js
to1.252.0
and introduced[email protected]
. Ensure these versions align with your new instrumentation-client logic and thatposthog-node
remains server-only and excluded from the client bundle.apps/dashboard/package.json (1)
80-81
: Upgrade PostHog dependencies in the dashboard app.The dashboard now uses
[email protected]
and[email protected]
. Verifyposthog-node
is only imported in server-side modules (e.g., instrumentation client) and not inadvertently included in the client bundle.apps/portal/package.json (1)
46-47
: Upgrade and add PostHog dependencies in the portal app.
posthog-js
pinned to1.252.0
and[email protected]
added. Confirmposthog-node
is confined to server instrumentation code and excluded from client-side outputs via your Next.js rewrites.apps/playground-web/knip.json (1)
6-6
: Ignoreposthog-node
in knip for playground-web.Adding
posthog-node
toignoreDependencies
prevents knip from falsely flagging server-only instrumentation modules as unused, matching the pattern in other apps.apps/portal/knip.json (1)
11-13
: PostHog deps correctly ignored – good catchAdding
posthog-node
to theignoreDependencies
list keeps knip from flagging this server-side SDK as “unused” in the client bundle audit. No further action required.apps/dashboard/src/app/pay/components/client/Providers.client.tsx (1)
7-10
: Verify app-wide PostHog initialisation now that the provider is gone
PHProvider
(and the per-page<PostHogPageView />
) were removed, so any analytics/page-view tracking must now be handled by the new top-levelinstrumentation-client
. Double-check that this file is imported exactly once (e.g. viaapp/layout.tsx
orsrc/instrumentation.ts
) so PostHog is initialised only once in the browser context.apps/portal/src/components/AI/chat.tsx (1)
126-127
: Callback deps updated correctly
posthog
was removed from the dependency array; the hook now only re-creates whenconversationId
changes. Looks good.apps/playground-web/src/app/layout.tsx (1)
47-63
: Ensure new instrumentation client is imported
LegacyPHProvider
and PostHog components are removed, but I don’t see an import for the side‐effect‐onlyinstrumentation-client.ts
(PostHog init). Verify you’ve added something like:import '../instrumentation-client';so analytics actually boot up.
apps/dashboard/src/app/bridge/components/client/Providers.client.tsx (1)
1-5
: Legacy PostHog wrappers correctly removed
AllPHProvider
andPostHogPageView
imports/usage have been stripped, simplifying the provider hierarchy.apps/dashboard/src/app/(app)/layout.tsx (1)
63-74
: Removal of legacy PostHog layout components approved
ThePHProvider
,PosthogHeadSetup
, andPostHogPageView
have been cleanly removed from the root layout.apps/playground-web/instrumentation-client.ts (1)
6-14
:ui_host
mismatch with rewrite targetRewrites forward
/_ph/*
tohttps://us.i.posthog.com
butui_host
here points tohttps://us.posthog.com
(no “.i
” sub-domain).
Confirm this endpoint is intentional; otherwise events and static assets may bypass the proxy/CSP.apps/dashboard/next.config.ts (1)
188-190
: Verify unsupportedskipTrailingSlashRedirect
flag
skipTrailingSlashRedirect
is still experimental and absent from some Next.js versions.
If the build fails, replace it with a custom rewrite or upgrade Next.js to ≥ 13.4.
Please confirm CI passes on all deployment targets.apps/playground-web/next.config.mjs (1)
49-52
:✅ Verification successful
Verify
skipTrailingSlashRedirect
is supported in your Next.js version
skipTrailingSlashRedirect
is only available from Next 14.1+.
If the project is pinned to an earlier version the build will fail silently at runtime.Run a quick grep to confirm the workspace Next.js version:
🏁 Script executed:
#!/bin/bash jq -r '.dependencies."next"' package.jsonLength of output: 48
🏁 Script executed:
#!/bin/bash # Check if Next.js is listed under dependencies jq -r '.dependencies."next"' package.json # Check if Next.js is listed under devDependencies jq -r '.devDependencies."next"' package.json # Fallback: grep any mention of "next" in package.json rg '"next"' -n package.jsonLength of output: 130
🏁 Script executed:
#!/bin/bash # Check if Next.js is listed in the playground-web app’s package.json TARGET="apps/playground-web/package.json" echo "Inspecting $TARGET for Next.js version..." jq -r '.dependencies."next"' "$TARGET" jq -r '.devDependencies."next"' "$TARGET" rg '"next"' -n "$TARGET" || trueLength of output: 402
skipTrailingSlashRedirect is supported in Next.js 15.3.3
No action required—your Next.js version (15.3.3) is above the 14.1+ threshold for
skipTrailingSlashRedirect
.• apps/playground-web/package.json:
– "next": "15.3.3"
d24c171
to
4864b9f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/dashboard/src/hooks/analytics/useTrack.ts (1)
16-22
:⚠️ Potential issueDuplicate console logging still enabled for production – remove the second call or guard it
The second
console.debug
(lines 20-21) executes unconditionally, so production builds will emit analytics payloads to the browser console. This repeats the message already printed inside theNODE_ENV !== "production"
guard, adds noise, and risks leaking PII.- if (process.env.NODE_ENV !== "production") { - console.debug(`[PH.capture]:${catActLab}`, restData); - } - - // TODO: bring back tracking - console.debug(catActLab, restData); + // TODO: bring back tracking + if (process.env.NODE_ENV !== "production") { + console.debug(`[PH.capture disabled]: ${catActLab}`, restData); + }This keeps a single debug line only in non-production environments.
🧹 Nitpick comments (2)
apps/dashboard/.env.example (2)
107-108
: Add context forNEXT_PUBLIC_ENGINE_CLOUD_URL
.This new variable lacks a descriptive comment; please add a short explanation (purpose, default/local-dev value) above it, consistent with the style of adjacent entries.
🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
109-111
: Quote thePOSTHOG_HOST
URL for consistency.All other host URLs in this example are wrapped in double quotes. Update accordingly:
-NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com +NEXT_PUBLIC_POSTHOG_HOST="https://us.i.posthog.com"🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (43)
apps/dashboard/.env.example
(1 hunks)apps/dashboard/knip.json
(1 hunks)apps/dashboard/next.config.ts
(2 hunks)apps/dashboard/package.json
(1 hunks)apps/dashboard/src/@/analytics/dashboard.client.tsx
(1 hunks)apps/dashboard/src/@/analytics/shared.ts
(1 hunks)apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
(2 hunks)apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/layout.tsx
(3 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
(2 hunks)apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/layout.tsx
(1 hunks)apps/dashboard/src/app/pay/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
(0 hunks)apps/dashboard/src/hooks/analytics/useTrack.ts
(1 hunks)apps/dashboard/src/lib/posthog/Posthog.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/dashboard/src/utils/errorParser.tsx
(0 hunks)apps/playground-web/instrumentation-client.ts
(1 hunks)apps/playground-web/knip.json
(1 hunks)apps/playground-web/next.config.mjs
(1 hunks)apps/playground-web/package.json
(1 hunks)apps/playground-web/src/app/layout.tsx
(1 hunks)apps/playground-web/src/lib/posthog/Posthog.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/portal/instrumentation-client.ts
(1 hunks)apps/portal/knip.json
(1 hunks)apps/portal/next.config.mjs
(1 hunks)apps/portal/package.json
(1 hunks)apps/portal/src/app/layout.tsx
(1 hunks)apps/portal/src/components/AI/chat.tsx
(1 hunks)apps/portal/src/components/others/Feedback.tsx
(1 hunks)apps/portal/src/lib/env.ts
(0 hunks)apps/portal/src/lib/posthog/Posthog.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogPageView.tsx
(0 hunks)
💤 Files with no reviewable changes (14)
- apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
- apps/dashboard/src/utils/errorParser.tsx
- apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
- apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
- apps/playground-web/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
- apps/portal/src/lib/env.ts
- apps/dashboard/src/lib/posthog/PosthogPageView.tsx
- apps/portal/src/lib/posthog/PosthogPageView.tsx
- apps/portal/src/lib/posthog/Posthog.tsx
- apps/playground-web/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
✅ Files skipped from review due to trivial changes (1)
- apps/dashboard/src/@/analytics/shared.ts
🚧 Files skipped from review as they are similar to previous changes (26)
- apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
- apps/dashboard/knip.json
- apps/playground-web/knip.json
- apps/dashboard/src/app/pay/components/client/Providers.client.tsx
- apps/portal/knip.json
- apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
- apps/dashboard/src/app/nebula-app/layout.tsx
- apps/portal/package.json
- apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
- apps/playground-web/package.json
- apps/dashboard/next.config.ts
- apps/playground-web/instrumentation-client.ts
- apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
- apps/portal/src/components/others/Feedback.tsx
- apps/portal/src/components/AI/chat.tsx
- apps/portal/instrumentation-client.ts
- apps/dashboard/package.json
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
- apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
- apps/playground-web/src/app/layout.tsx
- apps/dashboard/src/@/analytics/dashboard.client.tsx
- apps/playground-web/next.config.mjs
- apps/dashboard/src/app/(app)/layout.tsx
- apps/portal/src/app/layout.tsx
- apps/portal/next.config.mjs
🧰 Additional context used
🪛 dotenv-linter (3.3.0)
apps/dashboard/.env.example
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Build Packages
- GitHub Check: Lint Packages
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Unit Tests
- GitHub Check: Analyze (javascript)
e4907ad
to
ab73bf4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
apps/dashboard/.env.example (1)
107-108
: Remove unnecessary quotes & place key logicallyQuote marks are not needed when the value is empty, and they trigger
dotenv-linter
warnings.
Also,NEXT_PUBLIC_ENGINE_CLOUD_URL
should be grouped with the otherNEXT_PUBLIC_*
URLs above for readability.-NEXT_PUBLIC_ENGINE_CLOUD_URL="" +NEXT_PUBLIC_ENGINE_CLOUD_URL=🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
apps/dashboard/instrumentation-client.ts (1)
5-17
: Expose the singleton instance to downstream modulesAt the moment this file only performs side-effects. Exporting the configured
posthog
instance allows other helpers (e.g. a typedtrack()
wrapper) to reuse the same import
instead of re-importingposthog-js
elsewhere.if (NEXT_PUBLIC_POSTHOG_KEY) { posthog.init(/* … */); } -export {}; +export { posthog };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (43)
apps/dashboard/.env.example
(1 hunks)apps/dashboard/instrumentation-client.ts
(1 hunks)apps/dashboard/knip.json
(1 hunks)apps/dashboard/next.config.ts
(2 hunks)apps/dashboard/package.json
(1 hunks)apps/dashboard/src/@/analytics/dashboard.client.tsx
(1 hunks)apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
(3 hunks)apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/layout.tsx
(1 hunks)apps/dashboard/src/app/pay/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
(0 hunks)apps/dashboard/src/hooks/analytics/useTrack.ts
(1 hunks)apps/dashboard/src/lib/posthog/Posthog.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/dashboard/src/utils/errorParser.tsx
(0 hunks)apps/playground-web/instrumentation-client.ts
(1 hunks)apps/playground-web/knip.json
(1 hunks)apps/playground-web/next.config.mjs
(1 hunks)apps/playground-web/package.json
(1 hunks)apps/playground-web/src/app/layout.tsx
(1 hunks)apps/playground-web/src/lib/posthog/Posthog.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/portal/instrumentation-client.ts
(1 hunks)apps/portal/knip.json
(1 hunks)apps/portal/next.config.mjs
(1 hunks)apps/portal/package.json
(1 hunks)apps/portal/src/app/layout.tsx
(1 hunks)apps/portal/src/components/AI/chat.tsx
(1 hunks)apps/portal/src/components/others/Feedback.tsx
(1 hunks)apps/portal/src/lib/env.ts
(0 hunks)apps/portal/src/lib/posthog/Posthog.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogPageView.tsx
(0 hunks)
💤 Files with no reviewable changes (14)
- apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
- apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/utils/errorParser.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
- apps/portal/src/lib/posthog/PosthogPageView.tsx
- apps/portal/src/lib/posthog/Posthog.tsx
- apps/playground-web/src/lib/posthog/Posthog.tsx
- apps/portal/src/lib/env.ts
- apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/PosthogPageView.tsx
- apps/playground-web/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
✅ Files skipped from review due to trivial changes (1)
- apps/dashboard/knip.json
🚧 Files skipped from review as they are similar to previous changes (26)
- apps/portal/package.json
- apps/playground-web/package.json
- apps/playground-web/knip.json
- apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
- apps/portal/knip.json
- apps/dashboard/package.json
- apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
- apps/portal/src/components/others/Feedback.tsx
- apps/dashboard/src/app/pay/components/client/Providers.client.tsx
- apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
- apps/playground-web/instrumentation-client.ts
- apps/playground-web/src/app/layout.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
- apps/dashboard/src/app/nebula-app/layout.tsx
- apps/portal/instrumentation-client.ts
- apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
- apps/dashboard/next.config.ts
- apps/dashboard/src/app/(app)/layout.tsx
- apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
- apps/dashboard/src/@/analytics/dashboard.client.tsx
- apps/portal/src/components/AI/chat.tsx
- apps/playground-web/next.config.mjs
- apps/dashboard/src/hooks/analytics/useTrack.ts
- apps/portal/next.config.mjs
- apps/portal/src/app/layout.tsx
🧰 Additional context used
🪛 dotenv-linter (3.3.0)
apps/dashboard/.env.example
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Lint Packages
- GitHub Check: Build Packages
- GitHub Check: Unit Tests
- GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/dashboard/instrumentation-client.ts (1)
9-15
: Verify option names & value types against PostHog 1.252.0
capture_pageview: "history_change"
and
capture_pageleave: "if_capture_pageview"
are not documented in the PostHog 1.x typings
(accepted types are boolean or"history"
for SPA support). A typo here will silently disable
page/navigation analytics.Please confirm these strings are supported in 1.252.0 or switch to the canonical flags:
- capture_pageview: "history_change", - capture_pageleave: "if_capture_pageview", + capture_pageview: true, // or "history" + capture_pageleave: true,
ab73bf4
to
fd4f354
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (1)
apps/dashboard/.env.example (1)
110-111
:⚠️ Potential issueAlign PostHog host with client code and fix key ordering.
The currentNEXT_PUBLIC_POSTHOG_HOST
(https://us.i.posthog.com
) doesn’t matchinstrumentation-client.ts
(which useshttps://us.posthog.com
), causing analytics to break. Also, alphabetize the vars (HOST before KEY) and remove quotes on the emptyKEY
per linter rules.- NEXT_PUBLIC_POSTHOG_KEY="" - NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com + NEXT_PUBLIC_POSTHOG_HOST=https://us.posthog.com + NEXT_PUBLIC_POSTHOG_KEY=🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
🧹 Nitpick comments (6)
apps/dashboard/.eslintrc.js (1)
113-118
: Message string and pattern mismatch – tighten for clarityThe explanatory message uses the single-star pattern
"src/@/analytics/*"
, while the override below targets"src/@/analytics/**/*"
.
Although this is purely cosmetic, keeping the wording/patterns consistent avoids confusion for future maintainers skimming the config.- 'Import "posthog-js" directly only within the analytics helpers ("src/@/analytics/*"). Use the exported helpers from "@/analytics/track" elsewhere.', + 'Import "posthog-js" directly only within analytics helpers ("src/@/analytics/**/*"). Use the exported helpers from "@/analytics/track" elsewhere.',apps/dashboard/.env.example (2)
106-107
: Remove quotes for empty engine cloud URL and reorder keys alphabetically.
Dotenv-linter flags quote characters on empty values and expects keys in alphabetical order. SwapNEXT_PUBLIC_ENGINE_CLOUD_URL
above the commentedNEXT_PUBLIC_THIRDWEB_VAULT_URL
and drop the quotes for the empty value.- # NEXT_PUBLIC_THIRDWEB_VAULT_URL="" - NEXT_PUBLIC_ENGINE_CLOUD_URL="" + NEXT_PUBLIC_ENGINE_CLOUD_URL= + # NEXT_PUBLIC_THIRDWEB_VAULT_URL=""🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 106-106: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
109-109
: Capitalize the PostHog section heading.
Section headers elsewhere are title-cased. Update to match style.-# posthog setup +# PostHog setupapps/dashboard/src/@/analytics/track/__internal.ts (1)
22-23
: Return value can signal success/failure.Consider returning a boolean (
true
if captured,false
if skipped).
It allows callers to react (e.g. buffer locally) without having to re-inspect PostHog state.apps/dashboard/src/@/analytics/track/README.md (2)
32-38
: Add language identifier to fenced code block (markdown-lint MD040).-``` +```text track/ # ← you are here ├─ __internal.ts # low-level wrapper around posthog.capture (do NOT use) ├─ contract.ts # "contract" event category helpers ├─ README.md # this file └─ … # future categories live here🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
32-32: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
40-46
: Comma before ‘so’ (LanguageTool).… star-export, so the helpers are surfaced …
Minor grammar nit – add a comma before “so”.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (49)
apps/dashboard/.env.example
(1 hunks)apps/dashboard/.eslintrc.js
(2 hunks)apps/dashboard/instrumentation-client.ts
(1 hunks)apps/dashboard/knip.json
(1 hunks)apps/dashboard/next.config.ts
(2 hunks)apps/dashboard/package.json
(1 hunks)apps/dashboard/src/@/analytics/dashboard.client.tsx
(1 hunks)apps/dashboard/src/@/analytics/track.ts
(1 hunks)apps/dashboard/src/@/analytics/track/README.md
(1 hunks)apps/dashboard/src/@/analytics/track/__internal.ts
(1 hunks)apps/dashboard/src/@/analytics/track/contract.ts
(1 hunks)apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
(3 hunks)apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/layout.tsx
(1 hunks)apps/dashboard/src/app/pay/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
(3 hunks)apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
(0 hunks)apps/dashboard/src/hooks/analytics/useTrack.ts
(1 hunks)apps/dashboard/src/lib/posthog/Posthog.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/dashboard/src/utils/errorParser.tsx
(0 hunks)apps/playground-web/instrumentation-client.ts
(1 hunks)apps/playground-web/knip.json
(1 hunks)apps/playground-web/next.config.mjs
(1 hunks)apps/playground-web/package.json
(1 hunks)apps/playground-web/src/app/layout.tsx
(1 hunks)apps/playground-web/src/lib/posthog/Posthog.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/portal/instrumentation-client.ts
(1 hunks)apps/portal/knip.json
(1 hunks)apps/portal/next.config.mjs
(1 hunks)apps/portal/package.json
(1 hunks)apps/portal/src/app/layout.tsx
(1 hunks)apps/portal/src/components/AI/chat.tsx
(1 hunks)apps/portal/src/components/others/Feedback.tsx
(1 hunks)apps/portal/src/lib/env.ts
(0 hunks)apps/portal/src/lib/posthog/Posthog.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogPageView.tsx
(0 hunks)
💤 Files with no reviewable changes (14)
- apps/dashboard/src/utils/errorParser.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
- apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
- apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
- apps/portal/src/lib/env.ts
- apps/portal/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/lib/posthog/PosthogPageView.tsx
- apps/playground-web/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/Posthog.tsx
- apps/playground-web/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
- apps/portal/src/lib/posthog/Posthog.tsx
✅ Files skipped from review due to trivial changes (2)
- apps/playground-web/package.json
- apps/dashboard/src/@/analytics/track.ts
🚧 Files skipped from review as they are similar to previous changes (27)
- apps/playground-web/knip.json
- apps/dashboard/knip.json
- apps/dashboard/package.json
- apps/portal/knip.json
- apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
- apps/portal/package.json
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
- apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
- apps/dashboard/src/app/pay/components/client/Providers.client.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
- apps/portal/src/components/others/Feedback.tsx
- apps/dashboard/instrumentation-client.ts
- apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
- apps/playground-web/instrumentation-client.ts
- apps/dashboard/src/app/(app)/layout.tsx
- apps/playground-web/next.config.mjs
- apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
- apps/portal/instrumentation-client.ts
- apps/dashboard/src/app/nebula-app/layout.tsx
- apps/portal/src/components/AI/chat.tsx
- apps/dashboard/next.config.ts
- apps/playground-web/src/app/layout.tsx
- apps/portal/src/app/layout.tsx
- apps/dashboard/src/hooks/analytics/useTrack.ts
- apps/dashboard/src/@/analytics/dashboard.client.tsx
- apps/portal/next.config.mjs
- apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/@/analytics/track/contract.ts (2)
packages/thirdweb/src/exports/thirdweb.ts (1)
isAddress
(308-308)apps/dashboard/src/@/analytics/track/__internal.ts (1)
__internal__reportEvent
(12-23)
apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx (1)
apps/dashboard/src/@/analytics/track/contract.ts (1)
reportContractDeployed
(52-56)
🪛 dotenv-linter (3.3.0)
apps/dashboard/.env.example
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
🪛 LanguageTool
apps/dashboard/src/@/analytics/track/README.md
[uncategorized] ~85-~85: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...(one directory up) and add a star-export so the helpers are surfaced at the pack...
(COMMA_COMPOUND_SENTENCE_2)
🪛 markdownlint-cli2 (0.17.2)
apps/dashboard/src/@/analytics/track/README.md
32-32: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
// allow direct PostHog imports inside analytics helpers | ||
{ | ||
files: "src/@/analytics/**/*", | ||
rules: { | ||
"no-restricted-imports": ["off"], | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Don’t disable all import restrictions in analytics helpers
Turning no-restricted-imports
completely off for "src/@/analytics/**/*"
re-enables every restricted import (e.g. direct Chakra-UI components, next/navigation
’s useRouter
, etc.) inside that folder.
We only need to lift the ban for posthog-js
; the other guards should keep protecting the codebase.
Consider a narrower override that keeps the rest of the rule active:
{
files: "src/@/analytics/**/*",
rules: {
- "no-restricted-imports": ["off"],
+ "no-restricted-imports": [
+ "error",
+ {
+ paths: [
+ // Copy the existing paths **except** the posthog-js entry,
+ // so the other restrictions remain enforced.
+ ],
+ },
+ ],
},
},
This preserves the architectural discipline for all other libraries while still allowing direct posthog-js
imports where they’re meant to live.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/dashboard/.eslintrc.js around lines 147 to 153, the current override
disables all import restrictions for files in src/@/analytics/**/*, which
unintentionally allows all restricted imports. Instead, modify the override to
only allow direct imports of 'posthog-js' by configuring the
no-restricted-imports rule to permit 'posthog-js' while keeping other
restrictions active. This ensures only the intended exception is made without
removing protections for other restricted imports.
if (!posthog.__loaded) { | ||
console.warn( | ||
"[DASHBOARD_ANALYTICS] is not initialized, cannot track event", | ||
); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
posthog.__loaded
is not in the public typings – this will break tsc
.
posthog-js
’s type definitions do not expose the __loaded
flag, so accessing it directly fails strict compilation (Property '__loaded' does not exist on type 'PostHog'
). Cast or guard with an index signature to silence the error without disabling noImplicitAny
.
- if (!posthog.__loaded) {
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+ if (!(posthog as unknown as { __loaded?: boolean }).__loaded) {
📝 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.
if (!posthog.__loaded) { | |
console.warn( | |
"[DASHBOARD_ANALYTICS] is not initialized, cannot track event", | |
); | |
return; | |
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | |
if (!(posthog as unknown as { __loaded?: boolean }).__loaded) { | |
console.warn( | |
"[DASHBOARD_ANALYTICS] is not initialized, cannot track event", | |
); | |
return; |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/__internal.ts around lines 16 to 20,
accessing the private property posthog.__loaded causes TypeScript compilation
errors because it is not in the public typings. To fix this, use a type
assertion or an index signature to access __loaded safely, such as casting
posthog to any or using (posthog as any).__loaded, so the compiler does not
complain while preserving type safety without disabling noImplicitAny.
export function reportContractDeployed( | ||
payload: z.infer<typeof EVMContractSchema>, | ||
) { | ||
__internal__reportEvent("contract deployed", payload); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Runtime validation is missing despite documented intent.
reportContractDeployed
forwards the payload without calling EVMContractSchema.parse
, so invalid data can slip through unchecked.
export function reportContractDeployed(
payload: z.infer<typeof EVMContractSchema>,
) {
- __internal__reportEvent("contract deployed", payload);
+ const parsed = EVMContractSchema.parse(payload);
+ __internal__reportEvent("contract deployed", parsed);
}
📝 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.
export function reportContractDeployed( | |
payload: z.infer<typeof EVMContractSchema>, | |
) { | |
__internal__reportEvent("contract deployed", payload); | |
} | |
export function reportContractDeployed( | |
payload: z.infer<typeof EVMContractSchema>, | |
) { | |
const parsed = EVMContractSchema.parse(payload); | |
__internal__reportEvent("contract deployed", parsed); | |
} |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/contract.ts around lines 52 to 56, the
function reportContractDeployed forwards the payload without validating it
against EVMContractSchema. To fix this, call EVMContractSchema.parse on the
payload before passing it to __internal__reportEvent to ensure runtime
validation and prevent invalid data from being reported.
const EVMAddressSchema = z.string().check( | ||
z.refine(isAddress, { | ||
message: "Invalid EVM address", | ||
}), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
z.string().check(…)
and z.refine
combo is invalid Zod API.
check
is not a method on Zod schemas (v3/v4). Use .refine
directly:
-const EVMAddressSchema = z.string().check(
- z.refine(isAddress, {
- message: "Invalid EVM address",
- }),
-);
+const EVMAddressSchema = z
+ .string()
+ .refine(isAddress, { message: "Invalid EVM address" });
📝 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.
const EVMAddressSchema = z.string().check( | |
z.refine(isAddress, { | |
message: "Invalid EVM address", | |
}), | |
); | |
const EVMAddressSchema = z | |
.string() | |
.refine(isAddress, { message: "Invalid EVM address" }); |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/contract.ts around lines 35 to 39, the
code incorrectly uses z.string().check(...) which is not a valid method in Zod
v3/v4. Replace the usage of .check with a direct call to .refine on the string
schema, passing the isAddress function and the error message as options to
correctly validate the EVM address.
const EVMChainIdSchema = z.coerce.number().check( | ||
z.gte(1, { | ||
message: "Invalid chain ID", | ||
}), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue for chain-id schema – .gte
belongs on a number schema.
-const EVMChainIdSchema = z.coerce.number().check(
- z.gte(1, {
- message: "Invalid chain ID",
- }),
-);
+const EVMChainIdSchema = z.coerce
+ .number()
+ .gte(1, { message: "Invalid chain ID" });
📝 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.
const EVMChainIdSchema = z.coerce.number().check( | |
z.gte(1, { | |
message: "Invalid chain ID", | |
}), | |
); | |
const EVMChainIdSchema = z.coerce | |
.number() | |
.gte(1, { message: "Invalid chain ID" }); |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/contract.ts around lines 41 to 45, the
chain ID schema incorrectly applies `.gte` on a coerced number schema using
`.check`. To fix this, replace `.check(z.gte(1))` with `.gte(1)` directly on the
number schema after coercion, ensuring `.gte` is called on a proper number
schema as intended by the zod library.
reportContractDeployed({ | ||
address: contractAddr, | ||
chainId: walletChain.id, | ||
metadataUri: metadata.metadataUri, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Do not let analytics failures flag the deployment as failed.
reportContractDeployed
runs inside the same try
block that gates contract deployment; if it throws (e.g. because of later schema-validation), the whole deployment flow is treated as an error. Wrap it in its own try…catch
or make the helper swallow errors.
- reportContractDeployed({
- address: contractAddr,
- chainId: walletChain.id,
- });
+ try {
+ reportContractDeployed({
+ address: contractAddr,
+ chainId: walletChain.id,
+ });
+ } catch {
+ // non-blocking – analytics failure should not disrupt UX
+ }
📝 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.
reportContractDeployed({ | |
address: contractAddr, | |
chainId: walletChain.id, | |
metadataUri: metadata.metadataUri, | |
}); | |
try { | |
reportContractDeployed({ | |
address: contractAddr, | |
chainId: walletChain.id, | |
}); | |
} catch { | |
// non-blocking – analytics failure should not disrupt UX | |
} |
🤖 Prompt for AI Agents
In
apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
around lines 648 to 651, the call to reportContractDeployed is inside the main
try block for contract deployment, causing analytics errors to be treated as
deployment failures. To fix this, wrap the reportContractDeployed call in its
own try-catch block to catch and ignore any errors it throws, ensuring analytics
failures do not affect the deployment flow.
fd4f354
to
3ee08e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ BugBot reviewed your changes and found no bugs!
Was this report helpful? Give feedback by reacting with 👍 or 👎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🔭 Outside diff range comments (5)
apps/dashboard/.env.example (1)
105-112
:⚠️ Potential issueFix dotenv-linter violations: reorder keys and drop quotes
dotenv-linter
currently complains about:
NEXT_PUBLIC_ENGINE_CLOUD_URL
coming afterNEXT_PUBLIC_THIRDWEB_VAULT_URL
.- Quotes around the empty values.
NEXT_PUBLIC_POSTHOG_HOST
being afterNEXT_PUBLIC_POSTHOG_KEY
, and the quoted empty key.Failing to satisfy the linter blocks CI for every env-file change, so please align the keys alphabetically and remove superfluous quotes:
-# required for server wallet management -NEXT_PUBLIC_THIRDWEB_VAULT_URL="" -NEXT_PUBLIC_ENGINE_CLOUD_URL="" +# required for server wallet management +NEXT_PUBLIC_ENGINE_CLOUD_URL= +NEXT_PUBLIC_THIRDWEB_VAULT_URL= # PostHog setup -NEXT_PUBLIC_POSTHOG_KEY="" -NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com +# Host must precede Key (dotenv-linter) and match the client code +NEXT_PUBLIC_POSTHOG_HOST=https://us.posthog.com +NEXT_PUBLIC_POSTHOG_KEY=🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 106-106: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx (1)
33-47
: 🛠️ Refactor suggestion
trackingLabel
is now dead code – remove prop & usages
CardLink
no longer performs any tracking, yet the prop is still declared and passed from every call-site. This leaves:
- Unused props → TypeScript “unused” warnings in strict settings.
- Future confusion about whether tracking still happens.
Minimal clean-up:
- <CardLink - title="Create Coin" - description="Launch your own ERC-20 coin" - href={`/team/${props.teamSlug}/${props.projectSlug}/assets/create/token`} - icon={CoinsIcon} - trackingLabel="create-token" - /> + <CardLink + title="Create Coin" + description="Launch your own ERC-20 coin" + href={`/team/${props.teamSlug}/${props.projectSlug}/assets/create/token`} + icon={CoinsIcon} + />and in
CardLink
:- trackingLabel: string; + /* removed tracking */Repeat for the other two invocations.
If analytics will be re-introduced via the new typed helpers, wire them up directly instead of keeping this stale prop.
apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx (1)
47-51
: 🛠️ Refactor suggestion
trackingCategory
/trackingLabel
are now dead-code – remove to avoid API driftBoth props were used only by the removed PostHog
TrackedLinkTW
. Keeping them in the public type misleads call-sites and bloats the bundle with unused strings.- trackingCategory: string; - trackingLabel: string; + /* legacy-tracking props removed */apps/dashboard/src/components/cmd-k-search/index.tsx (1)
36-52
: 🛠️ Refactor suggestion
queryClient
parameter is dead code
contractTypesenseSearchQuery
receivesqueryClient
but never uses it, so every render allocates an ignored argument.-function contractTypesenseSearchQuery( - searchQuery: string, - queryClient: QueryClient, -) { +function contractTypesenseSearchQuery(searchQuery: string) {Update the call-sites accordingly:
-const typesenseSearchQuery = useQuery( - contractTypesenseSearchQuery(debouncedSearchValue, queryClient), -); +const typesenseSearchQuery = useQuery( + contractTypesenseSearchQuery(debouncedSearchValue), +);Removes an unnecessary dependency and lets TypeScript catch accidental misuse.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/components/delegate-button.tsx (1)
32-34
:⚠️ Potential issueLogic hides the button even when zero tokens are delegated
tokensDelegatedQuery.data
is aBigNumber
.
BigNumber(0)
is truthy, so the current check means the button disappears when the user has zero delegated tokens – exactly when they need it.-if (tokensDelegatedQuery.data || tokensDelegatedQuery.isPending) { +if ( + tokensDelegatedQuery.isPending || + (tokensDelegatedQuery.data && + !tokensDelegatedQuery.data.isZero()) // only hide when > 0 +) { return null; }Fixing this prevents an accidental dead-end in the UI.
♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/mint-supply-tab.tsx (1)
63-66
: Same logging concern as aboveForward the error to an app-level logger or toast instead of a bare
console.error
to avoid silent failures in production.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/platform-fees.tsx (1)
91-94
: Consistent error handlingAlign with the suggestion in other files: replace
console.error
with a structured logger / notification helper for observability and user feedback.
🧹 Nitpick comments (43)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/burn-tab.tsx (1)
107-110
: Typo in burn-confirmation copy
"remove them them from your wallet"
– duplicated word.- copies of the NFT will remove them them from your wallet. + copies of the NFT will remove them from your wallet.apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx (1)
80-83
: Prefer structured logging over bareconsole.error
console.error
is useful during development but tends to get lost in production environments and cannot be queried/alerted on.
If you have a centralised logger (e.g.logger.error(err, { context: … })
) or an error-reporting service, use that instead so the signal is not silently discarded.- onError: (error) => { - onError(error); - console.error(error); + onError: (error) => { + onError(error); // toast / UI feedback + logger.error(error, { // persisted log + component: "AddWebhookButton", + action: "createWebhook", + });apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/components/distribute-button.tsx (1)
56-59
: Replaceconsole.error
with a central loggerSame reasoning as for the webhook button: rely on structured, searchable logging instead of direct console output so that operational tooling can pick the failure up.
- onError: (error) => { - console.error(error); - onError(error); + onError: (error) => { + logger.error(error, { + component: "DistributeButton", + contract: contract.address, + }); + onError(error);apps/dashboard/src/app/(app)/get-started/team/[team_slug]/select-plan/_components/plan-selector.tsx (1)
44-46
: Deduplicate hard-codedplanSKU
literalsThe same string literals are repeated for every plan.
Introduce a union/enum (type BillingPlan = "starter" | "growth" | …
) or reuse an existing constant so typos are impossible and refactors are centralised.- reportPlanSelected({ planSKU: "starter" }); + reportPlanSelected({ planSKU: BillingPlan.STARTER });This will also give you autocomplete & static-analysis support.
Also applies to: 61-63, 79-81, 96-98
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/webhooks/components/webhooks-table.tsx (1)
200-205
: Use structured logging for deletion failures
console.error
doesn’t surface in most production setups.
Pipe the error into your logging layer instead so failures deleting webhooks are discoverable.- onError: (error) => { - console.error(error); + onError: (error) => { + logger.error(error, { + component: "DeleteWebhookModal", + webhookId: webhook.id, + });apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx (1)
158-159
: Console-only error handling is acceptable; consider surfacing user feedback.Replacing analytics calls with
console.error
means failures are now invisible to the end-user unless they open DevTools. A toast (consistent with surrounding UX) or a generic error banner would keep the UI behaviour unchanged while still dropping analytics.apps/dashboard/src/tw-components/button.tsx (2)
132-144
: Duplicate per-component no-optrackEvent
– collapse into a single helper.Defining an identical noop in every tracked component bloats bundle size and adds ESLint suppressions. Export a shared helper (e.g.
noopTrackEvent
) and import it here instead.-// eslint-disable-next-line @typescript-eslint/no-unused-vars -const trackEvent = (..._args: unknown[]) => {}; +import { noopTrackEvent as trackEvent } from "@/analytics/track";(Repeat for
TrackedIconButton
.)
160-173
: Minor: onClick still builds an event object that is discarded.If analytics is truly removed, consider deleting the whole
onClick
wrapper to avoid useless allocations:- onClick={() => - trackEvent({ - category, - action: "click", - label, - }) - } + // analytics removed – plain clickapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/components/index.tsx (1)
82-84
: Log error once; avoid double reporting.
console.error(error)
is already invoked insideuseTxNotifications.onError
.
The additional call here logs the same error twice. Remove this line or the one inside the hook to keep logs clean.apps/dashboard/src/@/analytics/track/nft.ts (2)
9-12
: Consider.strict()
on the object schemaWithout
.strict()
Zod silently strips unknown keys, which might hide accidental payload mistakes.
Making the schema strict fails fast and surfaces bugs early.-const BaseNFTSchema = z.object({ +const BaseNFTSchema = z + .object({ address: EVMAddressSchema, chainId: EVMChainIdSchema, -}); + }) + .strict();
16-22
: Avoid sendingundefined
& accept numeric token IDs
- PostHog drops
undefined
values; cleaner to omit the field entirely.- On-chain IDs are numeric – allow
string | number
to avoid unnecessary casts.-export function reportNFTMinted( - payload: NFTBasePayload & { tokenId?: string }, -) { - __internal__reportEvent("nft minted", { - ...BaseNFTSchema.parse(payload), - tokenId: payload.tokenId, - }); +export function reportNFTMinted( + payload: NFTBasePayload & { tokenId?: string | number }, +) { + const props: Record<string, unknown> = BaseNFTSchema.parse(payload); + if (payload.tokenId !== undefined) { + props.tokenId = payload.tokenId; + } + __internal__reportEvent("nft minted", props); }apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/import-backend-wallet-button.tsx (1)
92-95
: Replace directconsole.error
with a centralized logger / toastUsing
console.error
in production UIs can leak PII and is hard to aggregate.
Prefer a scoped logger or the existing notification system so errors surface in monitoring.- onError: (error) => { - onError(error); - console.error(error); + onError: (error) => { + onError(error); + logger.error("engine.import-backend-wallet.failed", error); },(Assumes a
logger
utility is available; otherwise consider adding one.)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/royalties.tsx (1)
104-106
: Surface errors through user-facing notifications, notconsole.error
console.error
is invisible to most users and unobservable in error-tracking tools.
Leverage the existingonError
callback or a toast to give feedback and capture telemetry.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/transfer-tab.tsx (1)
72-80
: Missed opportunity to hook into the new analytics helpers.
trackEvent
calls were dropped and replaced withconsole.error
.
If transfer events are still valuable, consider emitting a typed event via the new analytics helpers (e.g.reportNFTTransferred
/reportTokenTransferred
) inside theonSuccess
/onError
callbacks.This keeps observability parity with the old implementation while benefiting from the new schema-validated pipeline.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx (1)
1-4
: Import path nitpick
reportNFTMinted
is imported from the root@/analytics/track
, which re-exports many helpers.
Importing directly from@/analytics/track/nft
would make tree-shaking slightly more effective and avoids dragging unrelated helpers into the bundle.-import { reportNFTMinted } from "@/analytics/track"; +import { reportNFTMinted } from "@/analytics/track/nft";apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/mint-button.tsx (1)
1-4
: Same tree-shaking nitpick as aboveImporting the granular helper avoids bundling the full
track
barrel.-import { reportTokenMinted } from "@/analytics/track"; +import { reportTokenMinted } from "@/analytics/track/token";apps/dashboard/src/@/components/ui/NavLink.tsx (1)
27-28
: No-op tracking stub may mask missing analytics and leaves dead prop API
track
is now a silent no-op, yet the component still exposes atracking
prop and dutifully calls the stub.
If analytics are truly removed, consider deleting the prop (and the call) to avoid:
- Dead code that is never executed.
- A misleading API surface that suggests events are still emitted.
- An unnecessary runtime function allocation on every render.
- if (props.tracking) { - track({ - category: props.tracking.category, - action: props.tracking.action, - label: props.tracking.label, - url: props.href, - }); - } + // analytics removed – drop legacy tracking branchAlternatively, wire this to the new centralised analytics helpers rather than a no-op.
apps/dashboard/src/components/notices/AnnouncementBanner.tsx (1)
6-6
: Use the shared Link wrapper for consistent styling / behaviourEverywhere else the codebase imports your custom
tw-components/link
abstraction.
Usingnext/link
directly breaks visual/behavioural consistency (focus ring, smooth-scroll, etc.).
Swap to the sharedLink
unless there is a specific reason not to.apps/dashboard/src/tw-components/link.tsx (1)
71-76
: Left-over analytics stub inflates bundle and confuses consumers
trackEvent
is declared but guaranteed to be a no-op, yet the component still fires it on every click.
Given the new central analytics layer, either:
- Delegate to
__internal__reportEvent
, or- Remove the tracking props from
TrackedLink
entirely.At minimum, drop the unused spread parameter to silence eslint without disabling the rule:
-// eslint-disable-next-line @typescript-eslint/no-unused-vars -const trackEvent = (..._args: unknown[]) => {}; +const trackEvent = () => {};apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/relayers-table.tsx (1)
262-264
: Replace bareconsole.error
with structured error handling
useTxNotifications
already surfaces the error to the user and probably logs it internally.
Logging the full error object twice adds little value and may unintentionally leak sensitive information (e.g. auth token in stack-traces) to the browser console.- onError(error); - console.error(error); + onError(error); // notifications + internal loggingSame for the revoke flow a few lines below.
If you still need console output, prefer a redacted/serialised message:
console.error("updateRelayer failed:", error?.message);Also applies to: 374-377
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx (1)
123-127
: Guard analytics call & enrich payloadA failing PostHog/network request inside
reportTokenBurned
would currently reject theonSuccess
promise chain and surface as an uncaught error in the console.
Wrap the call or makereportTokenBurned
resilient:-reportTokenBurned({ - address: contract.address, - chainId: contract.chain.id, - quantity: data.amount, -}); +try { + reportTokenBurned({ + address: contract.address, + chainId: contract.chain.id, + quantity: data.amount, + walletAddress: address, // optional but valuable + }); +} catch (_) { + /* non-blocking – ignore analytics failure */ +}Adds two benefits:
- Prevents UI breakage if analytics layer is offline.
- Captures the burner’s wallet for richer insights.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx (1)
315-315
: Duplicate error surface & potential PII leak
toast.error
already conveys the failure to the user. Logging the raw error object twice may expose backend responses or tokens in plain text.If console logging is desired, redact first:
console.error("updateProject failed:", err?.message);Same for the delete flow.
Also applies to: 946-947
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/create-wallet-credential-button.tsx (1)
24-36
: Avoid leaking raw error objects to the browser console
console.error(error);
may expose implementation details (e.g. stack traces, request payloads) to end-users via DevTools. Consider routing unexpected errors through a central logger (e.g. Sentry) and/or printing a redacted string in production builds.- console.error(error); + if (process.env.NODE_ENV === "development") { + // eslint-disable-next-line no-console + console.error(error); + } + captureException?.(error); // your centralized loggerapps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/add-relayer-button.tsx (1)
118-126
: Redundant error handling path
onError
already callsonError(error)
fromuseTxNotifications
, so the additionalconsole.error(error);
is probably superfluous and clutters logs.- onError: (error) => { - onError(error); - console.error(error); - }, + onError,apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/create-backend-wallet-button.tsx (1)
71-79
: Prefer surfacing the specific failure reason to the toastOnly a generic “Failed to create wallet” is shown to users. You already have the
error
object here—forwardingerror.message
(or a safe fallback) will make troubleshooting easier.toast.promise(promise, { success: "Wallet created successfully", - error: "Failed to create wallet", + error: (err) => + typeof err === "object" && err !== null && "message" in err + ? (err as { message: string }).message + : "Failed to create wallet", });apps/dashboard/src/components/pay/RouteDiscovery.tsx (1)
63-75
: Handle & surface API error detailsThe failure toast always shows the same static message. If the API returns a meaningful error (e.g. 409 duplicate, 400 bad address), exposing it will shorten support cycles.
- onError: () => { - toast.error("Token submission failed!", { - description: - "Please double check the network and token address. If issues persist, please reach out to our support team.", - }); - }, + onError: (err: unknown) => { + const description = + typeof err === "object" && err && "message" in err + ? (err as { message: string }).message + : "Please double-check the network and token address. If issues persist, contact support."; + toast.error("Token submission failed!", { description }); + },apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx (1)
86-92
: Consolidate error reporting
airdropNotifications.onError(err)
is already invoked in the outercatch
. The additionalconsole.error(error);
inside the mutation callback duplicates logging and may be noisy.- onError: (error) => { - console.error(error); - }, + onError: () => { + /* rely on airdropNotifications.onError in the enclosing catch */ + },apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx (1)
106-113
: Addrel="noopener noreferrer"
whentarget="_blank"
& prefer plain<a>
for external links
next/link
renders an<a>
element inside the React tree.
You can safely passtarget
, but omittingrel
opens a small security hole (tab-nabbing).
Also, whentarget="_blank"
is used the link is external by definition, so theasChild
pattern could simply render a native<a>
and skipnext/link
altogether.-<Link - href={props.cta.link} - target={props.cta.target} - className="flex items-center" -> +<Link + href={props.cta.link} + target={props.cta.target} + rel={props.cta.target === "_blank" ? "noopener noreferrer" : undefined} + className="flex items-center" +>apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx (1)
425-435
: Redundant no-oponError
handlerThe auction path passes
onError: () => { // No error handling needed for auction },An empty handler is equivalent to omitting the option and unnecessarily clutters the call-site. Simply remove
onError
– the surroundingtry/catch
already handles failures.apps/dashboard/src/components/cmd-k-search/index.tsx (1)
61-63
:queryClient
instance now unusedAfter removing the argument above, the
const queryClient = useQueryClient();
(line 61) is no longer referenced – delete to avoid the unused-var lint error.apps/dashboard/src/app/(app)/login/onboarding/LinkWalletPrompt/LinkWalletPrompt.tsx (2)
61-67
: External link missingrel="noopener noreferrer"
Opening external targets in a new tab (
target="_blank"
) without arel
attribute exposes the page towindow.opener
attacks. Add the recommended attributes:-<Link … target="_blank"> +<Link … target="_blank" rel="noopener noreferrer">[security]
26-35
: Consider capturingaccountAddress
in analytics payload
reportAccountWalletLinkRequested
only sends{ email }
.
AddingaccountAddress
(already available viaprops.accountAddress
) would give Product richer attribution and eliminate the need to correlate data later.apps/dashboard/src/@/analytics/track/README.md (2)
32-38
: Specify language for fenced block (markdown-lint MD040)Add a language identifier so tooling renders the directory tree properly:
-``` +```text track/ # ← you are here ├─ __internal.ts # low-level wrapper around posthog.capture (do NOT use) …<details> <summary>🧰 Tools</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> 32-32: Fenced code blocks should have a language specified null (MD040, fenced-code-language) </details> </details> --- `102-106`: **Minor grammar – missing comma before coordinating conjunction** > *Avoid calling PostHog directly** – always go through …* Insert a comma before “so” to satisfy LanguageTool COMMA_COMPOUND_SENTENCE_2 rule: ```diff -so we keep a single choke-point. +, so we keep a single choke-point.
apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.tsx (1)
59-64
: Hard-coded action strings invite typos
trackingAction
is compared to literal strings"confirmEmail"
/"confirmLinkWallet"
.
Define a union/enum instead to gain compile-time safety:type TrackingAction = "confirmEmail" | "confirmLinkWallet"; … trackingAction: TrackingAction;Reduces the risk of silent analytics drops due to misspelling.
apps/dashboard/src/@/analytics/track/token.ts (2)
24-30
: Semantic nit – alias name misleads
TokenMintedPayload
is reused forreportTokenBurned
. Consider renaming to something neutral such asBaseTokenPayload
to improve readability and avoid future confusion.
32-37
: DRY opportunity
TokenTransferredSchema
duplicates theaddress
,chainId
,quantity
fields already defined inBaseTokenSchema
. You can compose the schemas instead:-const TokenTransferredSchema = z.object({ - address: EVMAddressSchema, - chainId: EVMChainIdSchema, - quantity: TokenAmountSchema, - to: EVMAddressSchema, -}); +const TokenTransferredSchema = BaseTokenSchema.extend({ + to: EVMAddressSchema, +});Keeps one source of truth and reduces maintenance overhead.
apps/dashboard/src/@/analytics/track/onboarding.ts (1)
50-55
: Consider enum/union forplanSKU
planSKU
is passed as a raw string in multiple places. Define a union type orenum
("growth" | "scale" | "pro"
) once and reuse it to avoid typos and ease refactors.apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/InviteTeamMembers.tsx (2)
83-88
: Analytics event should be emitted only on successful inviteIf
props.inviteTeamMembers
throws, the event is silently skipped – fine – but any retry logic will record duplicates. Wrap withtry/catch
so failures are explicit and optionally track attempts vs successes.inviteTeamMembers={async (params) => { - const res = await props.inviteTeamMembers(params); - reportTeamInviteMembersSent({ inviteCount: params.length }); - return res; + try { + const res = await props.inviteTeamMembers(params); + reportTeamInviteMembersSent({ inviteCount: params.length }); + return res; + } catch (err) { + // Optionally: __internal__reportEvent('team invite members failed', …); + throw err; + } }}
159-160
: Duplicate literals – extractplanSKU
constants
"growth"
,"scale"
,"pro"
are repeated inline. Export them from@/analytics/track
(or a sharedpricing.ts
) to prevent drift between UI & analytics.Also applies to: 177-178, 194-195
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/primary-sale.tsx (2)
46-46
: Remove stray diff-only lineThe sole
~
-annotated line is now an empty line that serves no purpose and triggers most linters’ “no-trailing-whitespace / no-useless-blank-line” rules. Delete it to keep the file clean.- +
91-93
: Prefer centralised error reporting overconsole.error
console.error(error)
is fine for local debugging, but for production we’ll lose visibility (users rarely share console dumps).
Consider funnelling the error into the new analytics / telemetry layer (or Sentry, LogRocket, etc.) so failures are observable in-flight.- console.error(error); + // Forward to observability pipeline + reportError("primary_sale_update_failed", error); onError(error);If no reporting helper exists yet, wrap one in the new analytics client for consistency.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/components/delegate-button.tsx (1)
47-48
: Send errors to telemetry rather than just the consoleSame observation as in
primary-sale.tsx
:console.error
is ephemeral.
Pipe the exception into whatever central logging / analytics mechanism replaces PostHog to retain visibility.- console.error(error); + reportError("delegate_tokens_failed", error);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (169)
apps/dashboard/.env.example
(1 hunks)apps/dashboard/.eslintrc.js
(2 hunks)apps/dashboard/instrumentation-client.ts
(1 hunks)apps/dashboard/knip.json
(1 hunks)apps/dashboard/next.config.ts
(2 hunks)apps/dashboard/package.json
(1 hunks)apps/dashboard/src/@/analytics/dashboard.client.tsx
(1 hunks)apps/dashboard/src/@/analytics/track.ts
(1 hunks)apps/dashboard/src/@/analytics/track/README.md
(1 hunks)apps/dashboard/src/@/analytics/track/__internal.ts
(1 hunks)apps/dashboard/src/@/analytics/track/contract.ts
(1 hunks)apps/dashboard/src/@/analytics/track/marketplace.ts
(1 hunks)apps/dashboard/src/@/analytics/track/nft.ts
(1 hunks)apps/dashboard/src/@/analytics/track/onboarding.ts
(1 hunks)apps/dashboard/src/@/analytics/track/schemas.ts
(1 hunks)apps/dashboard/src/@/analytics/track/token.ts
(1 hunks)apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx
(2 hunks)apps/dashboard/src/@/components/blocks/pricing-card.tsx
(0 hunks)apps/dashboard/src/@/components/ui/NavLink.tsx
(1 hunks)apps/dashboard/src/@/components/ui/tracked-link.tsx
(2 hunks)apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/NextSteps.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/PayModal.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx
(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/burn-tab.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/claim-tab.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/mint-supply-tab.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/transfer-tab.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/batch-lazy-mint-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/lazy-mint-form.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/reveal-button.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/components/index.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/components/delegate-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/components/proposal-button.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/platform-fees.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/primary-sale.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/royalties.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/components/distribute-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/claim-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/mint-button.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/transfer-button.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/profile/[addressOrEns]/components/PublishedContractTable.tsx
(1 hunks)apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
(3 hunks)apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx
(0 hunks)apps/dashboard/src/app/(app)/account/contracts/_components/DeployViaCLIOrImportCard.tsx
(0 hunks)apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/components/TeamPlanBadge.tsx
(0 hunks)apps/dashboard/src/app/(app)/get-started/team/[team_slug]/select-plan/_components/plan-selector.tsx
(6 hunks)apps/dashboard/src/app/(app)/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/login/onboarding/LinkWalletPrompt/LinkWalletPrompt.stories.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/LinkWalletPrompt/LinkWalletPrompt.tsx
(3 hunks)apps/dashboard/src/app/(app)/login/onboarding/LoginOrSignup/LoginOrSignup.stories.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/LoginOrSignup/LoginOrSignup.tsx
(2 hunks)apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.stories.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.tsx
(3 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding-ui.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.stories.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
(2 hunks)apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/InviteTeamMembers.stories.tsx
(0 hunks)apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/InviteTeamMembers.tsx
(6 hunks)apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/team-onboarding.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/invite-team-members-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/step-card.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx
(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx
(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/send-test-tx.client.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/overview/engine-instances-table.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/access-tokens-table.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/add-access-token-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/add-keypair-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/keypairs-table.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/add-admin-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/admins-table.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/circle-config.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/kms-aws-config.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/kms-gcp-config.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/contract-subscriptions/components/add-contract-subscription-button.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/contract-subscriptions/components/contract-subscriptions-table.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/backend-wallets-table.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/create-backend-wallet-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/import-backend-wallet-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/add-relayer-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/relayers-table.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/create-wallet-credential-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/edit-wallet-credential-button.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/webhooks/components/add-webhook-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/webhooks/components/webhooks-table.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
(3 hunks)apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
(0 hunks)apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
(2 hunks)apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChat.tsx
(0 hunks)apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx
(0 hunks)apps/dashboard/src/app/nebula-app/(app)/components/Swap/common.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/layout.tsx
(1 hunks)apps/dashboard/src/app/pay/components/client/Providers.client.tsx
(1 hunks)apps/dashboard/src/components/buttons/MismatchButton.tsx
(0 hunks)apps/dashboard/src/components/cmd-k-search/index.tsx
(4 hunks)apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx
(0 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
(3 hunks)apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx
(0 hunks)apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx
(1 hunks)apps/dashboard/src/components/embedded-wallets/Configure/InAppWalletSettingsUI.stories.tsx
(0 hunks)apps/dashboard/src/components/embedded-wallets/Configure/index.tsx
(4 hunks)apps/dashboard/src/components/notices/AnnouncementBanner.tsx
(2 hunks)apps/dashboard/src/components/onboarding/ApplyForOpCreditsForm.tsx
(0 hunks)apps/dashboard/src/components/onboarding/ApplyForOpCreditsModal.tsx
(0 hunks)apps/dashboard/src/components/pay/PayConfig.tsx
(0 hunks)apps/dashboard/src/components/pay/RouteDiscovery.tsx
(1 hunks)apps/dashboard/src/components/settings/Account/Billing/CreditsItem.tsx
(0 hunks)apps/dashboard/src/components/settings/Account/Notifications.tsx
(1 hunks)apps/dashboard/src/components/settings/ApiKeys/Create/index.tsx
(1 hunks)apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
(0 hunks)apps/dashboard/src/components/smart-wallets/SponsorshipPolicies/index.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
(0 hunks)apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
(0 hunks)apps/dashboard/src/hooks/analytics/useTrack.ts
(0 hunks)apps/dashboard/src/lib/posthog/Posthog.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/dashboard/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/dashboard/src/tw-components/button.tsx
(2 hunks)apps/dashboard/src/tw-components/link.tsx
(2 hunks)apps/dashboard/src/utils/errorParser.tsx
(0 hunks)apps/playground-web/instrumentation-client.ts
(1 hunks)apps/playground-web/knip.json
(1 hunks)apps/playground-web/next.config.mjs
(1 hunks)apps/playground-web/package.json
(1 hunks)apps/playground-web/src/app/layout.tsx
(1 hunks)apps/playground-web/src/lib/posthog/Posthog.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/playground-web/src/lib/posthog/PosthogPageView.tsx
(0 hunks)apps/portal/instrumentation-client.ts
(1 hunks)apps/portal/knip.json
(1 hunks)apps/portal/next.config.mjs
(1 hunks)apps/portal/package.json
(1 hunks)apps/portal/src/app/layout.tsx
(1 hunks)apps/portal/src/components/AI/chat.tsx
(1 hunks)apps/portal/src/components/others/Feedback.tsx
(1 hunks)apps/portal/src/lib/env.ts
(0 hunks)apps/portal/src/lib/posthog/Posthog.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
(0 hunks)apps/portal/src/lib/posthog/PosthogPageView.tsx
(0 hunks)
💤 Files with no reviewable changes (65)
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.stories.tsx
- apps/dashboard/src/app/(app)/login/onboarding/LoginOrSignup/LoginOrSignup.stories.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx
- apps/dashboard/src/components/embedded-wallets/Configure/InAppWalletSettingsUI.stories.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/send-test-tx.client.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/components/proposal-button.tsx
- apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/InviteTeamMembers.stories.tsx
- apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.stories.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/overview/engine-instances-table.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
- apps/dashboard/src/app/(app)/login/onboarding/LinkWalletPrompt/LinkWalletPrompt.stories.tsx
- apps/dashboard/src/app/(app)/components/TeamPlanBadge.tsx
- apps/dashboard/src/components/settings/Account/Billing/CreditsItem.tsx
- apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx
- apps/dashboard/src/app/(app)/account/contracts/_components/DeployViaCLIOrImportCard.tsx
- apps/dashboard/src/components/smart-wallets/SponsorshipPolicies/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifierServer.tsx
- apps/dashboard/src/utils/errorParser.tsx
- apps/portal/src/lib/env.ts
- apps/playground-web/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChat.tsx
- apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx
- apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx
- apps/dashboard/src/@/components/blocks/pricing-card.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/step-card.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/claim-tab.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/reveal-button.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/keypairs-table.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/kms-gcp-config.tsx
- apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/circle-config.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/access-tokens-table.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx
- apps/dashboard/src/components/onboarding/ApplyForOpCreditsForm.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx
- apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/admins-table.tsx
- apps/dashboard/src/components/pay/PayConfig.tsx
- apps/portal/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx
- apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/configuration/components/kms-aws-config.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx
- apps/portal/src/lib/posthog/PosthogHeadSetup.tsx
- apps/dashboard/src/components/buttons/MismatchButton.tsx
- apps/portal/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/components/onboarding/ApplyForOpCreditsModal.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/contract-subscriptions/components/contract-subscriptions-table.tsx
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding-ui.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx
- apps/dashboard/src/components/wallets/PosthogIdentifier.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/edit-wallet-credential-button.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/contract-subscriptions/components/add-contract-subscription-button.tsx
- apps/playground-web/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/Posthog.tsx
- apps/dashboard/src/lib/posthog/PosthogPageView.tsx
- apps/dashboard/src/hooks/analytics/useTrack.ts
✅ Files skipped from review due to trivial changes (19)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/batch-lazy-mint-button.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/NextSteps.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/add-access-token-button.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/backend-wallets-table.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/lazy-mint-form.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/add-admin-button.tsx
- apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/team-onboarding.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/claim-button.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
- apps/dashboard/src/components/settings/ApiKeys/Create/index.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/add-keypair-button.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
- apps/dashboard/src/components/embedded-wallets/Configure/index.tsx
- apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/Swap/common.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx
🚧 Files skipped from review as they are similar to previous changes (32)
- apps/dashboard/knip.json
- apps/portal/knip.json
- apps/portal/src/components/others/Feedback.tsx
- apps/dashboard/src/app/pay/components/client/Providers.client.tsx
- apps/dashboard/src/app/(app)/login/onboarding/account-onboarding.tsx
- apps/playground-web/knip.json
- apps/playground-web/package.json
- apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx
- apps/dashboard/src/app/bridge/components/client/Providers.client.tsx
- apps/portal/package.json
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
- apps/dashboard/package.json
- apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx
- apps/dashboard/.eslintrc.js
- apps/dashboard/src/app/nebula-app/layout.tsx
- apps/dashboard/src/@/analytics/track/__internal.ts
- apps/playground-web/instrumentation-client.ts
- apps/dashboard/instrumentation-client.ts
- apps/dashboard/src/@/analytics/dashboard.client.tsx
- apps/dashboard/src/app/(app)/layout.tsx
- apps/playground-web/src/app/layout.tsx
- apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header-logged-in.client.tsx
- apps/dashboard/next.config.ts
- apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx
- apps/dashboard/src/@/analytics/track/contract.ts
- apps/portal/instrumentation-client.ts
- apps/dashboard/src/@/analytics/track.ts
- apps/portal/src/app/layout.tsx
- apps/portal/next.config.mjs
- apps/portal/src/components/AI/chat.tsx
- apps/playground-web/next.config.mjs
- apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
🧰 Additional context used
🧬 Code Graph Analysis (15)
apps/dashboard/src/app/(app)/get-started/team/[team_slug]/select-plan/_components/plan-selector.tsx (1)
apps/dashboard/src/@/analytics/track/onboarding.ts (2)
reportPlanSelected
(50-52)reportPlanSelectSkipped
(54-56)
apps/dashboard/src/components/notices/AnnouncementBanner.tsx (1)
apps/dashboard/src/tw-components/link.tsx (1)
Link
(33-56)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/mint-button.tsx (1)
apps/dashboard/src/@/analytics/track/token.ts (1)
reportTokenMinted
(24-26)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/transfer-button.tsx (1)
apps/dashboard/src/@/analytics/track/token.ts (1)
reportTokenTransferred
(41-46)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx (1)
apps/dashboard/src/@/analytics/track/token.ts (1)
reportTokenBurned
(28-30)
apps/dashboard/src/@/analytics/track/nft.ts (2)
apps/dashboard/src/@/analytics/track/schemas.ts (2)
EVMAddressSchema
(9-13)EVMChainIdSchema
(16-20)apps/dashboard/src/@/analytics/track/__internal.ts (1)
__internal__reportEvent
(12-23)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx (1)
apps/dashboard/src/@/analytics/track/nft.ts (1)
reportNFTMinted
(16-23)
apps/dashboard/src/app/(app)/login/onboarding/team-onboarding/InviteTeamMembers.tsx (1)
apps/dashboard/src/@/analytics/track/onboarding.ts (3)
reportTeamInviteMembersSent
(36-40)reportTeamInviteMembersSkipped
(42-44)reportPlanSelected
(50-52)
apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx (1)
apps/dashboard/src/tw-components/link.tsx (1)
Link
(33-56)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx (1)
apps/dashboard/src/@/analytics/track/marketplace.ts (1)
reportListingCreated
(18-23)
apps/dashboard/src/app/(app)/login/onboarding/LoginOrSignup/LoginOrSignup.tsx (1)
apps/dashboard/src/@/analytics/track/onboarding.ts (1)
reportAccountEmailVerificationRequested
(7-13)
apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.tsx (1)
apps/dashboard/src/@/analytics/track/onboarding.ts (2)
reportAccountEmailVerified
(15-20)reportAccountWalletLinked
(28-30)
apps/dashboard/src/@/analytics/track/schemas.ts (1)
packages/thirdweb/src/exports/thirdweb.ts (1)
isAddress
(308-308)
apps/dashboard/src/@/analytics/track/token.ts (2)
apps/dashboard/src/@/analytics/track/schemas.ts (2)
EVMAddressSchema
(9-13)EVMChainIdSchema
(16-20)apps/dashboard/src/@/analytics/track/__internal.ts (1)
__internal__reportEvent
(12-23)
apps/dashboard/src/@/analytics/track/onboarding.ts (1)
apps/dashboard/src/@/analytics/track/__internal.ts (1)
__internal__reportEvent
(12-23)
🪛 dotenv-linter (3.3.0)
apps/dashboard/.env.example
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
[warning] 107-107: [UnorderedKey] The NEXT_PUBLIC_ENGINE_CLOUD_URL key should go before the NEXT_PUBLIC_THIRDWEB_VAULT_URL key
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
[warning] 111-111: [UnorderedKey] The NEXT_PUBLIC_POSTHOG_HOST key should go before the NEXT_PUBLIC_POSTHOG_KEY key
🪛 LanguageTool
apps/dashboard/src/@/analytics/track/README.md
[uncategorized] ~85-~85: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...(one directory up) and add a star-export so the helpers are surfaced at the pack...
(COMMA_COMPOUND_SENTENCE_2)
🪛 markdownlint-cli2 (0.17.2)
apps/dashboard/src/@/analytics/track/README.md
32-32: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Build Packages
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (15)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx (1)
94-99
: Stray blank diff line – safe to squashThe only change in this hunk is a blank line (line 97) that was marked as modified.
Unless this was intentional for readability, consider squashing it out to keep the history noise-free.apps/dashboard/src/app/(app)/get-started/team/[team_slug]/select-plan/_components/plan-selector.tsx (2)
3-4
: 👍 Moving to explicit, typed analytics callsImporting the typed helpers from
@/analytics/track
keeps the event surface consistent and prevents ad-hoc strings.
Looks good.
122-124
: Nit: fire-and-forget telemetry – consider awaiting?
reportPlanSelectSkipped()
is presumably synchronous, but if it becomes async later the event may be lost when the navigation triggers.
Optionally make it return a promise andawait
it before routing.apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/invite-team-members-button.tsx (1)
9-14
: Tracking removal looks fine – confirm no stale props remain.All tracking code was stripped, but the component still receives plain
props
that were previously forwarded to analytics. Double-check no caller passes “tracking-related” props that are now unused.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/transfer-button.tsx (2)
3-4
: Import path pinned to barrel – verify tree-shaking.
@/analytics/track
re-exports many helpers; importing from the barrel can pull more code into the client bundle than importingtoken.ts
directly. If bundle size matters, switch to
@/analytics/track/token
.
119-124
: Type consistency between analytics payload and form values.
quantity: d.amount
is a string from<Input>
while most on-chain helpers & zod schemas usebigint
ornumber
. IfTokenTransferredSchema
expects a numeric type this will throw at runtime and skip analytics.apps/dashboard/src/app/(app)/(dashboard)/profile/[addressOrEns]/components/PublishedContractTable.tsx (1)
136-138
: Dependency array update looks correct – just double-checkTrackedLinkTW
still emits analytics events.
trackEvent
has been removed from the table column factory and from the dependency list, which is expected after the PostHog migration.
The only remaining analytics-related element inside the table isTrackedLinkTW
; make sure that this component is now wired to the new analytics layer (or is a harmless no-op) so that clicking the audit badge still gets captured (if desired).apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/mint-button.tsx (1)
81-85
: Quantity type – ensure it matches the schema.
d.amount
is a string (because it comes straight from a text input).
IfreportTokenMinted
’s schema expects anumber
orbigint
, parsing should happen before the call to avoid runtime validation errors.- quantity: d.amount, + quantity: BigInt(d.amount), // or Number(d.amount) depending on schemaapps/dashboard/src/components/settings/Account/Notifications.tsx (1)
37-43
: LGTM – tracking removed cleanlyThe callbacks now exclusively trigger user-visible notifications without leaking errors to analytics; this aligns with the new minimal tracking stance.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/metadata.tsx (1)
178-180
: Error flow now only logs – consider surfacing to user or analyticsSwitching from tracked errors to
console.error
is fine for local debugging but loses both:
- Structured telemetry for failure rates.
- Feedback to users in production if the console isn’t visible.
If analytics are intentionally removed, ensure UX still conveys the failure (toast, inline message).
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx (1)
3-3
: Import path is fine – just ensure treeshakingNo issues; webpack/next-tree-shaking should drop unused helpers from
@/analytics/track
.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/PayModal.tsx (1)
38-43
: Missed opportunity to capture purchase analyticsPurchases (especially successful ones) are core business metrics.
Consider emitting a dedicated event (e.g.reportPayPurchase
) in both the crypto & fiat paths rather than dropping tracking entirely. This keeps the refactor consistent with the rest of the new type-safe analytics helpers.No action required if omission is deliberate.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx (1)
34-40
: Consider awaitingmutateAsync
to propagate failuresBy not awaiting
cancelQuery.mutateAsync(transaction)
the returned promise is only consumed bytoast.promise
.
If the mutation rejects beforetoast.promise
attaches (edge-race) or another part of the call-chain relies on the returned promise, the error will be lost.-const promise = cancelQuery.mutateAsync(transaction); +const promise = await cancelQuery.mutateAsync(transaction);Wrap the
onClick
handler inasync () => { … }
to keep behaviour unchanged while guaranteeing proper error surfacing.apps/dashboard/src/app/(app)/login/onboarding/LoginOrSignup/LoginOrSignup.tsx (1)
45-52
: 👍 Good swap to typed event reporterReplacing the generic tracking prop with
reportAccountEmailVerificationRequested
makes the side-effect explicit and type-safe. No further concerns here.apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx (1)
62-100
: Async chain is correct butcontractAddressRef
may stayundefined
on failureIf
deployERC20Contract
rejects,contractAddressRef.current
remainsundefined
yet subsequent steps (airdropTokens
,mintTokens
,setClaimConditions
) may still be invoked from the UI, causing opaque “No contract address” errors.Consider short-circuiting the wizard upon deployment failure or only enabling following steps after a successful deploy.
* NFT-related analytics helpers (ERC721 & ERC1155 non-fungible). | ||
*/ | ||
|
||
import { z } from "zod/v4-mini"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unpublished import path will break compilation
"zod/v4-mini"
is not part of the public Zod distribution (current major is v3).
Importing through this path will throw Cannot find module at build time unless a custom alias is configured.
Use the canonical package entry instead.
-import { z } from "zod/v4-mini";
+import { z } from "zod";
📝 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.
import { z } from "zod/v4-mini"; | |
// apps/dashboard/src/@/analytics/track/nft.ts | |
-import { z } from "zod/v4-mini"; | |
+import { z } from "zod"; |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/nft.ts at line 5, the import path
"zod/v4-mini" is invalid and will cause build errors because it is not part of
the public Zod package. Replace this import with the standard public entry "zod"
to ensure the module is found and the code compiles correctly.
reportNFTMinted({ | ||
address: contract.address, | ||
chainId: contract.chain.id, | ||
tokenId: undefined, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Pass back the minted tokenId when available.
tokenId
is currently reported as undefined
.
erc721MintTo
/ erc1155MintTo
both return the minted tokenId in their receipt (or it can be extracted from logs).
Populating this field increases the value of the telemetry and prevents nullable schema columns downstream.
- tokenId: undefined,
+ tokenId: mintedTokenId, // derive from the tx receipt
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx
around lines 120 to 124, the reportNFTMinted call sets tokenId to undefined,
which loses valuable telemetry data. Update the code to extract the minted
tokenId from the receipt returned by erc721MintTo or erc1155MintTo (or from
their logs) and pass this tokenId to reportNFTMinted instead of undefined to
ensure accurate reporting and avoid nullable schema columns downstream.
<Link | ||
href={props.href} | ||
category="announcement" | ||
label={props.trackingLabel} | ||
target={props.href.startsWith("http") ? "_blank" : undefined} | ||
className="ontainer flex cursor-pointer items-center gap-2 lg:justify-center " | ||
> | ||
<span className="inline-block font-medium leading-normal hover:underline"> | ||
{props.label} | ||
</span> | ||
</TrackedLinkTW> | ||
</Link> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security + typo: add rel="noopener noreferrer"
and fix className
- External links opened with
target="_blank"
should also specify
rel="noopener noreferrer"
to prevent the new page from gaining a
reference towindow.opener
. className="ontainer ..."
is missing the leading c (container
).
- <Link
- href={props.href}
- target={props.href.startsWith("http") ? "_blank" : undefined}
- className="ontainer flex cursor-pointer items-center gap-2 lg:justify-center "
+ <Link
+ href={props.href}
+ target={props.href.startsWith("http") ? "_blank" : undefined}
+ rel={props.href.startsWith("http") ? "noopener noreferrer" : undefined}
+ className="container flex cursor-pointer items-center gap-2 lg:justify-center "
>
📝 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.
<Link | |
href={props.href} | |
category="announcement" | |
label={props.trackingLabel} | |
target={props.href.startsWith("http") ? "_blank" : undefined} | |
className="ontainer flex cursor-pointer items-center gap-2 lg:justify-center " | |
> | |
<span className="inline-block font-medium leading-normal hover:underline"> | |
{props.label} | |
</span> | |
</TrackedLinkTW> | |
</Link> | |
<Link | |
href={props.href} | |
target={props.href.startsWith("http") ? "_blank" : undefined} | |
rel={props.href.startsWith("http") ? "noopener noreferrer" : undefined} | |
className="container flex cursor-pointer items-center gap-2 lg:justify-center " | |
> | |
<span className="inline-block font-medium leading-normal hover:underline"> | |
{props.label} | |
</span> | |
</Link> |
🤖 Prompt for AI Agents
In apps/dashboard/src/components/notices/AnnouncementBanner.tsx around lines 22
to 30, fix the typo in className by changing "ontainer" to "container" and add
rel="noopener noreferrer" to the Link component when target="_blank" is set to
improve security for external links.
export function reportListingCreated(payload: ListingCreatedPayload) { | ||
__internal__reportEvent( | ||
"marketplace listing created", | ||
ListingCreatedSchema.parse(payload), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Prefer safeParse
to avoid throwing inside production builds
ListingCreatedSchema.parse
will throw on invalid payloads, crashing the caller.
Unless callers wrap this in try/catch, switch to safeParse
and early-return on failure:
-export function reportListingCreated(payload: ListingCreatedPayload) {
- __internal__reportEvent(
- "marketplace listing created",
- ListingCreatedSchema.parse(payload),
- );
+export function reportListingCreated(payload: ListingCreatedPayload) {
+ const res = ListingCreatedSchema.safeParse(payload);
+ if (!res.success) {
+ // option: report validation failure to Sentry / console
+ return;
+ }
+ __internal__reportEvent("marketplace listing created", res.data);
}
This protects production sessions from unexpected runtime exceptions.
📝 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.
export function reportListingCreated(payload: ListingCreatedPayload) { | |
__internal__reportEvent( | |
"marketplace listing created", | |
ListingCreatedSchema.parse(payload), | |
); | |
export function reportListingCreated(payload: ListingCreatedPayload) { | |
const res = ListingCreatedSchema.safeParse(payload); | |
if (!res.success) { | |
// option: report validation failure to Sentry / console | |
return; | |
} | |
__internal__reportEvent("marketplace listing created", res.data); | |
} |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/marketplace.ts around lines 18 to 22,
replace the use of ListingCreatedSchema.parse with
ListingCreatedSchema.safeParse to avoid throwing exceptions on invalid payloads.
Use safeParse to validate the payload, check if the parsing was successful, and
only call __internal__reportEvent if it was. If safeParse fails, return early to
prevent runtime exceptions in production.
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const trackEvent = (..._args: unknown[]) => {}; | ||
const { category, label, trackingProps, ...restProps } = props; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Stubbed trackEvent
is dead code – delete or re-wire
The no-op preserves the old API but:
- Creates false expectation that link clicks are tracked.
- Forces ESLint disable comments and an unused prop (
category
,label
,trackingProps
).
Unless re-connecting to the new analytics layer soon, remove the tracking facade and related props to keep the component lean.
-export type TrackedLinkProps = React.ComponentProps<typeof Link> & {
- category: string;
- label?: string;
- trackingProps?: Record<string, string>;
-};
+export type TrackedLinkProps = React.ComponentProps<typeof Link>;
...
- onClick={(e) => {
- trackEvent({ category, action: "click", label, ...trackingProps });
- props.onClick?.(e);
- }}
+ onClick={props.onClick}
Also applies to: 30-32
🤖 Prompt for AI Agents
In apps/dashboard/src/@/components/ui/tracked-link.tsx around lines 14 to 16 and
30 to 32, the trackEvent function is a no-op stub causing dead code and unused
props (category, label, trackingProps) with ESLint disables. Remove the
trackEvent function entirely along with the related props from the component's
props destructuring and usage to eliminate dead code and unused variables,
simplifying the component and removing the need for ESLint disable comments.
import { isAddress } from "thirdweb"; | ||
import { z } from "zod/v4-mini"; | ||
|
||
// --------------------------- | ||
// Shared Zod Schemas | ||
// --------------------------- | ||
|
||
/** Validates an EVM address (0x…) using thirdweb's `isAddress`. */ | ||
export const EVMAddressSchema = z.string().check( | ||
z.refine(isAddress, { | ||
message: "Invalid EVM address", | ||
}), | ||
); | ||
|
||
/** Coerces the chain ID into a number and checks it is positive. */ | ||
export const EVMChainIdSchema = z.coerce.number().check( | ||
z.gte(1, { | ||
message: "Invalid chain ID", | ||
}), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid Zod API usage – code will not type-check nor run
Problems:
z.string().check(...)
–check
is not a Zod method (v3 & current v4 betas).z.refine
is a method, not a stand-alone function – passing it as value will throw.z.gte
does not exist;gte
is a method on number schemas.
Fix:
-import { isAddress } from "thirdweb";
-import { z } from "zod/v4-mini";
+import { isAddress } from "thirdweb";
+import { z } from "zod";
export const EVMAddressSchema = z
.string()
- .check(
- z.refine(isAddress, {
- message: "Invalid EVM address",
- }),
- );
+ .refine(isAddress, { message: "Invalid EVM address" });
export const EVMChainIdSchema = z
.coerce.number()
- .check(
- z.gte(1, {
- message: "Invalid chain ID",
- }),
- );
+ .gte(1, { message: "Invalid chain ID" });
Please run tsc
/ your linter – this currently fails compilation.
📝 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.
import { isAddress } from "thirdweb"; | |
import { z } from "zod/v4-mini"; | |
// --------------------------- | |
// Shared Zod Schemas | |
// --------------------------- | |
/** Validates an EVM address (0x…) using thirdweb's `isAddress`. */ | |
export const EVMAddressSchema = z.string().check( | |
z.refine(isAddress, { | |
message: "Invalid EVM address", | |
}), | |
); | |
/** Coerces the chain ID into a number and checks it is positive. */ | |
export const EVMChainIdSchema = z.coerce.number().check( | |
z.gte(1, { | |
message: "Invalid chain ID", | |
}), | |
); | |
import { isAddress } from "thirdweb"; | |
import { z } from "zod"; | |
// --------------------------- | |
// Shared Zod Schemas | |
// --------------------------- | |
/** Validates an EVM address (0x…) using thirdweb's `isAddress`. */ | |
export const EVMAddressSchema = z | |
.string() | |
.refine(isAddress, { message: "Invalid EVM address" }); | |
/** Coerces the chain ID into a number and checks it is positive. */ | |
export const EVMChainIdSchema = z | |
.coerce.number() | |
.gte(1, { message: "Invalid chain ID" }); |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/schemas.ts lines 1 to 20, the Zod schema
usage is incorrect: replace the non-existent .check method with .refine for
custom validation, call .refine as a method on the schema instead of passing it
as a standalone function, and replace the invalid z.gte call with the .gte
method on the number schema. Specifically, use z.string().refine(isAddress,
{message: "Invalid EVM address"}) for the address schema and
z.coerce.number().gte(1, {message: "Invalid chain ID"}) for the chain ID schema
to fix the type errors and make the code compile.
await sendAndConfirmTx.mutateAsync(transaction, { | ||
onSuccess: () => setOpen(false), | ||
onSuccess: () => { | ||
reportListingCreated({ | ||
marketplaceAddress: contract.address, | ||
chainId: contract.chain.id, | ||
assetAddress: _selectedContract.address, | ||
assetTokenId: selectedTokenId.toString(), | ||
}); | ||
setOpen(false); | ||
}, | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Duplicate success side-effects fire twice
sendAndConfirmTx.mutateAsync()
already receives an onSuccess
callback (lines 367-375).
Immediately after the promise resolves, listingNotifications.onSuccess()
is executed again (line 378).
For a successful tx this means two identical success toasts / side-effects are triggered.
await sendAndConfirmTx.mutateAsync(transaction, {
onSuccess: () => {
…
},
});
-// fires a 2nd time
-listingNotifications.onSuccess();
Drop the outer call or move notification logic exclusively into the inner handler to avoid double execution.
Same pattern exists in the auction branch below (lines 423-438).
📝 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.
await sendAndConfirmTx.mutateAsync(transaction, { | |
onSuccess: () => setOpen(false), | |
onSuccess: () => { | |
reportListingCreated({ | |
marketplaceAddress: contract.address, | |
chainId: contract.chain.id, | |
assetAddress: _selectedContract.address, | |
assetTokenId: selectedTokenId.toString(), | |
}); | |
setOpen(false); | |
}, | |
}); | |
await sendAndConfirmTx.mutateAsync(transaction, { | |
onSuccess: () => { | |
reportListingCreated({ | |
marketplaceAddress: contract.address, | |
chainId: contract.chain.id, | |
assetAddress: _selectedContract.address, | |
assetTokenId: selectedTokenId.toString(), | |
}); | |
setOpen(false); | |
}, | |
}); |
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx
around lines 366 to 377, the success side-effects for
sendAndConfirmTx.mutateAsync are duplicated because the onSuccess callback is
defined both inside mutateAsync and immediately after awaiting it. To fix this,
remove the outer call to listingNotifications.onSuccess() after the await and
keep the notification logic only inside the onSuccess callback passed to
mutateAsync. Apply the same fix to the auction branch around lines 423 to 438 to
prevent double execution of success side-effects.
// Quantity represented as a decimal string so we don't lose precision. | ||
const TokenAmountSchema = z.string().check( | ||
z.refine((val) => /^\d+$/.test(val), { | ||
message: "Quantity must be a positive integer represented as a string", | ||
}), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suspicious z.check(z.refine())
usage – likely wrong Zod API call
z.string().check(z.refine(...))
does not match the public Zod API (including zod/v4-mini
).
The usual pattern is either:
z.string().regex(/^\d+$/, { message: "…" })
or
z.string().refine(val => /^\d+$/.test(val), { message: "…" })
Passing the result of z.refine()
into .check()
will return a ZodEffects
object, not the boolean-returning predicate that .check()
expects, and will throw at runtime.
Proposed fix:
-const TokenAmountSchema = z.string().check(
- z.refine((val) => /^\d+$/.test(val), {
- message: "Quantity must be a positive integer represented as a string",
- }),
-);
+const TokenAmountSchema = z.string().regex(/^\d+$/, {
+ message: "Quantity must be a non-negative integer represented as a string",
+});
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/token.ts around lines 9 to 14, the code
incorrectly uses z.string().check(z.refine()), which is not a valid Zod API
pattern and causes runtime errors. Replace this with either
z.string().regex(/^\d+$/, { message: "Quantity must be a positive integer
represented as a string" }) or z.string().refine(val => /^\d+$/.test(val), {
message: "Quantity must be a positive integer represented as a string" }) to
properly validate the string format.
export function reportAccountEmailVerificationRequested(payload: { | ||
email: string; | ||
}) { | ||
__internal__reportEvent("account email verification requested", { | ||
email: payload.email, | ||
}); | ||
} | ||
|
||
export function reportAccountEmailVerified(payload: { email?: string }) { | ||
__internal__reportEvent( | ||
"account email verified", | ||
payload.email ? { email: payload.email } : null, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raw e-mail addresses sent to PostHog – PII leak
reportAccountEmailVerificationRequested
/ reportAccountEmailVerified
forward the plain e-mail address to the analytics backend. E-mails qualify as personal data under most privacy regulations (GDPR, CCPA, …). Unless you have explicit user consent and a signed DPA with PostHog this is risky.
Hashing the address (SHA-256 or similar) before emitting the event usually satisfies analytics/PII guidelines while still enabling user-level funnel analysis.
+import { createHash } from "crypto";
+
+function hashEmail(email: string) {
+ return createHash("sha256").update(email.trim().toLowerCase()).digest("hex");
+}
// …
__internal__reportEvent("account email verification requested", {
- email: payload.email,
+ email_hash: hashEmail(payload.email),
});
Apply the same treatment to reportAccountEmailVerified
.
[security]
📝 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.
export function reportAccountEmailVerificationRequested(payload: { | |
email: string; | |
}) { | |
__internal__reportEvent("account email verification requested", { | |
email: payload.email, | |
}); | |
} | |
export function reportAccountEmailVerified(payload: { email?: string }) { | |
__internal__reportEvent( | |
"account email verified", | |
payload.email ? { email: payload.email } : null, | |
); | |
} | |
import { createHash } from "crypto"; | |
function hashEmail(email: string) { | |
return createHash("sha256") | |
.update(email.trim().toLowerCase()) | |
.digest("hex"); | |
} | |
export function reportAccountEmailVerificationRequested(payload: { | |
email: string; | |
}) { | |
__internal__reportEvent("account email verification requested", { | |
email_hash: hashEmail(payload.email), | |
}); | |
} | |
export function reportAccountEmailVerified(payload: { email?: string }) { | |
__internal__reportEvent( | |
"account email verified", | |
payload.email | |
? { email_hash: hashEmail(payload.email) } | |
: null, | |
); | |
} |
🤖 Prompt for AI Agents
In apps/dashboard/src/@/analytics/track/onboarding.ts between lines 7 and 20,
the functions reportAccountEmailVerificationRequested and
reportAccountEmailVerified send raw email addresses to the analytics backend,
risking PII exposure. To fix this, hash the email addresses using a secure hash
function like SHA-256 before passing them to __internal__reportEvent in both
functions, ensuring compliance with privacy regulations while preserving
analytic capabilities.
PR-Codex overview
This PR primarily focuses on removing the
Posthog
integration from various components and files across the application while introducing new tracking methods and dependencies. It also updates theposthog-js
and addsposthog-node
to the project.Detailed summary
Posthog
related files:Posthog.tsx
,PosthogPageView.tsx
,PosthogHeadSetup.tsx
, etc.trackEvent
functions from numerous components.posthog-js
version to1.252.0
and addedposthog-node
.analytics
helpers.knip.json
files to reflect new dependencies.Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores
Style