@heyo-sh/create-heyo-docs 1.0.1 → 3.0.0

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 (118) hide show
  1. package/deployments/cloudflare/astro/package.json +2 -1
  2. package/deployments/cloudflare/astro/src/env.d.ts +2 -1
  3. package/deployments/cloudflare/astro/src/pages/heyo-docs-internal/ai-chat.ts +9 -7
  4. package/deployments/cloudflare/next/app/heyo-docs-internal/ai-chat/route.ts +9 -7
  5. package/deployments/cloudflare/next/cloudflare-env.d.ts +2 -1
  6. package/deployments/cloudflare/react-router/app/cloudflare-env.d.ts +2 -1
  7. package/deployments/cloudflare/react-router/app/routes/ai-chat.ts +9 -8
  8. package/deployments/cloudflare/react-router/package.json +2 -1
  9. package/deployments/vercel/astro/package.json +1 -0
  10. package/dist/index.js +24 -4
  11. package/dist/scaffold.d.ts.map +1 -1
  12. package/dist/utils.d.ts.map +1 -1
  13. package/package.json +1 -1
  14. package/templates/astro/content/index.mdx +8 -0
  15. package/templates/astro/heyo-docs.config.ts +4 -48
  16. package/templates/astro/src/components/docs-app.tsx +30 -130
  17. package/templates/astro/src/heyo-docs-icons.tsx +3 -1
  18. package/templates/astro/src/layouts/docs-layout.astro +10 -436
  19. package/templates/astro/src/lib/docs.ts +3 -2
  20. package/templates/astro/src/lib/openapi-request.ts +6 -146
  21. package/templates/astro/src/pages/[...slug].astro +7 -15
  22. package/templates/astro/src/pages/[...slug].md.ts +4 -1
  23. package/templates/astro/src/pages/heyo-docs-internal/ai-chat.ts +5 -7
  24. package/templates/astro/src/pages/heyo-docs-internal/openapi-request.ts +6 -0
  25. package/templates/astro/src/pages/index.astro +18 -9
  26. package/templates/astro/src/pages/llms-full.txt.ts +1 -1
  27. package/templates/astro/src/pages/llms.txt.ts +1 -1
  28. package/templates/astro/src/pages/rss.xml.ts +1 -1
  29. package/templates/astro/src/pages/sitemap.xml.ts +2 -2
  30. package/templates/astro/src/virtual.d.ts +5 -5
  31. package/templates/next/app/[[...slug]]/page.tsx +10 -9
  32. package/templates/next/app/components/docs-app.tsx +28 -120
  33. package/templates/next/app/heyo-docs-icons.tsx +1 -1
  34. package/templates/next/app/heyo-docs-internal/ai-chat/route.ts +6 -7
  35. package/templates/next/app/heyo-docs-internal/markdown/[[...slug]]/route.ts +1 -1
  36. package/templates/next/app/layout.tsx +25 -444
  37. package/templates/next/app/lib/docs.ts +3 -3
  38. package/templates/next/app/lib/openapi-request.ts +4 -136
  39. package/templates/next/app/llms-full.txt/route.ts +1 -1
  40. package/templates/next/app/llms.txt/route.ts +1 -1
  41. package/templates/next/app/rss.xml/route.ts +1 -1
  42. package/templates/next/app/sitemap.xml/route.ts +1 -1
  43. package/templates/next/content/index.mdx +8 -0
  44. package/templates/next/heyo-docs.config.ts +3 -47
  45. package/templates/next/next.config.ts +7 -1
  46. package/templates/react-router/app/heyo-docs-icons.tsx +3 -1
  47. package/templates/react-router/app/root.tsx +28 -465
  48. package/templates/react-router/app/routes/ai-chat.ts +4 -8
  49. package/templates/react-router/app/routes/docs.tsx +22 -63
  50. package/templates/react-router/app/routes/home.tsx +6 -1
  51. package/templates/react-router/app/routes/llms-full.ts +1 -1
  52. package/templates/react-router/app/routes/llms.ts +1 -1
  53. package/templates/react-router/app/routes/markdown.ts +4 -1
  54. package/templates/react-router/app/routes/openapi-request.ts +11 -144
  55. package/templates/react-router/app/routes/rss.ts +1 -1
  56. package/templates/react-router/app/routes/sitemap.ts +5 -8
  57. package/templates/react-router/app/virtual.d.ts +5 -5
  58. package/templates/react-router/content/index.mdx +8 -0
  59. package/templates/react-router/heyo-docs.config.ts +4 -48
  60. package/templates/astro/content/api-overview.mdx +0 -20
  61. package/templates/astro/content/assets/local-architecture.svg +0 -22
  62. package/templates/astro/content/assets/quick-reference.txt +0 -5
  63. package/templates/astro/content/changelog.mdx +0 -38
  64. package/templates/astro/content/configuration.mdx +0 -117
  65. package/templates/astro/content/deploying.mdx +0 -70
  66. package/templates/astro/content/essentials/callouts.mdx +0 -34
  67. package/templates/astro/content/essentials/code-blocks.mdx +0 -43
  68. package/templates/astro/content/essentials/lists.mdx +0 -36
  69. package/templates/astro/content/essentials/tables.mdx +0 -30
  70. package/templates/astro/content/essentials/tabs.mdx +0 -40
  71. package/templates/astro/content/essentials/text-styling.mdx +0 -43
  72. package/templates/astro/content/getting-started.mdx +0 -16
  73. package/templates/astro/content/mdx-components.mdx +0 -44
  74. package/templates/astro/content/openapi-petstore.json +0 -160
  75. package/templates/astro/content/openapi.json +0 -278
  76. package/templates/astro/content/quickstart.mdx +0 -60
  77. package/templates/astro/src/components/theme-provider.tsx +0 -106
  78. package/templates/astro/src/lib/seo.ts +0 -221
  79. package/templates/astro/src/lib/theme.ts +0 -74
  80. package/templates/next/app/components/theme-provider.tsx +0 -93
  81. package/templates/next/app/lib/seo.ts +0 -189
  82. package/templates/next/app/lib/theme.ts +0 -61
  83. package/templates/next/content/api-overview.mdx +0 -20
  84. package/templates/next/content/assets/local-architecture.svg +0 -22
  85. package/templates/next/content/assets/quick-reference.txt +0 -5
  86. package/templates/next/content/changelog.mdx +0 -38
  87. package/templates/next/content/configuration.mdx +0 -117
  88. package/templates/next/content/deploying.mdx +0 -70
  89. package/templates/next/content/essentials/callouts.mdx +0 -34
  90. package/templates/next/content/essentials/code-blocks.mdx +0 -43
  91. package/templates/next/content/essentials/lists.mdx +0 -36
  92. package/templates/next/content/essentials/tables.mdx +0 -30
  93. package/templates/next/content/essentials/tabs.mdx +0 -40
  94. package/templates/next/content/essentials/text-styling.mdx +0 -43
  95. package/templates/next/content/getting-started.mdx +0 -16
  96. package/templates/next/content/mdx-components.mdx +0 -41
  97. package/templates/next/content/openapi-petstore.json +0 -160
  98. package/templates/next/content/openapi.json +0 -278
  99. package/templates/next/content/quickstart.mdx +0 -60
  100. package/templates/react-router/app/components/theme-provider.tsx +0 -106
  101. package/templates/react-router/app/lib/theme.ts +0 -74
  102. package/templates/react-router/content/api-overview.mdx +0 -20
  103. package/templates/react-router/content/assets/local-architecture.svg +0 -22
  104. package/templates/react-router/content/assets/quick-reference.txt +0 -5
  105. package/templates/react-router/content/changelog.mdx +0 -38
  106. package/templates/react-router/content/configuration.mdx +0 -117
  107. package/templates/react-router/content/deploying.mdx +0 -70
  108. package/templates/react-router/content/essentials/callouts.mdx +0 -34
  109. package/templates/react-router/content/essentials/code-blocks.mdx +0 -43
  110. package/templates/react-router/content/essentials/lists.mdx +0 -36
  111. package/templates/react-router/content/essentials/tables.mdx +0 -30
  112. package/templates/react-router/content/essentials/tabs.mdx +0 -40
  113. package/templates/react-router/content/essentials/text-styling.mdx +0 -43
  114. package/templates/react-router/content/getting-started.mdx +0 -16
  115. package/templates/react-router/content/mdx-components.mdx +0 -293
  116. package/templates/react-router/content/openapi-petstore.json +0 -160
  117. package/templates/react-router/content/openapi.json +0 -278
  118. package/templates/react-router/content/quickstart.mdx +0 -60
