Skip to content

Commit

Permalink
move into a separate folder
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity committed Dec 20, 2024
1 parent 910430e commit 661b93c
Show file tree
Hide file tree
Showing 45 changed files with 387 additions and 174 deletions.
56 changes: 56 additions & 0 deletions packages/ui/analytics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@fern-docs/analytics",
"version": "0.0.0",
"private": true,
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./dist/index.js"
},
"./provider": {
"types": "./src/provider.tsx",
"default": "./dist/provider.js"
}
},
"scripts": {
"compile": "tsc --build",
"clean": "rm -rf ./dist && tsc --build --clean",
"format": "prettier --write --ignore-unknown --ignore-path ../../shared/.prettierignore \"**\"",
"format:check": "prettier --check --ignore-unknown --ignore-path ../../shared/.prettierignore \"**\"",
"lint": "eslint --max-warnings 0 src --ext .ts --resolve-plugins-relative-to ../../",
"dev": "tsc --watch tsconfig.json"
},
"peerDependencies": {
"next": "^14",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@fern-api/fdr-sdk": "workspace:*",
"@fern-platform/configs": "workspace:*",
"@types/mixpanel-browser": "^2.50.2",
"@types/node": "^18.7.18",
"@types/react": "^18",
"@types/react-dom": "^18.3.0",
"depcheck": "^1.4.3",
"eslint": "^8.56.0",
"next": "^14",
"organize-imports-cli": "^0.10.0",
"prettier": "^3.3.2",
"react": "^18",
"react-dom": "^18",
"typescript": "5.4.3"
},
"dependencies": {
"@amplitude/analytics-browser": "^2.11.10",
"@datadog/browser-rum": "^5.34.0",
"@hotjar/browser": "^1.0.9",
"@segment/snippet": "^5.2.1",
"fathom-client": "^3.7.2",
"logrocket": "^9.0.0",
"mixpanel-browser": "^2.57.1",
"posthog-js": "^1.154.5",
"zod": "^3.24.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { init, track } from "@amplitude/analytics-browser";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./use-track";

export function AmplitudeScript({ apiKey }: { apiKey: string }): ReactNode {
export default function AmplitudeScript({ apiKey }: { apiKey: string }): ReactNode {
useEffect(() => {
try {
init(apiKey, undefined, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Script from "next/script";
import { ReactNode } from "react";

// TODO: send events to clearbit
export function ClearbitScript({ apiKey }: { apiKey: string }): ReactNode {
export default function ClearbitScript({ apiKey }: { apiKey: string }): ReactNode {
return (
<Script
id="clearbit"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { datadogRum, type RumInitConfiguration } from "@datadog/browser-rum";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function DatadogRumScript(props: RumInitConfiguration): ReactNode {
export default function DatadogRumScript(props: RumInitConfiguration): ReactNode {
useEffect(() => {
datadogRum.init(props);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (user) {
datadogRum.setUser({ email: user.email, name: user.name });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as Fathom from "fathom-client";
import { ReactNode, useEffect } from "react";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useRouteChangeComplete } from "./use-route-changed";
import { useSafeListenTrackEvents } from "./use-track";

export function FathomScript({ siteId }: { siteId: string }): ReactNode {
export default function FathomScript({ siteId }: { siteId: string }): ReactNode {
useEffect(() => {
Fathom.load(siteId);
}, [siteId]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function FullstoryScript(props: { orgId: string }): ReactNode {
export default function FullstoryScript(props: { orgId: string }): ReactNode {
useSafeListenTrackEvents(({ event, properties }) => {
if (typeof window.FS === "function") {
// https://developer.fullstory.com/browser/capture-events/analytics-events/
window.FS("trackEvent", { name: event, properties });
}
});

const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (user && user.email && typeof window.FS === "function") {
// https://developer.fullstory.com/browser/identification/set-user-properties/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type GAParams = {
nonce?: string;
};

export function GoogleAnalytics(props: GAParams): ReactNode {
export default function GoogleAnalytics(props: GAParams): ReactNode {
const { gaId, debugMode, dataLayerName = "dataLayer", nonce } = props;
useEffect(() => {
// performance.mark is being used as a feature use signal. While it is traditionally used for performance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type GTMParams = {
nonce?: string;
};

export function GoogleTagManager(props: GTMParams): ReactNode {
export default function GoogleTagManager(props: GTMParams): ReactNode {
const { gtmId, dataLayerName = "dataLayer", nonce } = props;

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function HeapScript({ appId }: { appId: string }): ReactNode {
export default function HeapScript({ appId }: { appId: string }): ReactNode {
useSafeListenTrackEvents(({ event, properties }) => {
if (window.heap) {
window.heap.track(event, properties);
}
});

const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (!window.heap) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Hotjar from "@hotjar/browser";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useRouteChangeComplete } from "./use-route-changed";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function HotjarScript({ id, version }: { id: string; version: string }): ReactNode {
export default function HotjarScript({ id, version }: { id: string; version: string }): ReactNode {
useEffect(() => {
Hotjar.init(Number(id), Number(version));
}, [id, version]);

const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (user) {
const userInfo: Record<string, string> = {};
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/analytics/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare global {
interface Window {
[key: string]: any;
}
}

export { track, trackInternal } from "./track";
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Script from "next/script";
import { ReactElement, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

// copied from @intercom/messenger-js-sdk
interface IntercomSettings {
Expand Down Expand Up @@ -47,7 +47,7 @@ export function IntercomScript(props: IntercomSettings): ReactElement {
* @param config
*/
function useIntercomInitializer(config: IntercomSettings): void {
const user = useFernUser();
const user = useUserInfo();

useEffect(() => {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function KoalaScript({ apiKey }: { apiKey: string }): ReactNode {
const user = useFernUser();
export default function KoalaScript({ apiKey }: { apiKey: string }): ReactNode {
const user = useUserInfo();

useEffect(() => {
if (user && user.email && window.ko) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import LogRocket from "logrocket";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./use-track";

export function LogRocketScript({ appId }: { appId: string }): ReactNode {
export default function LogRocketScript({ appId }: { appId: string }): ReactNode {
useEffect(() => {
LogRocket.init(appId);
}, [appId]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import mixpanel from "mixpanel-browser";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export function MixpanelScript({ token }: { token: string }): ReactNode {
export default function MixpanelScript({ token }: { token: string }): ReactNode {
useEffect(() => {
mixpanel.init(token, {
track_pageview: true,
});
}, [token]);

const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (user?.email) {
mixpanel.identify(user.email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import Script from "next/script";
import { ReactNode } from "react";

// TODO: send events to pirsch
export function PirschScript({ identificationCode }: { identificationCode: string }): ReactNode {
export default function PirschScript({ identificationCode }: { identificationCode: string }): ReactNode {
return <Script defer src="https://api.pirsch.io/pa.js" id="pianjs" data-code={identificationCode} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import Script from "next/script";
import { ReactNode } from "react";

// TODO: send events to plausible
export function PlausibleScript({ domain }: { domain: string }): ReactNode {
export default function PlausibleScript({ domain }: { domain: string }): ReactNode {
return <Script id="plausible" defer src="https://plausible.io/js/script.js" data-domain={domain} />;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import posthog, { type PostHog } from "posthog-js";
import { ReactNode, useEffect } from "react";
import { useApiRoute, useFernUser } from "../atoms";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useRouteChangeComplete } from "./use-route-changed";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

/**
* Posthog natively allows us to define additional capture objects with distinct configs on the global instance,
Expand All @@ -23,50 +23,7 @@ function posthogHasCustomer(instance: PostHog): instance is PostHogWithCustomer
return Boolean((instance as PostHogWithCustomer).customer);
}

export function Posthog(): ReactNode {
const route = useApiRoute("/api/fern-docs/analytics/posthog");

// initialize the posthog instance
useEffect(() => {
const token = process.env.NEXT_PUBLIC_POSTHOG_API_KEY;
if (token == null) {
// eslint-disable-next-line no-console
console.warn("Posthog will NOT be initialized.");
return;
}

posthog.init(token, {
api_host: route,
capture_pageview: true,
capture_pageleave: true,
});
}, [route]);

// identify the user after the posthog instance is initialized
const user = useFernUser();
useEffect(() => {
if (user && user.email && posthog._isIdentified()) {
posthog.identify(user.email);
} else if (posthog._isIdentified()) {
posthog.reset();
}
}, [user]);

// capture pageviews
useRouteChangeComplete(() => {
// posthog doesn't handle this automatically: https://posthog.com/docs/libraries/next-js#pageview
posthog.capture("$pageview");
});

// capture events
useSafeListenTrackEvents(({ event, properties }) => {
posthog.capture(event, properties);
}, true);

return false;
}

export function CustomerPosthog({ token, api_host }: { token: string; api_host?: string }): ReactNode {
export default function CustomerPosthog({ token, api_host }: { token: string; api_host?: string }): ReactNode {
// initialize the posthog instance
useEffect(() => {
posthog.init(
Expand All @@ -81,7 +38,7 @@ export function CustomerPosthog({ token, api_host }: { token: string; api_host?:
}, [token, api_host]);

// identify the user after the posthog instance is initialized
const user = useFernUser();
const user = useUserInfo();
useEffect(() => {
if (user && user.email && getCustomerPosthog()) {
getCustomerPosthog()?.identify(user.email);
Expand Down
46 changes: 46 additions & 0 deletions packages/ui/analytics/src/posthog-internal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import posthog from "posthog-js";
import { ReactNode, useEffect } from "react";
import { useRouteChangeComplete } from "./use-route-changed";
import { useSafeListenTrackEvents } from "./use-track";
import { useUserInfo } from "./user";

export default function Posthog({ route }: { route: string }): ReactNode {
// initialize the posthog instance
useEffect(() => {
const token = process.env.NEXT_PUBLIC_POSTHOG_API_KEY;
if (token == null) {
// eslint-disable-next-line no-console
console.warn("Posthog will NOT be initialized.");
return;
}

posthog.init(token, {
api_host: route,
capture_pageview: true,
capture_pageleave: true,
});
}, [route]);

// identify the user after the posthog instance is initialized
const user = useUserInfo();
useEffect(() => {
if (user && user.email && posthog._isIdentified()) {
posthog.identify(user.email);
} else if (posthog._isIdentified()) {
posthog.reset();
}
}, [user]);

// capture pageviews
useRouteChangeComplete(() => {
// posthog doesn't handle this automatically: https://posthog.com/docs/libraries/next-js#pageview
posthog.capture("$pageview");
});

// capture events
useSafeListenTrackEvents(({ event, properties }) => {
posthog.capture(event, properties);
}, true);

return false;
}
Loading

0 comments on commit 661b93c

Please sign in to comment.