mintlify 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/bin/local-preview/helper-commands/cleanCommand.js +8 -0
  2. package/bin/local-preview/helper-commands/cleanCommand.js.map +1 -0
  3. package/bin/local-preview/utils/listener.js +9 -6
  4. package/bin/local-preview/utils/listener.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/local-preview/utils/listener.ts +9 -6
  7. package/bin/local-preview/injectNav.js +0 -94
  8. package/bin/local-preview/injectNav.js.map +0 -1
  9. package/bin/mint/client/.babel-plugin-macrosrc.json +0 -5
  10. package/bin/mint/client/.babelrc +0 -4
  11. package/bin/mint/client/.editorconfig +0 -12
  12. package/bin/mint/client/.eslintrc.json +0 -7
  13. package/bin/mint/client/.prettierignore +0 -4
  14. package/bin/mint/client/.prettierrc +0 -14
  15. package/bin/mint/client/.vscode/launch.json +0 -28
  16. package/bin/mint/client/README.md +0 -44
  17. package/bin/mint/client/jest.config.ts +0 -195
  18. package/bin/mint/client/next-env.d.ts +0 -4
  19. package/bin/mint/client/next.config.js +0 -152
  20. package/bin/mint/client/package.json +0 -139
  21. package/bin/mint/client/postcss.config.cjs +0 -9
  22. package/bin/mint/client/prebuild/faviconConfig.js +0 -35
  23. package/bin/mint/client/prebuild/getOpenApiContext.js +0 -53
  24. package/bin/mint/client/prebuild/index.js +0 -117
  25. package/bin/mint/client/prebuild/injectNav.js +0 -115
  26. package/bin/mint/client/prebuild/slugToTitle.js +0 -7
  27. package/bin/mint/client/rehype/withApiComponents.js +0 -60
  28. package/bin/mint/client/rehype/withCodeBlocks.js +0 -54
  29. package/bin/mint/client/rehype/withLayouts.js +0 -113
  30. package/bin/mint/client/rehype/withLinkRoles.js +0 -13
  31. package/bin/mint/client/rehype/withRawComponents.js +0 -13
  32. package/bin/mint/client/rehype/withStaticProps.js +0 -25
  33. package/bin/mint/client/rehype/withSyntaxHighlighting.js +0 -60
  34. package/bin/mint/client/remark/utils.js +0 -369
  35. package/bin/mint/client/remark/withFrames.js +0 -55
  36. package/bin/mint/client/remark/withImportsInjected.js +0 -36
  37. package/bin/mint/client/remark/withNextLinks.js +0 -37
  38. package/bin/mint/client/remark/withTableOfContents.js +0 -71
  39. package/bin/mint/client/scripts/local.js +0 -177
  40. package/bin/mint/client/sentry.client.config.js +0 -15
  41. package/bin/mint/client/sentry.properties +0 -4
  42. package/bin/mint/client/sentry.server.config.js +0 -15
  43. package/bin/mint/client/src/analytics/AbstractAnalyticsImplementation.ts +0 -50
  44. package/bin/mint/client/src/analytics/AnalyticsContext.ts +0 -5
  45. package/bin/mint/client/src/analytics/AnalyticsMediator.ts +0 -101
  46. package/bin/mint/client/src/analytics/FakeAnalyticsMediator.ts +0 -9
  47. package/bin/mint/client/src/analytics/GA4Script.tsx +0 -33
  48. package/bin/mint/client/src/analytics/implementations/amplitude.ts +0 -26
  49. package/bin/mint/client/src/analytics/implementations/fathom.ts +0 -38
  50. package/bin/mint/client/src/analytics/implementations/ga4.ts +0 -33
  51. package/bin/mint/client/src/analytics/implementations/hotjar.ts +0 -53
  52. package/bin/mint/client/src/analytics/implementations/mixpanel-browser.d.ts +0 -1
  53. package/bin/mint/client/src/analytics/implementations/mixpanel.ts +0 -52
  54. package/bin/mint/client/src/analytics/implementations/posthog.ts +0 -37
  55. package/bin/mint/client/src/components/Accordion/Accordion.tsx +0 -43
  56. package/bin/mint/client/src/components/Accordion/index.ts +0 -4
  57. package/bin/mint/client/src/components/ApiExample.tsx +0 -9
  58. package/bin/mint/client/src/components/Card.tsx +0 -51
  59. package/bin/mint/client/src/components/CodeGroup.tsx +0 -132
  60. package/bin/mint/client/src/components/Editor.tsx +0 -12
  61. package/bin/mint/client/src/components/Expandable.tsx +0 -40
  62. package/bin/mint/client/src/components/Heading.tsx +0 -84
  63. package/bin/mint/client/src/components/Param.tsx +0 -56
  64. package/bin/mint/client/src/components/Request.tsx +0 -19
  65. package/bin/mint/client/src/components/ResponseField.tsx +0 -33
  66. package/bin/mint/client/src/components/TabBar.tsx +0 -61
  67. package/bin/mint/client/src/config.ts +0 -115
  68. package/bin/mint/client/src/css/bar-of-progress.css +0 -10
  69. package/bin/mint/client/src/css/base.css +0 -29
  70. package/bin/mint/client/src/css/font-awesome.css +0 -7
  71. package/bin/mint/client/src/css/fonts.css +0 -44
  72. package/bin/mint/client/src/css/main.css +0 -11
  73. package/bin/mint/client/src/css/prism.css +0 -270
  74. package/bin/mint/client/src/css/utilities.css +0 -43
  75. package/bin/mint/client/src/enums/components.ts +0 -8
  76. package/bin/mint/client/src/fonts/FiraCode-VF.woff +0 -0
  77. package/bin/mint/client/src/fonts/FiraCode-VF.woff2 +0 -0
  78. package/bin/mint/client/src/fonts/IBMPlexMono-Regular.ttf +0 -0
  79. package/bin/mint/client/src/fonts/IBMPlexMono-SemiBold.ttf +0 -0
  80. package/bin/mint/client/src/fonts/Inter-italic-latin.var.woff2 +0 -0
  81. package/bin/mint/client/src/fonts/Inter-roman-latin.var.woff2 +0 -0
  82. package/bin/mint/client/src/fonts/Pally-Variable.ttf +0 -0
  83. package/bin/mint/client/src/fonts/SourceSansPro-Regular.otf +0 -0
  84. package/bin/mint/client/src/fonts/SourceSerifPro-Regular.ttf +0 -0
  85. package/bin/mint/client/src/fonts/Synonym-Variable.ttf +0 -0
  86. package/bin/mint/client/src/fonts/Ubuntu-Mono-bold.woff2 +0 -0
  87. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.woff2 +0 -0
  88. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.zopfli.woff +0 -0
  89. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular.module.css +0 -11
  90. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.woff2 +0 -0
  91. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.zopfli.woff +0 -0
  92. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold.module.css +0 -11
  93. package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.woff2 +0 -0
  94. package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.zopfli.woff +0 -0
  95. package/bin/mint/client/src/fonts/generated/Pally-Variable.module.css +0 -11
  96. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.woff2 +0 -0
  97. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.zopfli.woff +0 -0
  98. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular.module.css +0 -11
  99. package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.woff2 +0 -0
  100. package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.zopfli.woff +0 -0
  101. package/bin/mint/client/src/fonts/generated/Synonym-Variable.module.css +0 -11
  102. package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.woff2 +0 -0
  103. package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.zopfli.woff +0 -0
  104. package/bin/mint/client/src/fonts/generated/TenorSans-Regular.module.css +0 -11
  105. package/bin/mint/client/src/hooks/useActionKey.ts +0 -20
  106. package/bin/mint/client/src/hooks/useIsomorphicLayoutEffect.ts +0 -3
  107. package/bin/mint/client/src/hooks/useMedia.ts +0 -27
  108. package/bin/mint/client/src/hooks/usePrevNext.ts +0 -34
  109. package/bin/mint/client/src/hooks/useTop.ts +0 -15
  110. package/bin/mint/client/src/icons/CopyToClipboard.tsx +0 -33
  111. package/bin/mint/client/src/index.d.ts +0 -1
  112. package/bin/mint/client/src/layouts/ApiSupplemental.tsx +0 -173
  113. package/bin/mint/client/src/layouts/ContentsLayout.tsx +0 -256
  114. package/bin/mint/client/src/layouts/DocumentationLayout.tsx +0 -44
  115. package/bin/mint/client/src/layouts/OpenApiContent.tsx +0 -301
  116. package/bin/mint/client/src/layouts/SidebarLayout.tsx +0 -412
  117. package/bin/mint/client/src/layouts/UserFeedback.tsx +0 -73
  118. package/bin/mint/client/src/layouts/getGroupsInDivision.ts +0 -25
  119. package/bin/mint/client/src/layouts/isPathInGroupPages.ts +0 -10
  120. package/bin/mint/client/src/metadata.ts +0 -58
  121. package/bin/mint/client/src/nav.json +0 -219
  122. package/bin/mint/client/src/openapi.ts +0 -3
  123. package/bin/mint/client/src/pages/404.tsx +0 -73
  124. package/bin/mint/client/src/pages/_app.tsx +0 -138
  125. package/bin/mint/client/src/pages/_document.tsx +0 -57
  126. package/bin/mint/client/src/pages/api/issue.ts +0 -10
  127. package/bin/mint/client/src/pages/api/name.ts +0 -8
  128. package/bin/mint/client/src/pages/api/request.ts +0 -31
  129. package/bin/mint/client/src/pages/api/suggest.ts +0 -10
  130. package/bin/mint/client/src/pages/api/syntax-highlighted-json.ts +0 -13
  131. package/bin/mint/client/src/pages/api/utils.ts +0 -6
  132. package/bin/mint/client/src/pages/index.tsx +0 -31
  133. package/bin/mint/client/src/ui/Api.tsx +0 -359
  134. package/bin/mint/client/src/ui/Footer.tsx +0 -124
  135. package/bin/mint/client/src/ui/Header.tsx +0 -370
  136. package/bin/mint/client/src/ui/Logo.tsx +0 -55
  137. package/bin/mint/client/src/ui/PageHeader.tsx +0 -51
  138. package/bin/mint/client/src/ui/Search.tsx +0 -386
  139. package/bin/mint/client/src/ui/ThemeToggle.tsx +0 -285
  140. package/bin/mint/client/src/ui/Title.tsx +0 -22
  141. package/bin/mint/client/src/ui/TopLevelLink.tsx +0 -122
  142. package/bin/mint/client/src/utils/api.ts +0 -252
  143. package/bin/mint/client/src/utils/brands.ts +0 -217
  144. package/bin/mint/client/src/utils/castArray.ts +0 -3
  145. package/bin/mint/client/src/utils/childrenArray.ts +0 -3
  146. package/bin/mint/client/src/utils/fit.ts +0 -27
  147. package/bin/mint/client/src/utils/fontAwesome.ts +0 -577
  148. package/bin/mint/client/src/utils/getAnalyticsConfig.ts +0 -14
  149. package/bin/mint/client/src/utils/getLogoHref.ts +0 -9
  150. package/bin/mint/client/src/utils/getOpenApiContext.ts +0 -26
  151. package/bin/mint/client/src/utils/importAll.ts +0 -6
  152. package/bin/mint/client/src/utils/isObject.ts +0 -3
  153. package/bin/mint/client/src/utils/kebabToTitleCase.ts +0 -3
  154. package/bin/mint/client/src/utils/loadImage.ts +0 -8
  155. package/bin/mint/client/src/utils/slugToTitle.ts +0 -7
  156. package/bin/mint/client/src/utils/wait.ts +0 -5
  157. package/bin/mint/client/tailwind.config.cjs +0 -323
  158. package/bin/mint/client/test/test.test.ts +0 -5
  159. package/bin/mint/client/tsconfig.json +0 -36
  160. package/bin/mint/client/yarn.lock +0 -9702
