From 6ea97443deb0f716249928beef4558dbe81b0a07 Mon Sep 17 00:00:00 2001
From: Shahed Nasser
Date: Fri, 3 Oct 2025 13:33:48 +0300
Subject: [PATCH] docs: improved analytics and tracking (#13671)
* docs: improved analytics and tracking
* remove detailed feedback component
* remove ignore build script for api reference
* improvements
* fix pathname
---
.../components/DetailedFeedback/index.tsx | 83 ------------
.../components/Feedback/index.tsx | 23 ++++
.../Operation/DescriptionSection/index.tsx | 11 +-
.../components/Tags/Section/index.tsx | 10 +-
.../api-reference/instrumentation-client.ts | 7 +
www/apps/api-reference/markdown/admin.mdx | 35 +----
www/apps/api-reference/markdown/store.mdx | 39 +-----
www/apps/api-reference/package.json | 1 +
www/apps/api-reference/providers/index.tsx | 2 -
www/apps/api-reference/vercel.json | 3 +-
www/apps/book/instrumentation-client.ts | 7 +
www/apps/book/package.json | 1 +
www/apps/book/providers/index.tsx | 2 -
www/apps/cloud/instrumentation-client.ts | 7 +
www/apps/cloud/package.json | 1 +
www/apps/cloud/providers/index.tsx | 2 -
www/apps/resources/instrumentation-client.ts | 7 +
www/apps/resources/package.json | 1 +
www/apps/resources/providers/index.tsx | 2 -
www/apps/ui/instrumentation-client.ts | 7 +
www/apps/ui/package.json | 1 +
www/apps/ui/providers/index.tsx | 2 -
www/apps/user-guide/instrumentation-client.ts | 7 +
www/apps/user-guide/package.json | 1 +
www/apps/user-guide/providers/index.tsx | 2 -
www/packages/docs-ui/package.json | 2 +-
.../docs-ui/src/components/Feedback/index.tsx | 45 ++++---
.../docs-ui/src/components/Rating/index.tsx | 16 ++-
.../Sidebar/Top/MedusaMenu/index.tsx | 98 --------------
.../docs-ui/src/providers/Analytics/index.tsx | 122 ++++++++++--------
.../src/providers/LearningPath/index.tsx | 32 +++--
www/yarn.lock | 16 ++-
32 files changed, 214 insertions(+), 381 deletions(-)
delete mode 100644 www/apps/api-reference/components/DetailedFeedback/index.tsx
create mode 100644 www/apps/api-reference/components/Feedback/index.tsx
create mode 100644 www/apps/api-reference/instrumentation-client.ts
create mode 100644 www/apps/book/instrumentation-client.ts
create mode 100644 www/apps/cloud/instrumentation-client.ts
create mode 100644 www/apps/resources/instrumentation-client.ts
create mode 100644 www/apps/ui/instrumentation-client.ts
create mode 100644 www/apps/user-guide/instrumentation-client.ts
delete mode 100644 www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx
diff --git a/www/apps/api-reference/components/DetailedFeedback/index.tsx b/www/apps/api-reference/components/DetailedFeedback/index.tsx
deleted file mode 100644
index be37ae727b..0000000000
--- a/www/apps/api-reference/components/DetailedFeedback/index.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-"use client"
-
-import { useState } from "react"
-import { Label, TextArea, useAnalytics, useModal, ModalFooter } from "docs-ui"
-
-const DetailedFeedback = () => {
- const [improvementFeedback, setImprovementFeedback] = useState("")
- const [positiveFeedback, setPositiveFeedback] = useState("")
- const [additionalFeedback, setAdditionalFeedback] = useState("")
- const { loaded, track } = useAnalytics()
- const { closeModal } = useModal()
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- {
- if (
- !loaded ||
- (!improvementFeedback &&
- !positiveFeedback &&
- !additionalFeedback)
- ) {
- return
- }
- const buttonElm = e.target as HTMLButtonElement
- buttonElm.classList.add("cursor-not-allowed")
- buttonElm.textContent = "Please wait"
- track(
- "api-ref-general-feedback",
- {
- feedbackData: {
- improvementFeedback,
- positiveFeedback,
- additionalFeedback,
- },
- },
- function () {
- buttonElm.textContent = "Thank you!"
- setTimeout(() => {
- closeModal()
- }, 1000)
- }
- )
- },
- variant: "primary",
- },
- ]}
- className="mt-1"
- />
- >
- )
-}
-
-export default DetailedFeedback
diff --git a/www/apps/api-reference/components/Feedback/index.tsx b/www/apps/api-reference/components/Feedback/index.tsx
new file mode 100644
index 0000000000..ecac5f34b8
--- /dev/null
+++ b/www/apps/api-reference/components/Feedback/index.tsx
@@ -0,0 +1,23 @@
+"use client"
+
+import { Feedback as UiFeedback, FeedbackProps } from "docs-ui"
+import { usePathname } from "next/navigation"
+import { useArea } from "../../providers/area"
+
+export const Feedback = (props: Partial) => {
+ const pathname = usePathname()
+ const { area } = useArea()
+
+ return (
+
+ )
+}
diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx
index e3c9004b81..c18fb8ff78 100644
--- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx
+++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx
@@ -7,9 +7,7 @@ import type { TagsOperationDescriptionSectionResponsesProps } from "./Responses"
import dynamic from "next/dynamic"
import TagsOperationDescriptionSectionParameters from "./Parameters"
import MDXContentClient from "@/components/MDXContent/Client"
-import { useArea } from "../../../../providers/area"
import {
- Feedback,
Badge,
Link,
FeatureFlagNotice,
@@ -17,10 +15,10 @@ import {
Tooltip,
MarkdownContent,
} from "docs-ui"
-import { usePathname } from "next/navigation"
import { TagsOperationDescriptionSectionWorkflowBadgeProps } from "./WorkflowBadge"
import { TagsOperationDescriptionSectionEventsProps } from "./Events"
import { TagsOperationDescriptionSectionDeprecationNoticeProps } from "./DeprecationNotice"
+import { Feedback } from "@/components/Feedback"
const TagsOperationDescriptionSectionSecurity =
dynamic(
@@ -58,9 +56,6 @@ type TagsOperationDescriptionSectionProps = {
const TagsOperationDescriptionSection = ({
operation,
}: TagsOperationDescriptionSectionProps) => {
- const { area } = useArea()
- const pathname = usePathname()
-
return (
<>
@@ -127,14 +122,10 @@ const TagsOperationDescriptionSection = ({
>
)}
{operation.security && (
diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx
index d2b0abbf61..657acc63c8 100644
--- a/www/apps/api-reference/components/Tags/Section/index.tsx
+++ b/www/apps/api-reference/components/Tags/Section/index.tsx
@@ -19,8 +19,8 @@ import SectionContainer from "../../Section/Container"
import { useArea } from "@/providers/area"
import SectionDivider from "../../Section/Divider"
import clsx from "clsx"
-import { Feedback, Loading, Link } from "docs-ui"
-import { usePathname, useRouter } from "next/navigation"
+import { Loading, Link } from "docs-ui"
+import { useRouter } from "next/navigation"
import { OpenAPI } from "types"
import TagSectionSchema from "./Schema"
import checkElementInViewport from "../../../utils/check-element-in-viewport"
@@ -29,6 +29,7 @@ import useSWR from "swr"
import basePathUrl from "../../../utils/base-path-url"
import { getSectionId } from "docs-utils"
import { RoutesSummary } from "./RoutesSummary"
+import { Feedback } from "../../Feedback"
export type TagSectionProps = {
tag: OpenAPI.TagObject
@@ -51,7 +52,6 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => {
const [loadData, setLoadData] = useState(false)
const slugTagName = useMemo(() => getSectionId([tag.name]), [tag])
const { area } = useArea()
- const pathname = usePathname()
const { scrollableElement, scrollToTop } = useScrollController()
const { isBrowser } = useIsBrowser()
@@ -163,13 +163,9 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => {
)}
diff --git a/www/apps/api-reference/instrumentation-client.ts b/www/apps/api-reference/instrumentation-client.ts
new file mode 100644
index 0000000000..a7ea994b9b
--- /dev/null
+++ b/www/apps/api-reference/instrumentation-client.ts
@@ -0,0 +1,7 @@
+import posthog from "posthog-js"
+
+posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ person_profiles: "always",
+ defaults: "2025-05-24",
+})
diff --git a/www/apps/api-reference/markdown/admin.mdx b/www/apps/api-reference/markdown/admin.mdx
index a5fadf2a86..3caa57bc04 100644
--- a/www/apps/api-reference/markdown/admin.mdx
+++ b/www/apps/api-reference/markdown/admin.mdx
@@ -1,4 +1,5 @@
-import { Feedback, CodeTabs, CodeTab, H1 } from "docs-ui"
+import { CodeTabs, CodeTab, H1 } from "docs-ui"
+import { Feedback } from "@/components/Feedback"
import SectionContainer from "@/components/Section/Container"
import DividedMarkdownLayout from "@/layouts/DividedMarkdown"
import {
@@ -24,14 +25,10 @@ This API reference includes Medusa v2's Admin APIs, which are REST APIs exposed
All API Routes are prefixed with `/admin`. So, during development, the API Routes will be available under the path `http://localhost:9000/admin`. For production, replace `http://localhost:9000` with your Medusa application URL.
@@ -391,14 +388,10 @@ fetch(`/admin/products`, {
@@ -463,14 +456,10 @@ x-no-compression: false
@@ -648,14 +637,10 @@ sdk.admin.product.update("prod_123", {
To remove a property from the `metadata`, pass the property in the request body with an empty string value. This will remove the property from the `metadata` without affecting other properties.
@@ -942,14 +927,10 @@ However, some API routes restrict the fields and relations you can retrieve. To
@@ -1315,14 +1296,10 @@ curl -g "http://localhost:9000/admin/products?created_at[$lt]=2023-02-17&created
@@ -1496,14 +1473,10 @@ This sorts the products by their `created_at` field in the descending order.
@@ -1527,14 +1500,10 @@ This is useful if you want to extend an API route and pass additional data or pe
Refer to [this guide](!docs!/learn/customization/extend-features/extend-create-product) to find an example of extending an API route.
diff --git a/www/apps/api-reference/markdown/store.mdx b/www/apps/api-reference/markdown/store.mdx
index 59e5e6daef..db843c270d 100644
--- a/www/apps/api-reference/markdown/store.mdx
+++ b/www/apps/api-reference/markdown/store.mdx
@@ -5,7 +5,8 @@ import {
DividedMarkdownCode
} from "@/layouts/DividedMarkdown/Sections"
import Section from "@/components/Section"
-import { Feedback, CodeTabs, CodeTab, H1 } from "docs-ui"
+import { CodeTabs, CodeTab, H1 } from "docs-ui"
+import { Feedback } from "@/components/Feedback"
import ClientLibraries from "./client-libraries.mdx"
@@ -24,14 +25,10 @@ This API reference includes Medusa v2's Store APIs, which are REST APIs exposed
All API Routes are prefixed with `/store`. So, during development, the API Routes will be available under the path `http://localhost:9000/store`. For production, replace `http://localhost:9000` with your Medusa application URL.
@@ -264,14 +261,10 @@ fetch(`/store/products`, {
@@ -349,14 +342,10 @@ Where `{your_publishable_api_key}` is the token of the publishable API key. When
@@ -421,14 +410,10 @@ x-no-compression: false
@@ -624,14 +609,10 @@ sdk.store.cart.updateLineItem(
To remove a property from the `metadata`, pass the property in the request body with an empty string value. This will remove the property from the `metadata` without affecting other properties.
@@ -925,14 +906,10 @@ However, some API routes restrict the fields and relations you can retrieve. To
@@ -1289,14 +1266,10 @@ curl -g "http://localhost:9000/store/products?created_at[$lt]=2023-02-17&created
@@ -1468,14 +1441,10 @@ This sorts the products by their `created_at` field in the descending order.
@@ -1499,14 +1468,10 @@ This is useful if you want to extend an API route and pass additional data or pe
Refer to [this guide](!docs!/learn/customization/extend-features/extend-create-product) to find an example of extending an API route.
diff --git a/www/apps/api-reference/package.json b/www/apps/api-reference/package.json
index 6d514aec00..95c0c2ba2f 100644
--- a/www/apps/api-reference/package.json
+++ b/www/apps/api-reference/package.json
@@ -34,6 +34,7 @@
"openapi-sampler": "^1.3.1",
"pluralize": "^8.0.0",
"postcss": "8.4.27",
+ "posthog-js": "^1.269.1",
"prism-react-renderer": "2.4.0",
"react": "rc",
"react-dom": "rc",
diff --git a/www/apps/api-reference/providers/index.tsx b/www/apps/api-reference/providers/index.tsx
index b458ebf82b..f7e979a458 100644
--- a/www/apps/api-reference/providers/index.tsx
+++ b/www/apps/api-reference/providers/index.tsx
@@ -19,8 +19,6 @@ const Providers = ({ children }: ProvidersProps) => {
diff --git a/www/apps/api-reference/vercel.json b/www/apps/api-reference/vercel.json
index 18309e64e7..9ffa8062a3 100644
--- a/www/apps/api-reference/vercel.json
+++ b/www/apps/api-reference/vercel.json
@@ -6,6 +6,5 @@
"framework": "nextjs",
"installCommand": "yarn install",
"buildCommand": "turbo run build",
- "outputDirectory": ".next",
- "ignoreCommand": "bash ../../ignore-build-script.sh api-reference"
+ "outputDirectory": ".next"
}
diff --git a/www/apps/book/instrumentation-client.ts b/www/apps/book/instrumentation-client.ts
new file mode 100644
index 0000000000..a7ea994b9b
--- /dev/null
+++ b/www/apps/book/instrumentation-client.ts
@@ -0,0 +1,7 @@
+import posthog from "posthog-js"
+
+posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ person_profiles: "always",
+ defaults: "2025-05-24",
+})
diff --git a/www/apps/book/package.json b/www/apps/book/package.json
index 1b9c5b44f3..700c1b8d88 100644
--- a/www/apps/book/package.json
+++ b/www/apps/book/package.json
@@ -23,6 +23,7 @@
"docs-ui": "*",
"docs-utils": "*",
"next": "15.3.5",
+ "posthog-js": "^1.269.1",
"react": "rc",
"react-dom": "rc",
"rehype-mdx-code-props": "^2.0.0",
diff --git a/www/apps/book/providers/index.tsx b/www/apps/book/providers/index.tsx
index 8b74a4902c..d115ddea6b 100644
--- a/www/apps/book/providers/index.tsx
+++ b/www/apps/book/providers/index.tsx
@@ -26,8 +26,6 @@ const Providers = ({ children, aiAssistantProps = {} }: ProvidersProps) => {
diff --git a/www/apps/cloud/instrumentation-client.ts b/www/apps/cloud/instrumentation-client.ts
new file mode 100644
index 0000000000..a7ea994b9b
--- /dev/null
+++ b/www/apps/cloud/instrumentation-client.ts
@@ -0,0 +1,7 @@
+import posthog from "posthog-js"
+
+posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ person_profiles: "always",
+ defaults: "2025-05-24",
+})
diff --git a/www/apps/cloud/package.json b/www/apps/cloud/package.json
index 5aa34c191e..fea0e252dc 100644
--- a/www/apps/cloud/package.json
+++ b/www/apps/cloud/package.json
@@ -23,6 +23,7 @@
"clsx": "^2.1.0",
"docs-ui": "*",
"next": "15.3.5",
+ "posthog-js": "^1.269.1",
"react": "rc",
"react-dom": "rc",
"rehype-mdx-code-props": "^2.0.0",
diff --git a/www/apps/cloud/providers/index.tsx b/www/apps/cloud/providers/index.tsx
index 8fa9d94ce7..e9c344b269 100644
--- a/www/apps/cloud/providers/index.tsx
+++ b/www/apps/cloud/providers/index.tsx
@@ -27,8 +27,6 @@ const Providers = ({ children }: ProvidersProps) => {
diff --git a/www/apps/resources/instrumentation-client.ts b/www/apps/resources/instrumentation-client.ts
new file mode 100644
index 0000000000..a7ea994b9b
--- /dev/null
+++ b/www/apps/resources/instrumentation-client.ts
@@ -0,0 +1,7 @@
+import posthog from "posthog-js"
+
+posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ person_profiles: "always",
+ defaults: "2025-05-24",
+})
diff --git a/www/apps/resources/package.json b/www/apps/resources/package.json
index d2e607614e..757fb94cf3 100644
--- a/www/apps/resources/package.json
+++ b/www/apps/resources/package.json
@@ -22,6 +22,7 @@
"clsx": "^2.1.0",
"docs-ui": "*",
"next": "15.3.5",
+ "posthog-js": "^1.269.1",
"react": "rc",
"react-dom": "rc",
"rehype-mdx-code-props": "^2.0.0",
diff --git a/www/apps/resources/providers/index.tsx b/www/apps/resources/providers/index.tsx
index 03a489ac35..a92d2ef7b0 100644
--- a/www/apps/resources/providers/index.tsx
+++ b/www/apps/resources/providers/index.tsx
@@ -24,8 +24,6 @@ const Providers = ({ children }: ProvidersProps) => {
{
diff --git a/www/apps/user-guide/instrumentation-client.ts b/www/apps/user-guide/instrumentation-client.ts
new file mode 100644
index 0000000000..a7ea994b9b
--- /dev/null
+++ b/www/apps/user-guide/instrumentation-client.ts
@@ -0,0 +1,7 @@
+import posthog from "posthog-js"
+
+posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
+ person_profiles: "always",
+ defaults: "2025-05-24",
+})
diff --git a/www/apps/user-guide/package.json b/www/apps/user-guide/package.json
index a76d97c483..3d630f9fc2 100644
--- a/www/apps/user-guide/package.json
+++ b/www/apps/user-guide/package.json
@@ -22,6 +22,7 @@
"clsx": "^2.1.0",
"docs-ui": "*",
"next": "15.3.5",
+ "posthog-js": "^1.269.1",
"react": "rc",
"react-dom": "rc",
"rehype-mdx-code-props": "^2.0.0",
diff --git a/www/apps/user-guide/providers/index.tsx b/www/apps/user-guide/providers/index.tsx
index 8fa9d94ce7..e9c344b269 100644
--- a/www/apps/user-guide/providers/index.tsx
+++ b/www/apps/user-guide/providers/index.tsx
@@ -27,8 +27,6 @@ const Providers = ({ children }: ProvidersProps) => {
diff --git a/www/packages/docs-ui/package.json b/www/packages/docs-ui/package.json
index 328412143d..18d903e174 100644
--- a/www/packages/docs-ui/package.json
+++ b/www/packages/docs-ui/package.json
@@ -52,6 +52,7 @@
"@types/react": "*",
"@types/react-dom": "*",
"next": "*",
+ "posthog-js": "*",
"react": "*",
"react-dom": "*"
},
@@ -70,7 +71,6 @@
"mermaid": "^10.9.0",
"minisearch": "^7.1.1",
"npm-to-yarn": "^2.1.0",
- "posthog-js": "^1.269.0",
"prism-react-renderer": "2.4.0",
"react": "rc",
"react-dom": "rc",
diff --git a/www/packages/docs-ui/src/components/Feedback/index.tsx b/www/packages/docs-ui/src/components/Feedback/index.tsx
index 5da3924477..dbcd32ac60 100644
--- a/www/packages/docs-ui/src/components/Feedback/index.tsx
+++ b/www/packages/docs-ui/src/components/Feedback/index.tsx
@@ -105,28 +105,31 @@ export const Feedback = ({
if (showForm) {
setLoading(true)
}
- track(
- event,
- {
- url: pathName,
- label: document.title,
- feedback:
- (feedback !== null && feedback) ||
- (feedback === null && positiveFeedback)
- ? "yes"
- : "no",
- message: message?.length ? message : null,
- os: window.navigator.userAgent,
- feedbackOption,
- ...extraData,
+ track({
+ event: {
+ event,
+ options: {
+ url: pathName,
+ label: document.title,
+ feedback:
+ (feedback !== null && feedback) ||
+ (feedback === null && positiveFeedback)
+ ? "yes"
+ : "no",
+ message: message?.length ? message : null,
+ os: window.navigator.userAgent,
+ feedbackOption,
+ ...extraData,
+ },
+ callback: function () {
+ if (showForm) {
+ setLoading(false)
+ resetForm()
+ }
+ },
+ tracker: ["segment", "posthog"],
},
- function () {
- if (showForm) {
- setLoading(false)
- resetForm()
- }
- }
- )
+ })
}
function resetForm() {
diff --git a/www/packages/docs-ui/src/components/Rating/index.tsx b/www/packages/docs-ui/src/components/Rating/index.tsx
index 1a07d80c3e..8a6dc48e64 100644
--- a/www/packages/docs-ui/src/components/Rating/index.tsx
+++ b/www/packages/docs-ui/src/components/Rating/index.tsx
@@ -31,14 +31,16 @@ export const Rating: React.FC = ({
const submitTracking = useCallback(
(selectedRating?: number, feedback?: string) => {
- track(
- event,
- {
- rating: selectedRating || rating,
- additionalFeedback: feedback || additionalFeedback,
+ track({
+ event: {
+ event,
+ options: {
+ rating: selectedRating || rating,
+ additionalFeedback: feedback || additionalFeedback,
+ },
+ callback: () => onRating?.(selectedRating || rating),
},
- () => onRating?.(selectedRating || rating)
- )
+ })
},
[rating, additionalFeedback]
)
diff --git a/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx
deleted file mode 100644
index 08de9862af..0000000000
--- a/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-"use client"
-
-import clsx from "clsx"
-import React, { useRef, useState } from "react"
-import {
- BorderedIcon,
- getOsShortcut,
- useAnalytics,
- useClickOutside,
- useSidebar,
-} from "../../../.."
-import {
- EllipsisHorizontal,
- SidebarLeft,
- TimelineVertical,
-} from "@medusajs/icons"
-import { HouseIcon } from "../../../Icons/House"
-import { Menu } from "../../../Menu"
-
-export const SidebarTopMedusaMenu = () => {
- const [openMenu, setOpenMenu] = useState(false)
- const { setDesktopSidebarOpen } = useSidebar()
- const { track } = useAnalytics()
- const ref = useRef(null)
-
- const toggleOpen = () => {
- setOpenMenu((prev) => !prev)
- if (!openMenu) {
- track("nav_sidebar_open", {
- url: window.location.href,
- })
- }
- }
-
- useClickOutside({
- elmRef: ref,
- onClickOutside: () => {
- setOpenMenu(false)
- },
- })
-
- return (
-
-
-
-
- Medusa Docs
-
-
-
-
-
,
- title: "Homepage",
- link: "https://medusajs.com",
- },
- {
- type: "link",
- icon: ,
- title: "Changelog",
- link: "https://medusajs.com/changelog",
- },
- {
- type: "divider",
- },
- {
- type: "action",
- title: "Hide Sidebar",
- icon: ,
- shortcut: `${getOsShortcut()}.`,
- action: () => {
- setDesktopSidebarOpen(false)
- setOpenMenu(false)
- },
- },
- ]}
- />
-
-
- )
-}
diff --git a/www/packages/docs-ui/src/providers/Analytics/index.tsx b/www/packages/docs-ui/src/providers/Analytics/index.tsx
index 59777241ef..634b6e851c 100644
--- a/www/packages/docs-ui/src/providers/Analytics/index.tsx
+++ b/www/packages/docs-ui/src/providers/Analytics/index.tsx
@@ -8,7 +8,6 @@ import React, {
useState,
} from "react"
import { Analytics, AnalyticsBrowser } from "@segment/analytics-next"
-import { PostHogProvider as PHProvider } from "posthog-js/react"
import posthog from "posthog-js"
// @ts-expect-error Doesn't have a types package
@@ -22,16 +21,22 @@ export type ExtraData = {
export type AnalyticsContextType = {
loaded: boolean
analytics: Analytics | null
- track: (
- event: string,
- options?: Record,
- callback?: () => void
- ) => void
+ track: ({
+ event,
+ instant,
+ }: {
+ event: TrackedEvent
+ instant?: boolean
+ }) => void
}
+type Trackers = "segment" | "posthog"
+
export type TrackedEvent = {
event: string
options?: Record
+ callback?: () => void
+ tracker?: Trackers | Trackers[]
}
const AnalyticsContext = createContext(null)
@@ -39,8 +44,6 @@ const AnalyticsContext = createContext(null)
export type AnalyticsProviderProps = {
segmentWriteKey?: string
reoDevKey?: string
- postHogKey?: string
- postHogApiHost?: string
children?: React.ReactNode
}
@@ -50,8 +53,6 @@ export const AnalyticsProvider = ({
segmentWriteKey = "temp",
reoDevKey,
children,
- postHogKey,
- postHogApiHost = "https://eu.i.posthog.com",
}: AnalyticsProviderProps) => {
// loaded is used to ensure that a connection has been made to segment
// even if it failed. This is to ensure that the connection isn't
@@ -85,21 +86,13 @@ export const AnalyticsProvider = ({
}
}, [loaded, segmentWriteKey])
- const track = useCallback(
- async (
- event: string,
- options?: Record,
- callback?: () => void
- ) => {
+ const trackWithSegment = useCallback(
+ async ({ event, options }: TrackedEvent) => {
if (analytics) {
- void analytics.track(
- event,
- {
- ...options,
- uuid: analytics.user().anonymousId(),
- },
- callback
- )
+ void analytics.track(event, {
+ ...options,
+ uuid: analytics.user().anonymousId(),
+ })
} else {
// push the event into the queue
setQueue((prevQueue) => [
@@ -107,45 +100,70 @@ export const AnalyticsProvider = ({
{
event,
options,
+ tracker: "segment",
},
])
- if (callback) {
- console.warn(
- "Segment is either not installed or not configured. Simulating success..."
- )
- callback()
- }
+ console.warn(
+ "Segment is either not installed or not configured. Simulating success..."
+ )
}
},
[analytics, loaded]
)
- const initPostHog = useCallback(() => {
- if (!postHogKey) {
- return
- }
+ const trackWithPostHog = async ({ event, options }: TrackedEvent) => {
+ posthog.capture(event, options)
+ }
- posthog.init(postHogKey, {
- api_host: postHogApiHost,
- person_profiles: "always",
- defaults: "2025-05-24",
- })
- }, [])
+ const processEvent = useCallback(
+ async (event: TrackedEvent) => {
+ const trackers = Array.isArray(event.tracker)
+ ? event.tracker
+ : [event.tracker]
+ await Promise.all(
+ trackers.map(async (tracker) => {
+ switch (tracker) {
+ case "posthog":
+ return trackWithPostHog(event)
+ case "segment":
+ default:
+ return trackWithSegment(event)
+ }
+ })
+ )
+ },
+ [trackWithSegment, trackWithPostHog]
+ )
+
+ const track = ({ event }: { event: TrackedEvent }) => {
+ // Always queue events - this makes tracking non-blocking
+ setQueue((prevQueue) => [...prevQueue, event])
+
+ // Process event callback immediately
+ // This ensures that the callback is called even if the event is queued
+ event.callback?.()
+ }
useEffect(() => {
initSegment()
- initPostHog()
}, [initSegment])
useEffect(() => {
if (analytics && queue.length) {
- // track stuff in queue
- queue.forEach(async (trackEvent) =>
- track(trackEvent.event, trackEvent.options)
- )
+ // Process queue in background without blocking
+ const currentQueue = [...queue]
setQueue([])
+
+ // Process events asynchronously in batches to avoid overwhelming the system
+ const batchSize = 5
+ for (let i = 0; i < currentQueue.length; i += batchSize) {
+ const batch = currentQueue.slice(i, i + batchSize)
+ setTimeout(() => {
+ batch.forEach(processEvent)
+ }, i * 10) // Small delay between batches
+ }
}
- }, [analytics, queue])
+ }, [analytics, queue, trackWithSegment, trackWithPostHog, processEvent])
useEffect(() => {
if (!reoDevKey) {
@@ -155,12 +173,12 @@ export const AnalyticsProvider = ({
loadReoScript({
clientID: reoDevKey,
})
- .then((Reo: any) => {
- Reo.init({
+ .then((Reo: unknown) => {
+ ;(Reo as { init: (config: { clientID: string }) => void }).init({
clientID: reoDevKey,
})
})
- .catch((e: any) => {
+ .catch((e: Error) => {
console.error(`Could not connect to Reodotdev. Error: ${e}`)
})
}, [reoDevKey])
@@ -173,11 +191,7 @@ export const AnalyticsProvider = ({
loaded,
}}
>
- {postHogKey ? (
- {children}
- ) : (
- children
- )}
+ {children}
)
}
diff --git a/www/packages/docs-ui/src/providers/LearningPath/index.tsx b/www/packages/docs-ui/src/providers/LearningPath/index.tsx
index a15c784548..bc63d28e79 100644
--- a/www/packages/docs-ui/src/providers/LearningPath/index.tsx
+++ b/www/packages/docs-ui/src/providers/LearningPath/index.tsx
@@ -71,9 +71,14 @@ export const LearningPathProvider: React.FC = ({
)
}
- track(`learning_path_${path.name}`, {
- url: pathname,
- state: `start`,
+ track({
+ event: {
+ event: `learning_path_${path.name}`,
+ options: {
+ url: pathname,
+ state: `start`,
+ },
+ },
})
}
@@ -86,14 +91,19 @@ export const LearningPathProvider: React.FC = ({
const endPath = () => {
const didFinish = currentStep === (path?.steps.length || 0) - 1
const reachedIndex = currentStep === -1 ? 0 : currentStep
- track(`learning_path_${path?.name}`, {
- url: pathname,
- state: !didFinish ? `closed` : `end`,
- reachedStep:
- path?.steps[reachedIndex]?.title ||
- path?.steps[reachedIndex]?.description ||
- path?.steps[reachedIndex]?.descriptionJSX ||
- reachedIndex,
+ track({
+ event: {
+ event: `learning_path_${path?.name}`,
+ options: {
+ url: pathname,
+ state: !didFinish ? `closed` : `end`,
+ reachedStep:
+ path?.steps[reachedIndex]?.title ||
+ path?.steps[reachedIndex]?.description ||
+ path?.steps[reachedIndex]?.descriptionJSX ||
+ reachedIndex,
+ },
+ },
})
setPath(null)
setCurrentStep(-1)
diff --git a/www/yarn.lock b/www/yarn.lock
index 79b28ac72e..13a4c5d451 100644
--- a/www/yarn.lock
+++ b/www/yarn.lock
@@ -5483,6 +5483,7 @@ __metadata:
openapi-sampler: ^1.3.1
pluralize: ^8.0.0
postcss: 8.4.27
+ posthog-js: ^1.269.1
prism-react-renderer: 2.4.0
react: rc
react-dom: rc
@@ -5843,6 +5844,7 @@ __metadata:
eslint-plugin-react-hooks: ^5.0.0
next: 15.3.5
postcss: ^8
+ posthog-js: ^1.269.1
react: rc
react-dom: rc
rehype-mdx-code-props: ^2.0.0
@@ -6198,6 +6200,7 @@ __metadata:
eslint-plugin-react-hooks: ^5.0.0
next: 15.3.5
postcss: ^8
+ posthog-js: ^1.269.1
react: rc
react-dom: rc
rehype-mdx-code-props: ^2.0.0
@@ -7175,7 +7178,6 @@ __metadata:
minisearch: ^7.1.1
next: 15.3.5
npm-to-yarn: ^2.1.0
- posthog-js: ^1.269.0
prism-react-renderer: 2.4.0
react: rc
react-dom: rc
@@ -7198,6 +7200,7 @@ __metadata:
"@types/react": "*"
"@types/react-dom": "*"
next: "*"
+ posthog-js: "*"
react: "*"
react-dom: "*"
languageName: unknown
@@ -12428,9 +12431,9 @@ __metadata:
languageName: node
linkType: hard
-"posthog-js@npm:^1.269.0":
- version: 1.269.0
- resolution: "posthog-js@npm:1.269.0"
+"posthog-js@npm:^1.269.1":
+ version: 1.269.1
+ resolution: "posthog-js@npm:1.269.1"
dependencies:
"@posthog/core": 1.2.2
core-js: ^3.38.1
@@ -12445,7 +12448,7 @@ __metadata:
optional: true
rrweb-snapshot:
optional: true
- checksum: e29de2d4e33b643bc7dc57902d45294879915129bf5eba97e9486a4094cbaf0fbfc3d1ed55959434d0ffc94b55a640020d8ef786cddb6d48dc9c608667cd1ac4
+ checksum: 93b5d050f06dedb70820a2749d999451b37b24b61bb6041d61a1a05fe78405677284b00e1cfeae8e7b298645615002951febb275a4f87cf25191070172855590
languageName: node
linkType: hard
@@ -13390,6 +13393,7 @@ __metadata:
eslint-plugin-react-hooks: ^5.0.0
next: 15.3.5
postcss: ^8
+ posthog-js: ^1.269.1
react: rc
react-dom: rc
rehype-mdx-code-props: ^2.0.0
@@ -15129,6 +15133,7 @@ turbo@latest:
eslint-plugin-react-hooks: ^5.0.0
next: 15.3.5
postcss: ^8
+ posthog-js: ^1.269.1
react: rc
react-dom: rc
rehype-mdx-code-props: ^2.0.0
@@ -15482,6 +15487,7 @@ turbo@latest:
eslint-plugin-react-hooks: ^5.0.0
next: 15.3.5
postcss: ^8
+ posthog-js: ^1.269.1
react: rc
react-dom: rc
rehype-mdx-code-props: ^2.0.0