mirror of
https://github.com/placeholder-soft/web.git
synced 2026-01-12 17:02:57 +08:00
Add Client Analytics Pageview Tracking (#29)
* Add Client Analytics pageview tracking to Base Docs app. * Add Client Analytics pageview tracking to Base Web app. * Add import plugin to fix dotenv linting in docusaurus.config.js * Switch to .ts files and disable type-checking and linting. * Update initCCA file extension in docs config. * Add execution environment check before using window variable. * Replace process.env with publicRuntimeConfig. * Remove Amplitude env vars. Remove device id from analytics init files. * Remove duplicate dotenv call.
This commit is contained in:
11
.eslintrc.js
11
.eslintrc.js
@@ -16,10 +16,10 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
parser: "@typescript-eslint/parser",
|
||||
project: "./tsconfig.json",
|
||||
parser: '@typescript-eslint/parser',
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
plugins: ['react-perf', 'relay', '@typescript-eslint'],
|
||||
plugins: ['react-perf', 'relay', '@typescript-eslint', 'import'],
|
||||
extends: [
|
||||
'airbnb-typescript/base',
|
||||
'airbnb/rules/react',
|
||||
@@ -136,6 +136,5 @@ module.exports = {
|
||||
// Hard to migrate
|
||||
// Errors for all try/catch blocks and any types from third-parties
|
||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
const dotenv = require('dotenv');
|
||||
dotenv.config();
|
||||
|
||||
const baseConfig = {
|
||||
baseUrl: '/',
|
||||
favicon: 'img/favicon.ico',
|
||||
@@ -11,14 +14,14 @@ const baseConfig = {
|
||||
autoCollapseCategories: true,
|
||||
hideable: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
};;
|
||||
};
|
||||
|
||||
const lightCodeTheme = require('prism-react-renderer/themes/github');
|
||||
const darkCodeTheme = require('prism-react-renderer/themes/oceanicNext');
|
||||
|
||||
const APP_TITLE = `Base`;
|
||||
const APP_TITLE = 'Base';
|
||||
const PRODUCT_NAME = 'Base';
|
||||
|
||||
const config = {
|
||||
@@ -26,6 +29,9 @@ const config = {
|
||||
title: APP_TITLE,
|
||||
tagline: '',
|
||||
url: 'https://docs.base.org',
|
||||
customFields: {
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
@@ -57,6 +63,13 @@ const config = {
|
||||
'docusaurus-node-polyfills',
|
||||
'./src/plugins/docusaurus-plugin-kbar/index.js',
|
||||
],
|
||||
scripts: [
|
||||
{
|
||||
src: 'https://static-assets.coinbase.com/js/cca/v0.0.1.js',
|
||||
async: true,
|
||||
},
|
||||
],
|
||||
clientModules: [require.resolve('./src/utils/initCCA.ts')],
|
||||
|
||||
themeConfig: {
|
||||
...baseConfig.themeConfig,
|
||||
@@ -73,12 +86,12 @@ const config = {
|
||||
type: 'doc',
|
||||
docId: 'overview',
|
||||
position: 'left',
|
||||
label: `Documentation`,
|
||||
label: 'Documentation',
|
||||
},
|
||||
{
|
||||
to: '/base-camp/docs/welcome',
|
||||
position: 'left',
|
||||
label: `Base Camp`,
|
||||
label: 'Base Camp',
|
||||
items: [
|
||||
{
|
||||
label: 'Learn',
|
||||
@@ -94,7 +107,7 @@ const config = {
|
||||
type: 'doc',
|
||||
docId: 'security',
|
||||
position: 'left',
|
||||
label: `Security`,
|
||||
label: 'Security',
|
||||
},
|
||||
{
|
||||
type: 'dropdown',
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@rainbow-me/rainbowkit": "^1.0.4",
|
||||
"docusaurus-node-polyfills": "^1.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"kbar": "^0.1.0-beta.41",
|
||||
|
||||
48
apps/base-docs/src/utils/initCCA.ts
Normal file
48
apps/base-docs/src/utils/initCCA.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
// The CCA team said this lite version of the library is temporary and not officially supported.
|
||||
// They recommended disabling linting and type-checking for now, since this version is not typed.
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
const docusaurusConfig = require('@generated/docusaurus.config');
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
|
||||
const { customFields } = docusaurusConfig.default;
|
||||
const isDevelopment = customFields.nodeEnv === 'development';
|
||||
|
||||
// Initialize Client Analytics
|
||||
const initCCA = () => {
|
||||
if (ExecutionEnvironment.canUseDOM && window.ClientAnalytics) {
|
||||
const { init, identify, PlatformName } = window.ClientAnalytics;
|
||||
|
||||
init({
|
||||
isProd: !isDevelopment,
|
||||
amplitudeApiKey: isDevelopment
|
||||
? 'ca92bbcb548f7ec4b8ebe9194b8eda81'
|
||||
: '2b38c7ac93c0dccc83ebf9acc5107413',
|
||||
platform: PlatformName.web,
|
||||
projectName: 'base_docs',
|
||||
showDebugLogging: isDevelopment,
|
||||
version: '1.0.0',
|
||||
apiEndpoint: 'https://cca-lite.coinbase.com',
|
||||
});
|
||||
|
||||
identify({ deviceId: 'base_docs_device_id' });
|
||||
}
|
||||
};
|
||||
|
||||
export default initCCA();
|
||||
|
||||
// Track Pageviews
|
||||
export function onRouteDidUpdate({ location, previousLocation }) {
|
||||
if (location.pathname !== previousLocation?.pathname && window.ClientAnalytics) {
|
||||
const { logEvent } = window.ClientAnalytics;
|
||||
|
||||
const referrerURL =
|
||||
previousLocation?.pathname === null && document.referrer ? document.referrer : null;
|
||||
|
||||
logEvent('pageview', {
|
||||
page_path: location.pathname,
|
||||
prev_page_path: previousLocation?.pathname,
|
||||
referrer_url: referrerURL,
|
||||
});
|
||||
}
|
||||
}
|
||||
1
apps/web/global.d.ts
vendored
1
apps/web/global.d.ts
vendored
@@ -5,6 +5,7 @@ declare module 'next/config' {
|
||||
alchemyApiUrl: string;
|
||||
};
|
||||
publicRuntimeConfig: {
|
||||
nodeEnv: string;
|
||||
docsUrl: string;
|
||||
bridgeUrl: string;
|
||||
greenhouseApiUrl: string;
|
||||
|
||||
@@ -54,6 +54,8 @@ function extendBaseConfig(customConfig = {}, plugins = []) {
|
||||
const isLocalDevelopment = process.env.NODE_ENV === 'development';
|
||||
const baseXYZDomains = 'https://base.mirror.xyz';
|
||||
const greenhouseDomains = 'https://boards.greenhouse.io';
|
||||
const ccaDomain = 'https://static-assets.coinbase.com/js/cca/v0.0.1.js';
|
||||
const analyticsDomains = 'https://analytics-service-dev.cbhq.net';
|
||||
|
||||
const contentSecurityPolicy = {
|
||||
'default-src': [
|
||||
@@ -62,6 +64,8 @@ const contentSecurityPolicy = {
|
||||
isLocalDevelopment ? "'unsafe-eval'" : '',
|
||||
baseXYZDomains,
|
||||
greenhouseDomains,
|
||||
ccaDomain,
|
||||
analyticsDomains,
|
||||
],
|
||||
'frame-ancestors': ["'self'", baseXYZDomains],
|
||||
'form-action': ["'self'", baseXYZDomains],
|
||||
@@ -108,6 +112,7 @@ const securityHeaders = [
|
||||
|
||||
module.exports = extendBaseConfig({
|
||||
publicRuntimeConfig: {
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
docsUrl: process.env.DOCS_URL ?? 'https://docs.base.org',
|
||||
bridgeUrl: process.env.BRIDGE_URL ?? 'https://bridge.base.org',
|
||||
greenhouseApiUrl: process.env.GREENHOUSE_HTTPS ?? 'https://boards-api.greenhouse.io/v1',
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import './global.css';
|
||||
|
||||
import Script from 'next/script';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useCallback } from 'react';
|
||||
import initCCA from '../src/utils/initCCA';
|
||||
import { MotionConfig } from 'framer-motion';
|
||||
import App, { AppContext, AppProps } from 'next/app';
|
||||
|
||||
@@ -13,8 +17,14 @@ export async function getInitialProps(context: AppContext) {
|
||||
}
|
||||
|
||||
export default function StaticApp({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<MotionConfig reducedMotion="user">
|
||||
<Script
|
||||
src="https://static-assets.coinbase.com/js/cca/v0.0.1.js"
|
||||
onLoad={useCallback(() => initCCA(router), [router])}
|
||||
/>
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
|
||||
35
apps/web/src/utils/initCCA.ts
Normal file
35
apps/web/src/utils/initCCA.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
// The CCA team said this lite version of the library is temporary and not officially supported.
|
||||
// They recommended disabling linting and type-checking for now, since this version is not typed.
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
import getConfig from 'next/config';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const isDevelopment = publicRuntimeConfig.nodeEnv === 'development';
|
||||
|
||||
// CCA library loads in _app.tsx
|
||||
const initCCA = (router) => {
|
||||
if (window.ClientAnalytics) {
|
||||
const { init, identify, PlatformName, initNextJsTrackPageview } = window.ClientAnalytics;
|
||||
|
||||
init({
|
||||
isProd: !isDevelopment,
|
||||
amplitudeApiKey: isDevelopment
|
||||
? 'ca92bbcb548f7ec4b8ebe9194b8eda81'
|
||||
: '2b38c7ac93c0dccc83ebf9acc5107413',
|
||||
platform: PlatformName.web,
|
||||
projectName: 'base_web',
|
||||
showDebugLogging: isDevelopment,
|
||||
version: '1.0.0',
|
||||
apiEndpoint: 'https://cca-lite.coinbase.com',
|
||||
});
|
||||
|
||||
identify({ deviceId: 'base_web_device_id' });
|
||||
|
||||
initNextJsTrackPageview({
|
||||
nextJsRouter: router,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default initCCA;
|
||||
@@ -232,6 +232,7 @@ __metadata:
|
||||
"@rainbow-me/rainbowkit": ^1.0.4
|
||||
"@tsconfig/docusaurus": ^1.0.5
|
||||
docusaurus-node-polyfills: ^1.0.0
|
||||
dotenv: ^16.3.1
|
||||
express: ^4.18.2
|
||||
express-basic-auth: ^1.2.1
|
||||
kbar: ^0.1.0-beta.41
|
||||
@@ -11556,7 +11557,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:^16.0.3":
|
||||
"dotenv@npm:^16.0.3, dotenv@npm:^16.3.1":
|
||||
version: 16.3.1
|
||||
resolution: "dotenv@npm:16.3.1"
|
||||
checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd
|
||||
|
||||
Reference in New Issue
Block a user