@@ -1,177 +0,0 @@
1
- import SwaggerParser from '@apidevtools/swagger-parser';
2
- import favicons from 'favicons';
3
- import { promises as _promises } from 'fs';
4
- import pkg, { remove } from 'fs-extra';
5
- import { dirname, resolve } from 'path';
6
- import { fileURLToPath } from 'url';
7
-
8
- import faviconConfig from '../prebuild/faviconConfig.js';
9
- import { createPage, injectNav } from '../prebuild/injectNav.js';
10
-
11
- const { outputFileSync, readFileSync } = pkg;
12
- const { readdir, readFile } = _promises;
13
-
14
- const path = process.argv[2] ?? '../docs';
15
-
16
- const __filename = fileURLToPath(import.meta.url);
17
- const __dirname = dirname(__filename);
18
-
19
- const getFileList = async (dirName, og = dirName) => {
20
- let files = [];
21
- const items = await readdir(resolve(dirName), { withFileTypes: true });
22
-
23
- for (const item of items) {
24
- if (item.isDirectory()) {
25
- files = [...files, ...(await getFileList(`${dirName}/${item.name}`, og))];
26
- } else {
27
- files.push(`${dirName}/${item.name}`);
28
- }
29
- }
30
-
31
- return files;
32
- };
33
-
34
- const getFiles = async () => {
35
- const fileList = await getFileList(path);
36
- const markdownFiles = [];
37
- const staticFiles = [];
38
- let config = undefined;
39
- let openApi = undefined;
40
- const promises = [];
41
- fileList.forEach((filename) => {
42
- promises.push(
43
- (async () => {
44
- const content = await readFile(resolve(filename));
45
- if (filename.endsWith('mint.config.json') || filename.endsWith('mint.json')) {
46
- config = content;
47
- return;
48
- }
49
- const absolutePath = filename.substring(path.length + 1);
50
- const extension =
51
- filename.substring(filename.lastIndexOf('.') + 1, filename.length) || filename;
52
- if (extension && (extension === 'mdx' || extension === 'md' || extension === 'tsx')) {
53
- markdownFiles.push({
54
- path: absolutePath,
55
- content: Buffer.from(content, 'base64'),
56
- });
57
- return;
58
- }
59
-
60
- if (extension === 'json' || extension === 'yaml' || extension === 'yml') {
61
- try {
62
- outputFileSync('openapi', Buffer.from(content, 'base64').toString('utf-8'));
63
- const api = await SwaggerParser.validate('openapi');
64
- openApi = Buffer.from(JSON.stringify(api, null, 2), 'utf-8');
65
- } catch {
66
- // not valid openApi
67
- }
68
- }
69
- // every other file
70
- staticFiles.push({
71
- path: absolutePath,
72
- content: Buffer.from(content, 'base64'),
73
- });
74
- })()
75
- );
76
- });
77
- await Promise.all(promises);
78
- return { markdownFiles, staticFiles, config, openApi };
79
- };
80
-
81
- const injectMarkdownFilesAndNav = (markdownFiles, configObj, openApiObj) => {
82
- let pages = {};
83
- markdownFiles.forEach((markdownFile) => {
84
- const path = __dirname + `/../src/pages/${markdownFile.path}`;
85
- const page = createPage(markdownFile.path, markdownFile.content, openApiObj);
86
- if (page != null) {
87
- pages = {
88
- ...pages,
89
- ...page,
90
- };
91
- }
92
- outputFileSync(path, Buffer.from(markdownFile.content), { flag: 'w' });
93
- });
94
-
95
- console.log(`📄 ${markdownFiles.length} pages injected`);
96
-
97
- injectNav(pages, configObj);
98
- };
99
-
100
- const injectStaticFiles = (staticFiles) => {
101
- staticFiles.forEach((staticFile) => {
102
- const path = __dirname + `/../public/${staticFile.path}`;
103
- outputFileSync(path, Buffer.from(staticFile.content), { flag: 'w' });
104
- });
105
-
106
- console.log(`📄 ${staticFiles.length} static files injected`);
107
- };
108
-
109
- const injectConfig = (config) => {
110
- const path = __dirname + `/../src/mint.json`;
111
- outputFileSync(path, Buffer.from(config), { flag: 'w' });
112
- console.log('⚙️ Config file set properly');
113
- };
114
-
115
- const injectOpenApi = (openApi) => {
116
- const path = __dirname + `/../src/openapi.json`;
117
- if (openApi) {
118
- outputFileSync(path, Buffer.from(openApi), { flag: 'w' });
119
- console.log('🖥️ OpenAPI file detected and set as openapi.json');
120
- return;
121
- }
122
- outputFileSync(path, '{}', { flag: 'w' });
123
- };
124
-
125
- const injectFavicons = async (config) => {
126
- const buffer = Buffer.from(config);
127
- const configJSON = JSON.parse(buffer.toString());
128
-
129
- if (configJSON?.favicon == null) return;
130
-
131
- const desiredPath = resolve(__dirname + `/../public/${configJSON.favicon}`);
132
- const favicon = readFileSync(desiredPath);
133
- if (favicon == null) return;
134
- console.log('Generating favicons...');
135
- favicons(favicon, faviconConfig(config?.name), (err, response) => {
136
- if (err) {
137
- console.log(err.message); // Error description e.g. "An unknown error has occurred"
138
- return;
139
- }
140
- response.images.forEach((img) => {
141
- const path = __dirname + `/../public/favicons/${img.name}`;
142
- outputFileSync(path, Buffer.from(img.contents), { flag: 'w' });
143
- });
144
- response.files.forEach((file) => {
145
- const path = __dirname + `/../public/favicons/${file.name}`;
146
- outputFileSync(path, file.contents, { flag: 'w' });
147
- });
148
- console.log('Favicons generated');
149
- });
150
- };
151
-
152
- const deleteExistingOpenApi = async () => {
153
- const path = __dirname + '/../openapi';
154
- await remove(path);
155
- };
156
-
157
- const getAllFilesAndConfig = async () => {
158
- await deleteExistingOpenApi();
159
- const { markdownFiles, staticFiles, config, openApi } = await getFiles();
160
- const openApiObj = openApi == null ? null : JSON.parse(openApi.toString());
161
- const configObj = JSON.parse(config.toString());
162
- injectMarkdownFilesAndNav(markdownFiles, configObj, openApiObj);
163
- injectStaticFiles(staticFiles);
164
- injectOpenApi(openApi);
165
- injectConfig(config);
166
- injectFavicons(config);
167
- };
168
-
169
- (async function () {
170
- try {
171
- console.log('🔍 Fetching files');
172
- await getAllFilesAndConfig();
173
- } catch (error) {
174
- console.log(error);
175
- console.error('⚠️ Error while prebuilding documents');
176
- }
177
- })();
@@ -1,15 +0,0 @@
1
- // This file configures the initialization of Sentry on the browser.
2
- // The config you add here will be used whenever a page is visited.
3
- // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
-
5
- import * as Sentry from '@sentry/nextjs';
6
-
7
- const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
-
9
- if (process.env.VERCEL_ENV === 'production') {
10
- Sentry.init({
11
- dsn: SENTRY_DSN || 'https://817b9178a3aa4a01b57a91160d3a24bb@o1352345.ingest.sentry.io/6633662',
12
- tracesSampleRate: 0.05,
13
- enabled: process.env.VERCEL_ENV === 'production',
14
- });
15
- }
@@ -1,4 +0,0 @@
1
- defaults.url=https://sentry.io/
2
- defaults.org=mintlify
3
- defaults.project=docs-frontend
4
- cli.executable=../../../.npm/_npx/a8388072043b4cbc/node_modules/@sentry/cli/bin/sentry-cli
@@ -1,15 +0,0 @@
1
- // This file configures the initialization of Sentry on the server.
2
- // The config you add here will be used whenever the server handles a request.
3
- // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
-
5
- import * as Sentry from '@sentry/nextjs';
6
-
7
- const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
-
9
- if (process.env.VERCEL_ENV === 'production') {
10
- Sentry.init({
11
- dsn: SENTRY_DSN || 'https://817b9178a3aa4a01b57a91160d3a24bb@o1352345.ingest.sentry.io/6633662',
12
- tracesSampleRate: 0.05,
13
- enabled: process.env.VERCEL_ENV === 'production',
14
- });
15
- }
@@ -1,50 +0,0 @@
1
- export type AmplitudeConfigInterface = {
2
- apiKey?: string;
3
- };
4
-
5
- export type FathomConfigInterface = {
6
- siteId?: string;
7
- };
8
-
9
- export type GoogleAnalyticsConfigInterface = {
10
- measurementId?: string;
11
- };
12
-
13
- export type HotjarConfigInterface = {
14
- hjid?: string;
15
- hjsv?: string;
16
- };
17
-
18
- export type MixpanelConfigInterface = {
19
- projectToken?: string;
20
- };
21
-
22
- export type PostHogConfigInterface = {
23
- apiKey?: string;
24
- apiHost?: string;
25
- };
26
-
27
- // We can use & instead of | because all keys are optional
28
- export type ConfigInterface = AmplitudeConfigInterface &
29
- FathomConfigInterface &
30
- GoogleAnalyticsConfigInterface &
31
- HotjarConfigInterface &
32
- MixpanelConfigInterface &
33
- PostHogConfigInterface;
34
-
35
- // TypeScript doesn't recommend setting interfaces on constructors.
36
- // How an object is constructed should not matter because an interface
37
- // only cares about what it does.
38
- export abstract class AbstractAnalyticsImplementation {
39
- // New implementations need their own config interface.
40
- abstract init(implementationConfig: ConfigInterface): void;
41
- createEventListener(eventName: string): (eventProperties: object) => Promise<void> {
42
- return async function doNothing(_: object) {};
43
- }
44
- onRouteChange(url: string, routeProps: any): void {}
45
- }
46
-
47
- export type AnalyticsMediatorInterface = {
48
- createEventListener: (eventName: string) => (eventConfig: object) => Promise<void>;
49
- onRouteChange: (url: string, routeProps: any) => void;
50
- };
@@ -1,5 +0,0 @@
1
- import { createContext } from 'react';
2
- import { AnalyticsMediatorInterface } from './AbstractAnalyticsImplementation';
3
-
4
- const AnalyticsContext = createContext({} as AnalyticsMediatorInterface);
5
- export default AnalyticsContext;
@@ -1,101 +0,0 @@
1
- import * as Sentry from '@sentry/nextjs';
2
-
3
- import {
4
- AmplitudeConfigInterface,
5
- AbstractAnalyticsImplementation,
6
- AnalyticsMediatorInterface,
7
- FathomConfigInterface,
8
- HotjarConfigInterface,
9
- MixpanelConfigInterface,
10
- PostHogConfigInterface,
11
- GoogleAnalyticsConfigInterface,
12
- } from '@/analytics/AbstractAnalyticsImplementation';
13
- import PostHogAnalytics from '@/analytics/implementations/posthog';
14
-
15
- import AmplitudeAnalytics from './implementations/amplitude';
16
- import FathomAnalytics from './implementations/fathom';
17
- import GA4Analytics from './implementations/ga4';
18
- import HotjarAnalytics from './implementations/hotjar';
19
- import MixpanelAnalytics from './implementations/mixpanel';
20
-
21
- export type AnalyticsMediatorConstructorInterface = {
22
- amplitude?: AmplitudeConfigInterface;
23
- fathom?: FathomConfigInterface;
24
- ga4?: GoogleAnalyticsConfigInterface;
25
- hotjar?: HotjarConfigInterface;
26
- mixpanel?: MixpanelConfigInterface;
27
- posthog?: PostHogConfigInterface;
28
- };
29
-
30
- export default class AnalyticsMediator implements AnalyticsMediatorInterface {
31
- analyticsIntegrations: AbstractAnalyticsImplementation[] = [];
32
-
33
- constructor(analytics?: AnalyticsMediatorConstructorInterface) {
34
- // Ran first so we can assign the Sentry tags to false when not set.
35
- const amplitudeEnabled = Boolean(analytics?.amplitude?.apiKey);
36
- const fathomEnabled = Boolean(analytics?.fathom?.siteId);
37
- const ga4Enabled = Boolean(analytics?.ga4?.measurementId);
38
- const hotjarEnabled = Boolean(analytics?.hotjar?.hjid && analytics?.hotjar?.hjsv);
39
- const mixpanelEnabled = Boolean(analytics?.mixpanel?.projectToken);
40
- const posthogEnabled = Boolean(analytics?.posthog?.apiKey);
41
- Sentry.setTag('amplitude_enabled', `${amplitudeEnabled}`);
42
- Sentry.setTag('fathom_enabled', `${fathomEnabled}`);
43
- Sentry.setTag('ga4_enabled', `${ga4Enabled}`);
44
- Sentry.setTag('hotjar_enabled', `${hotjarEnabled}`);
45
- Sentry.setTag('mixpanel_enabled', `${mixpanelEnabled}`);
46
- Sentry.setTag('posthog_enabled', `${posthogEnabled}`);
47
-
48
- if (!analytics || Object.keys(analytics).length === 0) {
49
- return;
50
- }
51
-
52
- if (amplitudeEnabled) {
53
- const amplitude = new AmplitudeAnalytics();
54
- amplitude.init(analytics.amplitude!);
55
- this.analyticsIntegrations.push(amplitude);
56
- }
57
-
58
- if (fathomEnabled) {
59
- const fathom = new FathomAnalytics();
60
- fathom.init(analytics.fathom!);
61
- this.analyticsIntegrations.push(fathom);
62
- }
63
-
64
- if (ga4Enabled) {
65
- const ga4 = new GA4Analytics();
66
- ga4.init(analytics.ga4!);
67
- this.analyticsIntegrations.push(ga4);
68
- }
69
-
70
- if (hotjarEnabled) {
71
- const hotjar = new HotjarAnalytics();
72
- hotjar.init(analytics.hotjar!);
73
- this.analyticsIntegrations.push(hotjar);
74
- }
75
-
76
- if (posthogEnabled) {
77
- const posthog = new PostHogAnalytics();
78
- posthog.init(analytics.posthog!);
79
- this.analyticsIntegrations.push(posthog);
80
- }
81
-
82
- if (mixpanelEnabled) {
83
- const mixpanel = new MixpanelAnalytics();
84
- mixpanel.init(analytics.mixpanel!);
85
- this.analyticsIntegrations.push(mixpanel);
86
- }
87
- }
88
-
89
- createEventListener(eventName: string) {
90
- const listeners = this.analyticsIntegrations.map((integration) =>
91
- integration.createEventListener(eventName)
92
- );
93
- return async function (eventConfig: object) {
94
- listeners.forEach((listener) => listener(eventConfig));
95
- };
96
- }
97
-
98
- onRouteChange(url: string, routeProps: any) {
99
- this.analyticsIntegrations.forEach((integration) => integration.onRouteChange(url, routeProps));
100
- }
101
- }
@@ -1,9 +0,0 @@
1
- import { AnalyticsMediatorInterface } from './AbstractAnalyticsImplementation';
2
-
3
- export default class FakeAnalyticsMediator implements AnalyticsMediatorInterface {
4
- createEventListener(_: string) {
5
- return async function () {};
6
- }
7
-
8
- onRouteChange(_: string, __: any) {}
9
- }
@@ -1,33 +0,0 @@
1
- import Script from 'next/script';
2
-
3
- import { GoogleAnalyticsConfigInterface } from './AbstractAnalyticsImplementation';
4
-
5
- export default function GA4Script({ ga4 }: { ga4?: GoogleAnalyticsConfigInterface }) {
6
- if (!ga4?.measurementId || process.env.NODE_ENV !== 'production') {
7
- return null;
8
- }
9
-
10
- // There is no npm package for Google Analytics 4 so set up happens by placing this script.
11
- // We can send events using window.gtag.
12
- return (
13
- <>
14
- <Script
15
- strategy="afterInteractive"
16
- src={`https://www.googletagmanager.com/gtag/js?id=${ga4.measurementId}`}
17
- />
18
- <Script
19
- strategy="afterInteractive"
20
- dangerouslySetInnerHTML={{
21
- __html: `
22
- window.dataLayer = window.dataLayer || [];
23
- function gtag(){dataLayer.push(arguments);}
24
- gtag('js', new Date());
25
- gtag('config', '${ga4.measurementId}', {
26
- page_path: window.location.pathname,
27
- });
28
- `,
29
- }}
30
- />
31
- </>
32
- );
33
- }
@@ -1,26 +0,0 @@
1
- import { init as amplitudeInit, track } from '@amplitude/analytics-browser';
2
-
3
- import {
4
- AbstractAnalyticsImplementation,
5
- ConfigInterface,
6
- } from '@/analytics/AbstractAnalyticsImplementation';
7
-
8
- export default class AmplitudeAnalytics extends AbstractAnalyticsImplementation {
9
- initialized = false;
10
-
11
- init(implementationConfig: ConfigInterface) {
12
- if (implementationConfig?.apiKey && process.env.NODE_ENV === 'production') {
13
- amplitudeInit(implementationConfig.apiKey);
14
- this.initialized = true;
15
- }
16
- }
17
-
18
- createEventListener(eventName: string) {
19
- if (this.initialized) {
20
- return async function capture(eventProperties: object) {
21
- track(eventName, eventProperties);
22
- };
23
- }
24
- return async function doNothing(_: object) {};
25
- }
26
- }
@@ -1,38 +0,0 @@
1
- import * as Sentry from '@sentry/nextjs';
2
-
3
- import {
4
- AbstractAnalyticsImplementation,
5
- ConfigInterface,
6
- } from '@/analytics/AbstractAnalyticsImplementation';
7
-
8
- export default class FathomAnalytics extends AbstractAnalyticsImplementation {
9
- initialized = false;
10
- trackPageview: any;
11
-
12
- init(implementationConfig: ConfigInterface) {
13
- if (implementationConfig.siteId && process.env.NODE_ENV === 'production') {
14
- import('fathom-client')
15
- .then((_fathom) => {
16
- if (!this.initialized) {
17
- _fathom.load(implementationConfig.siteId!);
18
-
19
- // The Fathom library uses asterisk imports (ie. * as Fathom)
20
- // so there is no default export for us to store a reference to.
21
- // Instead, we keep a reference to the method we need.
22
- this.trackPageview = _fathom.trackPageview;
23
-
24
- this.initialized = true;
25
- }
26
- })
27
- .catch((e) => {
28
- Sentry.captureException(e);
29
- });
30
- }
31
- }
32
-
33
- onRouteChange(_: string, routeProps: any) {
34
- if (this.trackPageview && !routeProps.shallow) {
35
- this.trackPageview();
36
- }
37
- }
38
- }
@@ -1,33 +0,0 @@
1
- import {
2
- AbstractAnalyticsImplementation,
3
- ConfigInterface,
4
- } from '@/analytics/AbstractAnalyticsImplementation';
5
-
6
- export default class GA4Analytics extends AbstractAnalyticsImplementation {
7
- measurementId: string | undefined;
8
-
9
- init(implementationConfig: ConfigInterface) {
10
- // GA4 setup happens by placing GA4Script.
11
- // This implementation only exists to send custom events using window.gtag.
12
- if (process.env.NODE_ENV === 'production') {
13
- this.measurementId = implementationConfig.measurementId;
14
- }
15
- }
16
-
17
- createEventListener(eventName: string) {
18
- if (this.measurementId && (window as any).gtag) {
19
- return async function capture(_: object) {
20
- (window as any).gtag('event', eventName, {});
21
- };
22
- }
23
- return async function doNothing(_: object) {};
24
- }
25
-
26
- onRouteChange(url: string): void {
27
- if (this.measurementId && (window as any).gtag) {
28
- (window as any).gtag('config', this.measurementId, {
29
- page_path: url,
30
- });
31
- }
32
- }
33
- }
@@ -1,53 +0,0 @@
1
- import * as Sentry from '@sentry/nextjs';
2
-
3
- import {
4
- AbstractAnalyticsImplementation,
5
- ConfigInterface,
6
- } from '@/analytics/AbstractAnalyticsImplementation';
7
-
8
- export default class HotjarAnalytics extends AbstractAnalyticsImplementation {
9
- initialized = false;
10
-
11
- // Store events to submit after the library is loaded.
12
- waitTracking: string[] = [];
13
- hotjar = {
14
- event: (name: string) => this.waitTracking.push(name),
15
- } as any;
16
-
17
- init(implementationConfig: ConfigInterface) {
18
- if (
19
- implementationConfig?.hjid &&
20
- implementationConfig?.hjsv &&
21
- process.env.NODE_ENV === 'production'
22
- ) {
23
- const hjid = parseInt(implementationConfig.hjid, 10);
24
- const hjsv = parseInt(implementationConfig.hjsv, 10);
25
-
26
- import('react-hotjar')
27
- .then((_hotjar) => {
28
- if (!this.initialized) {
29
- // Get default module export
30
- this.hotjar = _hotjar;
31
- this.hotjar.initialize(hjid, hjsv);
32
- this.initialized = true;
33
-
34
- this.waitTracking.forEach((eventName) => {
35
- this.hotjar.event(eventName);
36
- });
37
- }
38
-
39
- return this.hotjar;
40
- })
41
- .catch((e) => {
42
- Sentry.captureException(e);
43
- });
44
- }
45
- }
46
-
47
- createEventListener(eventName: string) {
48
- const captureFunc = async function capture(this: HotjarAnalytics, _: object) {
49
- this.hotjar.event(eventName);
50
- };
51
- return captureFunc.bind(this);
52
- }
53
- }
@@ -1 +0,0 @@
1
- declare module 'mixpanel-browser';
@@ -1,52 +0,0 @@
1
- import * as Sentry from '@sentry/nextjs';
2
-
3
- import {
4
- AbstractAnalyticsImplementation,
5
- ConfigInterface,
6
- } from '@/analytics/AbstractAnalyticsImplementation';
7
-
8
- export default class MixpanelAnalytics extends AbstractAnalyticsImplementation {
9
- initialized = false;
10
-
11
- // Store events to submit after the library is loaded.
12
- waitTracking: { name: string; properties: object }[] = [];
13
- mixpanel = {
14
- track: (name: string, properties: object) => this.waitTracking.push({ name, properties }),
15
- } as any;
16
-
17
- init(implementationConfig: ConfigInterface) {
18
- if (implementationConfig.projectToken && process.env.NODE_ENV === 'production') {
19
- // Dynamic import reduces our First Load JS by 18 kB
20
- import('mixpanel-browser')
21
- .then((_mixpanel) => {
22
- if (!this.initialized) {
23
- // Get default module export
24
- const mixpanelLib = _mixpanel.default;
25
- mixpanelLib.init(implementationConfig.projectToken, {
26
- secure_cookie: true,
27
- });
28
-
29
- this.initialized = true;
30
- this.mixpanel = mixpanelLib;
31
-
32
- this.waitTracking.forEach((event) => {
33
- this.mixpanel.track(event.name, event.properties);
34
- });
35
- }
36
- })
37
- .catch((e) => {
38
- Sentry.captureException(e);
39
- });
40
- } else {
41
- // Stop storing events, we don't need them because the library will not be loaded.
42
- this.mixpanel.track = (_name: string, _properties: object) => {};
43
- }
44
- }
45
-
46
- createEventListener(eventName: string) {
47
- const captureFunc = async function capture(this: MixpanelAnalytics, eventProperties: object) {
48
- this.mixpanel.track(eventName, eventProperties);
49
- };
50
- return captureFunc.bind(this);
51
- }
52
- }
@@ -1,37 +0,0 @@
1
- import Router from 'next/router';
2
- import posthog from 'posthog-js';
3
-
4
- import {
5
- AbstractAnalyticsImplementation,
6
- ConfigInterface,
7
- } from '@/analytics/AbstractAnalyticsImplementation';
8
-
9
- export default class PostHogAnalytics extends AbstractAnalyticsImplementation {
10
- initialized = false;
11
-
12
- init(implementationConfig: ConfigInterface) {
13
- if (implementationConfig.apiKey && !this.initialized) {
14
- this.initialized = true;
15
- // apiHost only has to be passed in if the user is self-hosting PostHog
16
- posthog.init(implementationConfig.apiKey, {
17
- api_host: implementationConfig.apiHost || 'https://app.posthog.com',
18
- loaded: (posthogInstance) => {
19
- if (process.env.NODE_ENV !== 'production') posthogInstance.opt_out_capturing();
20
- },
21
- });
22
-
23
- // Track page views
24
- const handleRouteChange = () => posthog.capture('$pageview');
25
- Router.events.on('routeChangeComplete', handleRouteChange);
26
- }
27
- }
28
-
29
- createEventListener(eventName: string) {
30
- if (this.initialized) {
31
- return async function capture(eventProperties: object) {
32
- posthog.capture(eventName, eventProperties);
33
- };
34
- }
35
- return async function doNothing(_: object) {};
36
- }
37
- }