@@ -1,82 +1,22 @@
1
1
  import type { Metadata } from "next";
2
2
  import type { ReactNode } from "react";
3
- import { adobeAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/adobe";
4
- import { amplitudeAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/amplitude";
5
- import { clarityBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/clarity";
6
- import { clearbitAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/clearbit";
7
- import { fathomAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/fathom";
3
+ import { ThemeProvider } from "@heyo-sh/heyo-docs/theme/provider";
8
4
  import {
9
- googleAnalyticsBootstrapScript,
10
- googleAnalyticsScript,
11
- } from "@heyo-sh/heyo-docs/integrations/analytics/google-analytics";
12
- import {
13
- googleTagManagerBootstrapScript,
14
- googleTagManagerNoScriptUrl,
15
- } from "@heyo-sh/heyo-docs/integrations/analytics/google-tag-manager";
16
- import { heapBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/heap";
17
- import { hotjarBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/hotjar";
18
- import {
19
- logRocketBootstrapScript,
20
- logRocketScript,
21
- } from "@heyo-sh/heyo-docs/integrations/analytics/logrocket";
22
- import {
23
- mixpanelBootstrapScript,
24
- mixpanelScript,
25
- } from "@heyo-sh/heyo-docs/integrations/analytics/mixpanel";
26
- import {
27
- openpanelBootstrapScript,
28
- openpanelScript,
29
- } from "@heyo-sh/heyo-docs/integrations/analytics/openpanel";
30
- import { openReplayBootstrapScript } from "@heyo-sh/heyo-docs/integrations/analytics/openreplay";
31
- import { osanoConsentScript } from "@heyo-sh/heyo-docs/integrations/consent/osano";
32
- import {
33
- transcendConsentScript,
34
- transcendGoogleConsentModeDefaultsScript,
35
- } from "@heyo-sh/heyo-docs/integrations/consent/transcend";
36
- import { pirschAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/pirsch";
37
- import { plausibleAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/plausible";
38
- import {
39
- posthogApiHost,
40
- posthogBootstrapScript,
41
- posthogScript,
42
- } from "@heyo-sh/heyo-docs/integrations/analytics/posthog";
43
- import { rybbitAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/rybbit";
44
- import {
45
- swetrixBootstrapScript,
46
- swetrixScript,
47
- } from "@heyo-sh/heyo-docs/integrations/analytics/swetrix";
48
- import { chaskiqBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/chaskiq";
49
- import { chatwootBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/chatwoot";
50
- import {
51
- frontChatBootstrapScript,
52
- frontChatScript,
53
- } from "@heyo-sh/heyo-docs/integrations/support/front";
54
- import { intercomBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/intercom";
55
- import { papercupsBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/papercups";
56
- import { typebotBootstrapScript } from "@heyo-sh/heyo-docs/integrations/support/typebot";
57
- import { umamiAnalyticsScript } from "@heyo-sh/heyo-docs/integrations/analytics/umami";
58
- import {
59
- zammadBootstrapScript,
60
- zammadChatScript,
61
- } from "@heyo-sh/heyo-docs/integrations/support/zammad";
5
+ DEFAULT_THEME_STORAGE_KEY,
6
+ themeBootstrapScript,
7
+ } from "@heyo-sh/heyo-docs/theme/script";
8
+ import { IntegrationScripts } from "@heyo-sh/heyo-docs/integrations";
9
+ import { nextSiteSeo } from "@heyo-sh/heyo-docs/seo/next";
10
+ import { serializeJsonLd } from "@heyo-sh/heyo-docs/seo";
62
11
 
63
12
  import config from "../heyo-docs.config";
64
- import "./app.css";
65
13
  import "./_heyo-docs/theme.css";
66
- import { ThemeProvider } from "./components/theme-provider";
67
- import { getThemeScript, THEME_STORAGE_KEY } from "./lib/theme";
14
+ import "./app.css";
15
+
16
+ const siteSeo = nextSiteSeo(config);
68
17
 
69
18
  export const metadata: Metadata = {
70
- ...(config.siteUrl ? { metadataBase: new URL(config.siteUrl) } : {}),
71
- title: config.title,
72
- description: config.description,
73
- robots: { index: true, follow: true },
74
- alternates: {
75
- ...(config.siteUrl ? { canonical: "/" } : {}),
76
- ...(config.groups.some((group) => group.type === "changelog")
77
- ? { types: { "application/rss+xml": "/rss.xml" } }
78
- : {}),
79
- },
19
+ ...siteSeo.metadata,
80
20
  manifest: "/site.webmanifest",
81
21
  icons: {
82
22
  icon: [
@@ -88,402 +28,43 @@ export const metadata: Metadata = {
88
28
  { url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
89
29
  ],
90
30
  },
91
- openGraph: {
92
- type: "website",
93
- siteName: config.title,
94
- title: config.title,
95
- description: config.description,
96
- ...(config.siteUrl ? { url: config.siteUrl } : {}),
97
- },
98
- twitter: {
99
- card: "summary",
100
- title: config.title,
101
- description: config.description,
102
- },
103
31
  };
104
32
 
105
- const osano = config.integrations.consent.osano
106
- ? osanoConsentScript(config.integrations.consent.osano)
107
- : undefined;
108
- const transcend = config.integrations.consent.transcend
109
- ? transcendConsentScript(config.integrations.consent.transcend)
110
- : undefined;
111
- const transcendGoogleConsentDefaults =
112
- transcend &&
113
- (config.integrations.analytics.ga4 || config.integrations.analytics.gtm)
114
- ? transcendGoogleConsentModeDefaultsScript()
115
- : undefined;
116
- const adobe = config.integrations.analytics.adobe
117
- ? adobeAnalyticsScript(config.integrations.analytics.adobe)
118
- : undefined;
119
- const amplitude = config.integrations.analytics.amplitude
120
- ? amplitudeAnalyticsScript(config.integrations.analytics.amplitude)
121
- : undefined;
122
- const clarity = config.integrations.analytics.clarity
123
- ? clarityBootstrapScript()
124
- : undefined;
125
- const clearbit = config.integrations.analytics.clearbit
126
- ? clearbitAnalyticsScript(config.integrations.analytics.clearbit)
127
- : undefined;
128
- const fathom = config.integrations.analytics.fathom
129
- ? fathomAnalyticsScript(config.integrations.analytics.fathom)
130
- : undefined;
131
- const googleAnalytics = config.integrations.analytics.ga4
132
- ? googleAnalyticsScript(config.integrations.analytics.ga4)
133
- : undefined;
134
- const googleAnalyticsBootstrap = googleAnalytics
135
- ? googleAnalyticsBootstrapScript()
136
- : undefined;
137
- const googleTagManager = config.integrations.analytics.gtm
138
- ? googleTagManagerBootstrapScript()
139
- : undefined;
140
- const googleTagManagerNoScript = config.integrations.analytics.gtm
141
- ? googleTagManagerNoScriptUrl(config.integrations.analytics.gtm)
142
- : undefined;
143
- const heap = config.integrations.analytics.heap
144
- ? heapBootstrapScript()
145
- : undefined;
146
- const hotjar = config.integrations.analytics.hotjar
147
- ? hotjarBootstrapScript()
148
- : undefined;
149
- const logRocket = config.integrations.analytics.logrocket
150
- ? logRocketScript()
151
- : undefined;
152
- const logRocketBootstrap = logRocket ? logRocketBootstrapScript() : undefined;
153
- const mixpanel = config.integrations.analytics.mixpanel
154
- ? mixpanelScript()
155
- : undefined;
156
- const mixpanelBootstrap = mixpanel ? mixpanelBootstrapScript() : undefined;
157
- const openpanel = config.integrations.analytics.openpanel
158
- ? openpanelScript()
159
- : undefined;
160
- const openpanelBootstrap = openpanel ? openpanelBootstrapScript() : undefined;
161
- const openReplay = config.integrations.analytics.openreplay
162
- ? openReplayBootstrapScript()
163
- : undefined;
164
- const pirsch = config.integrations.analytics.pirsch
165
- ? pirschAnalyticsScript(config.integrations.analytics.pirsch)
166
- : undefined;
167
- const plausible = config.integrations.analytics.plausible
168
- ? plausibleAnalyticsScript(config.integrations.analytics.plausible)
169
- : undefined;
170
- const posthog = config.integrations.analytics.posthog
171
- ? posthogScript(config.integrations.analytics.posthog)
172
- : undefined;
173
- const posthogBootstrap = posthog ? posthogBootstrapScript() : undefined;
174
- const posthogHost = config.integrations.analytics.posthog
175
- ? posthogApiHost(config.integrations.analytics.posthog)
176
- : undefined;
177
- const rybbit = config.integrations.analytics.rybbit
178
- ? rybbitAnalyticsScript(config.integrations.analytics.rybbit)
179
- : undefined;
180
- const swetrix = config.integrations.analytics.swetrix
181
- ? swetrixScript()
182
- : undefined;
183
- const swetrixBootstrap = swetrix ? swetrixBootstrapScript() : undefined;
184
- const umami = config.integrations.analytics.umami
185
- ? umamiAnalyticsScript(config.integrations.analytics.umami)
186
- : undefined;
187
- const intercom = config.integrations.support.intercom
188
- ? intercomBootstrapScript()
189
- : undefined;
190
- const front = config.integrations.support.front ? frontChatScript() : undefined;
191
- const frontBootstrap = front ? frontChatBootstrapScript() : undefined;
192
- const chatwoot = config.integrations.support.chatwoot
193
- ? chatwootBootstrapScript()
194
- : undefined;
195
- const chaskiq = config.integrations.support.chaskiq
196
- ? chaskiqBootstrapScript()
197
- : undefined;
198
- const papercups = config.integrations.support.papercups
199
- ? papercupsBootstrapScript()
200
- : undefined;
201
- const typebot = config.integrations.support.typebot
202
- ? typebotBootstrapScript()
203
- : undefined;
204
- const zammad = config.integrations.support.zammad
205
- ? zammadChatScript(config.integrations.support.zammad)
206
- : undefined;
207
- const zammadBootstrap = zammad ? zammadBootstrapScript() : undefined;
208
-
209
33
  export default function RootLayout({ children }: { children: ReactNode }) {
210
34
  return (
211
35
  <html lang="en" suppressHydrationWarning>
212
36
  <head>
213
- {transcendGoogleConsentDefaults && (
214
- <script
215
- dangerouslySetInnerHTML={{
216
- __html: transcendGoogleConsentDefaults,
217
- }}
218
- />
219
- )}
220
- {transcend && (
221
- <script data-cfasync={transcend.dataCfasync} src={transcend.src} />
222
- )}
223
37
  <meta name="color-scheme" content="light dark" />
224
- <meta name="referrer" content="strict-origin-when-cross-origin" />
225
- {osano && <script src={osano.src} />}
226
- {googleTagManager && (
227
- <script
228
- data-google-tag-manager-container-id={
229
- config.integrations.analytics.gtm?.containerId
230
- }
231
- dangerouslySetInnerHTML={{ __html: googleTagManager }}
232
- />
233
- )}
234
38
  <script
235
39
  dangerouslySetInnerHTML={{
236
- __html: getThemeScript(THEME_STORAGE_KEY, config.mode),
40
+ __html: themeBootstrapScript(
41
+ DEFAULT_THEME_STORAGE_KEY,
42
+ config.mode,
43
+ ),
237
44
  }}
238
45
  />
239
- {adobe && <script async={adobe.async} src={adobe.src} />}
240
- {amplitude && <script src={amplitude.src} />}
241
- {clarity && (
242
- <script
243
- data-clarity-project-id={
244
- config.integrations.analytics.clarity?.projectId
245
- }
246
- dangerouslySetInnerHTML={{ __html: clarity }}
247
- />
248
- )}
249
- {clearbit && <script src={clearbit.src} />}
250
- {fathom && (
251
- <script
252
- data-site={fathom.siteId}
253
- data-spa={fathom.spa}
254
- defer={fathom.defer}
255
- src={fathom.src}
256
- />
257
- )}
258
- {googleAnalytics && googleAnalyticsBootstrap && (
259
- <>
260
- <script async={googleAnalytics.async} src={googleAnalytics.src} />
261
- <script
262
- data-google-analytics-measurement-id={
263
- config.integrations.analytics.ga4?.measurementId
264
- }
265
- dangerouslySetInnerHTML={{ __html: googleAnalyticsBootstrap }}
266
- />
267
- </>
268
- )}
269
- {heap && (
270
- <script
271
- data-heap-environment-id={
272
- config.integrations.analytics.heap?.environmentId
273
- }
274
- dangerouslySetInnerHTML={{ __html: heap }}
275
- />
276
- )}
277
- {hotjar && (
278
- <script
279
- data-hotjar-site-id={config.integrations.analytics.hotjar?.siteId}
280
- data-hotjar-snippet-version={
281
- config.integrations.analytics.hotjar?.snippetVersion
282
- }
283
- dangerouslySetInnerHTML={{ __html: hotjar }}
284
- />
285
- )}
286
- {logRocket && logRocketBootstrap && (
287
- <>
288
- <script crossOrigin={logRocket.crossOrigin} src={logRocket.src} />
289
- <script
290
- data-logrocket-app-id={
291
- config.integrations.analytics.logrocket?.appId
292
- }
293
- dangerouslySetInnerHTML={{ __html: logRocketBootstrap }}
294
- />
295
- </>
296
- )}
297
- {mixpanel && mixpanelBootstrap && (
298
- <>
299
- <script src={mixpanel.src} />
300
- <script
301
- data-mixpanel-project-token={
302
- config.integrations.analytics.mixpanel?.projectToken
303
- }
304
- dangerouslySetInnerHTML={{ __html: mixpanelBootstrap }}
305
- />
306
- </>
307
- )}
308
- {openpanel && openpanelBootstrap && (
309
- <>
310
- <script
311
- data-openpanel-api-url={
312
- config.integrations.analytics.openpanel?.apiUrl
313
- }
314
- data-openpanel-client-id={
315
- config.integrations.analytics.openpanel?.clientId
316
- }
317
- dangerouslySetInnerHTML={{ __html: openpanelBootstrap }}
318
- />
319
- <script
320
- async={openpanel.async}
321
- defer={openpanel.defer}
322
- src={openpanel.src}
323
- />
324
- </>
325
- )}
326
- {openReplay && (
327
- <script
328
- data-openreplay-ingest-point={
329
- config.integrations.analytics.openreplay?.ingestPoint
330
- }
331
- data-openreplay-project-key={
332
- config.integrations.analytics.openreplay?.projectKey
333
- }
334
- dangerouslySetInnerHTML={{ __html: openReplay }}
335
- />
336
- )}
337
- {pirsch && (
338
- <script
339
- data-code={pirsch.code}
340
- defer={pirsch.defer}
341
- src={pirsch.src}
342
- />
343
- )}
344
- {plausible && (
345
- <script
346
- data-domain={plausible.domain}
347
- defer={plausible.defer}
348
- src={plausible.src}
349
- />
350
- )}
351
- {posthog && posthogBootstrap && posthogHost && (
352
- <>
353
- <script src={posthog.src} />
354
- <script
355
- data-posthog-api-host={posthogHost}
356
- data-posthog-project-api-key={
357
- config.integrations.analytics.posthog?.projectApiKey
358
- }
359
- dangerouslySetInnerHTML={{ __html: posthogBootstrap }}
360
- />
361
- </>
362
- )}
363
- {rybbit && (
364
- <script
365
- data-site-id={rybbit.siteId}
366
- defer={rybbit.defer}
367
- src={rybbit.src}
368
- />
369
- )}
370
- {umami && (
371
- <script
372
- data-website-id={umami.websiteId}
373
- defer={umami.defer}
374
- src={umami.src}
375
- />
376
- )}
377
- {chaskiq && (
378
- <script
379
- data-chaskiq-app-id={config.integrations.support.chaskiq?.appId}
380
- data-chaskiq-base-url={config.integrations.support.chaskiq?.baseUrl}
381
- data-chaskiq-ws-url={config.integrations.support.chaskiq?.wsUrl}
382
- dangerouslySetInnerHTML={{ __html: chaskiq }}
383
- />
384
- )}
385
- {papercups && (
386
- <script
387
- data-papercups-base-url={
388
- config.integrations.support.papercups?.baseUrl
389
- }
390
- data-papercups-inbox={config.integrations.support.papercups?.inbox}
391
- data-papercups-token={config.integrations.support.papercups?.token}
392
- dangerouslySetInnerHTML={{ __html: papercups }}
393
- />
394
- )}
395
- {typebot && (
396
- <script
397
- data-heyo-typebot
398
- data-typebot-api-host={config.integrations.support.typebot?.apiHost}
399
- data-typebot-id={config.integrations.support.typebot?.typebot}
400
- dangerouslySetInnerHTML={{ __html: typebot }}
401
- type="module"
402
- />
403
- )}
46
+ <IntegrationScripts
47
+ integrations={config.integrations}
48
+ placement="head"
49
+ />
404
50
  <script
405
51
  type="application/ld+json"
406
52
  dangerouslySetInnerHTML={{
407
- __html: JSON.stringify({
408
- "@context": "https://schema.org",
409
- "@type": "WebSite",
410
- name: config.title,
411
- description: config.description,
412
- ...(config.siteUrl ? { url: config.siteUrl } : {}),
413
- }).replace(/</g, "\\u003c"),
53
+ __html: serializeJsonLd(siteSeo.structuredData),
414
54
  }}
415
55
  />
416
56
  </head>
417
57
  <body>
418
- {googleTagManagerNoScript && (
419
- <noscript>
420
- <iframe
421
- height="0"
422
- src={googleTagManagerNoScript}
423
- style={{ display: "none", visibility: "hidden" }}
424
- title="Google Tag Manager"
425
- width="0"
426
- />
427
- </noscript>
428
- )}
58
+ <IntegrationScripts
59
+ integrations={config.integrations}
60
+ placement="body"
61
+ />
429
62
  <ThemeProvider
430
63
  defaultTheme={config.mode}
431
- storageKey={THEME_STORAGE_KEY}
64
+ storageKey={DEFAULT_THEME_STORAGE_KEY}
432
65
  >
433
66
  {children}
434
67
  </ThemeProvider>
435
- {swetrix && swetrixBootstrap && (
436
- <>
437
- <script defer={swetrix.defer} src={swetrix.src} />
438
- <script
439
- data-swetrix-api-url={
440
- config.integrations.analytics.swetrix?.apiUrl
441
- }
442
- data-swetrix-project-id={
443
- config.integrations.analytics.swetrix?.projectId
444
- }
445
- dangerouslySetInnerHTML={{ __html: swetrixBootstrap }}
446
- />
447
- </>
448
- )}
449
- {intercom && (
450
- <script
451
- data-intercom-app-id={config.integrations.support.intercom?.appId}
452
- data-intercom-api-base={
453
- config.integrations.support.intercom?.apiBase
454
- }
455
- dangerouslySetInnerHTML={{ __html: intercom }}
456
- />
457
- )}
458
- {front && frontBootstrap && (
459
- <>
460
- <script src={front.src} />
461
- <script
462
- data-front-chat-id={config.integrations.support.front?.chatId}
463
- dangerouslySetInnerHTML={{ __html: frontBootstrap }}
464
- />
465
- </>
466
- )}
467
- {chatwoot && (
468
- <script
469
- data-chatwoot-base-url={
470
- config.integrations.support.chatwoot?.baseUrl
471
- }
472
- data-chatwoot-website-token={
473
- config.integrations.support.chatwoot?.websiteToken
474
- }
475
- dangerouslySetInnerHTML={{ __html: chatwoot }}
476
- />
477
- )}
478
- {zammad && zammadBootstrap && (
479
- <>
480
- <script src={zammad.src} />
481
- <script
482
- data-zammad-chat-id={config.integrations.support.zammad?.chatId}
483
- dangerouslySetInnerHTML={{ __html: zammadBootstrap }}
484
- />
485
- </>
486
- )}
487
68
  </body>
488
69
  </html>
489
70
  );
@@ -1,11 +1,11 @@
1
- import type { DocsPage } from "@heyo-sh/heyo-docs";
1
+ import type { DocsPage } from "@heyo-sh/heyo-docs/types";
2
2
  import {
3
- changelogGroupForPage,
4
3
  createDocsModel,
5
4
  findDocsPage,
6
5
  findOpenApiEndpoint,
7
6
  normaliseDocsPathname,
8
- } from "@heyo-sh/heyo-docs/node";
7
+ } from "@heyo-sh/heyo-docs/model";
8
+ import { changelogGroupForPage } from "@heyo-sh/heyo-docs/navigation";
9
9
 
10
10
  import config from "../../heyo-docs.config";
11
11
  import {
@@ -1,147 +1,15 @@
1
- import { findOpenApiEndpoint } from "@heyo-sh/heyo-docs/node";
2
- import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs";
1
+ import { handleOpenApiRequest as forwardOpenApiRequest } from "@heyo-sh/heyo-docs/openapi/request";
3
2
 
4
3
  import { docsModel } from "./docs";
5
4
 
6
- interface OpenApiRequestPayload {
7
- bearerToken: string;
8
- body?: string;
9
- endpointSlug: string;
10
- parameters: Record<string, string>;
11
- server: string;
12
- }
13
-
14
- /** Sends documented API calls server-side after validating the declared server. */
5
+ /** Same-origin Try It proxy constrained to servers declared by the OpenAPI schema. */
15
6
  export async function handleOpenApiRequest(
16
7
  request: Request,
17
8
  ): Promise<Response> {
18
9
  if (request.method !== "POST")
19
10
  return new Response("Method Not Allowed", {
20
- headers: { Allow: "POST" },
21
11
  status: 405,
12
+ headers: { Allow: "POST" },
22
13
  });
23
- const payload = await requestPayload(request);
24
- if (!payload)
25
- return new Response("Invalid OpenAPI request.", { status: 400 });
26
- const endpoint = findOpenApiEndpoint(
27
- docsModel.endpoints,
28
- payload.endpointSlug,
29
- );
30
- if (!endpoint) return new Response("Endpoint not found.", { status: 404 });
31
- if (endpoint.servers.length && !endpoint.servers.includes(payload.server))
32
- return new Response("API server is not declared in the OpenAPI schema.", {
33
- status: 400,
34
- });
35
- if (!endpoint.servers.length && payload.server)
36
- return new Response("This endpoint does not declare an API server.", {
37
- status: 400,
38
- });
39
-
40
- try {
41
- const response = await fetch(
42
- requestUrl(endpoint, payload.server, payload.parameters, request.url),
43
- {
44
- method: endpoint.method.toUpperCase(),
45
- headers: requestHeaders(
46
- endpoint,
47
- payload.parameters,
48
- payload.bearerToken,
49
- ),
50
- body: payload.body,
51
- },
52
- );
53
- const headers = new Headers();
54
- const contentType = response.headers.get("content-type");
55
- if (contentType) headers.set("content-type", contentType);
56
- return new Response(
57
- [204, 205, 304].includes(response.status)
58
- ? null
59
- : await response.arrayBuffer(),
60
- { headers, status: response.status, statusText: response.statusText },
61
- );
62
- } catch {
63
- return new Response("The API server could not be reached.", {
64
- status: 502,
65
- });
66
- }
67
- }
68
-
69
- async function requestPayload(
70
- request: Request,
71
- ): Promise<OpenApiRequestPayload | undefined> {
72
- try {
73
- const value: unknown = await request.json();
74
- if (!isRecord(value)) return undefined;
75
- const endpointSlug = stringValue(value.endpointSlug);
76
- const server = stringValue(value.server);
77
- if (!endpointSlug || server === undefined) return undefined;
78
- return {
79
- endpointSlug,
80
- server,
81
- bearerToken: stringValue(value.bearerToken) ?? "",
82
- body: stringValue(value.body),
83
- parameters: stringRecord(value.parameters),
84
- };
85
- } catch {
86
- return undefined;
87
- }
88
- }
89
-
90
- function requestUrl(
91
- endpoint: OpenApiEndpoint,
92
- server: string,
93
- parameters: Record<string, string>,
94
- requestUrl: string,
95
- ) {
96
- const path = endpoint.path.replace(
97
- /\{([^}]+)\}/g,
98
- (match: string, name: string) => {
99
- const value = parameters[`path:${name}`];
100
- return value ? encodeURIComponent(value) : match;
101
- },
102
- );
103
- const query = new URLSearchParams();
104
- for (const parameter of endpoint.parameters) {
105
- if (parameter.in !== "query") continue;
106
- const value = parameters[`query:${parameter.name}`];
107
- if (value) query.set(parameter.name, value);
108
- }
109
- const destination = `${path}${query.size ? `?${query}` : ""}`;
110
- return server
111
- ? `${server.replace(/\/$/, "")}${destination}`
112
- : new URL(destination, requestUrl).toString();
113
- }
114
-
115
- function requestHeaders(
116
- endpoint: OpenApiEndpoint,
117
- parameters: Record<string, string>,
118
- bearerToken: string,
119
- ) {
120
- const headers = new Headers();
121
- for (const parameter of endpoint.parameters) {
122
- if (parameter.in !== "header") continue;
123
- const value = parameters[`header:${parameter.name}`];
124
- if (value) headers.set(parameter.name, value);
125
- }
126
- if (endpoint.requestBody?.contentType)
127
- headers.set("Content-Type", endpoint.requestBody.contentType);
128
- if (bearerToken) headers.set("Authorization", `Bearer ${bearerToken}`);
129
- return headers;
130
- }
131
-
132
- function isRecord(value: unknown): value is Record<string, unknown> {
133
- return typeof value === "object" && value !== null && !Array.isArray(value);
134
- }
135
-
136
- function stringRecord(value: unknown): Record<string, string> {
137
- if (!isRecord(value)) return {};
138
- return Object.fromEntries(
139
- Object.entries(value).filter(
140
- (entry): entry is [string, string] => typeof entry[1] === "string",
141
- ),
142
- );
143
- }
144
-
145
- function stringValue(value: unknown): string | undefined {
146
- return typeof value === "string" ? value : undefined;
14
+ return forwardOpenApiRequest(request, docsModel.endpoints);
147
15
  }
@@ -1,4 +1,4 @@
1
- import { llmsFull } from "@heyo-sh/heyo-docs/node";
1
+ import { llmsFull } from "@heyo-sh/heyo-docs/llm";
2
2
 
3
3
  import { config, markdownPages } from "../lib/docs";
4
4
 
@@ -1,4 +1,4 @@
1
- import { llmsIndex } from "@heyo-sh/heyo-docs/node";
1
+ import { llmsIndex } from "@heyo-sh/heyo-docs/llm";
2
2
 
3
3
  import { config, markdownPages } from "../lib/docs";
4
4