@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
@@ -2,15 +2,15 @@
2
2
  import { AstroDocsApp } from "../components/docs-app";
3
3
  import DocsLayout from "../layouts/docs-layout.astro";
4
4
  import { docsContext, pathnameForSlug } from "../lib/docs";
5
- import { docsSeo } from "../lib/seo";
6
- import { openApiEndpointDetail } from "@heyo-sh/heyo-docs";
5
+ import { docsSeo, siteSeo } from "@heyo-sh/heyo-docs/seo";
6
+ import { openApiEndpointDetail } from "@heyo-sh/heyo-docs/openapi";
7
7
  import { pages } from "virtual:heyo-docs-content";
8
8
  import { openApiEndpoints } from "virtual:heyo-docs-openapi/index";
9
9
 
10
10
  export async function getStaticPaths() {
11
- return [...pages, ...openApiEndpoints].map(({ slug }) => ({
12
- params: { slug: slug === "/" ? undefined : slug.slice(1) },
13
- }));
11
+ return [...pages, ...openApiEndpoints]
12
+ .filter(({ slug }) => slug !== "/")
13
+ .map(({ slug }) => ({ params: { slug: slug.slice(1) } }));
14
14
  }
15
15
 
16
16
  const pathname = pathnameForSlug(Astro.params.slug);
@@ -25,16 +25,8 @@ const seo = exists
25
25
  ? docsSeo({ ...context, pathname })
26
26
  : {
27
27
  title: `Not found | ${context.config.title}`,
28
- description: context.config.description,
29
- structuredData: [
30
- {
31
- "@context": "https://schema.org",
32
- "@type": "WebSite",
33
- name: context.config.title,
34
- description: context.config.description,
35
- ...(context.config.siteUrl ? { url: context.config.siteUrl } : {}),
36
- },
37
- ],
28
+ description: siteSeo(context.config).description,
29
+ structuredData: siteSeo(context.config).structuredData,
38
30
  };
39
31
  ---
40
32
 
@@ -1,5 +1,8 @@
1
1
  import type { APIRoute } from "astro";
2
- import { markdownForPage, pathnameFromMarkdownPath } from "@heyo-sh/heyo-docs";
2
+ import {
3
+ markdownForPage,
4
+ pathnameFromMarkdownPath,
5
+ } from "@heyo-sh/heyo-docs/llm";
3
6
 
4
7
  import { pages } from "virtual:heyo-docs-content/server";
5
8
 
@@ -1,4 +1,3 @@
1
- import { createAiChatResponse } from "@heyo-sh/heyo-docs/ai";
2
1
  import type { APIRoute } from "astro";
3
2
 
4
3
  import config from "../../../heyo-docs.config";
@@ -6,17 +5,16 @@ import { pages as markdownPages } from "virtual:heyo-docs-content/server";
6
5
 
7
6
  export const prerender = false;
8
7
 
9
- export const POST: APIRoute = ({ request }) => {
10
- const apiKey = process.env.OPENAI_API_KEY;
11
- if (!apiKey)
8
+ export const POST: APIRoute = async ({ request }) => {
9
+ if (!config.ai?.chat)
12
10
  return Response.json(
13
- { error: "OPENAI_API_KEY is not configured." },
14
- { status: 500 },
11
+ { error: "AI chat is not configured." },
12
+ { status: 404 },
15
13
  );
16
14
 
15
+ const { createAiChatResponse } = await import("@heyo-sh/heyo-docs/ai");
17
16
  return createAiChatResponse(request, {
18
17
  ai: config.ai,
19
- auth: { type: "api-key", token: apiKey },
20
18
  markdownPages,
21
19
  pages: markdownPages.map((page) => ({
22
20
  description: page.description,
@@ -5,4 +5,10 @@ import { handleOpenApiRequest } from "../../lib/openapi-request";
5
5
  /** The only dynamic OpenAPI surface: a same-origin proxy for Try it requests. */
6
6
  export const prerender = false;
7
7
 
8
+ export const GET: APIRoute = () =>
9
+ new Response("Method Not Allowed", {
10
+ headers: { Allow: "POST" },
11
+ status: 405,
12
+ });
13
+
8
14
  export const POST: APIRoute = ({ request }) => handleOpenApiRequest(request);
@@ -1,13 +1,22 @@
1
1
  ---
2
- import { navigationPages } from "@heyo-sh/heyo-docs";
3
-
2
+ import { AstroDocsApp } from "../components/docs-app";
3
+ import DocsLayout from "../layouts/docs-layout.astro";
4
4
  import { docsContext } from "../lib/docs";
5
+ import { docsSeo, siteSeo } from "@heyo-sh/heyo-docs/seo";
5
6
 
6
- const firstPage = docsContext("/")
7
- .model.navigation.flatMap((group) => navigationPages(group.sections))
8
- .at(0);
9
-
10
- if (!firstPage) throw new Error("No local documentation page is configured.");
11
-
12
- return Astro.redirect(firstPage.slug);
7
+ const pathname = "/";
8
+ const context = docsContext(pathname);
9
+ const exists = Boolean(context.page || context.endpoint);
10
+ if (!exists) Astro.response.status = 404;
11
+ const seo = exists
12
+ ? docsSeo({ ...context, pathname })
13
+ : {
14
+ title: `Not found | ${context.config.title}`,
15
+ description: siteSeo(context.config).description,
16
+ structuredData: siteSeo(context.config).structuredData,
17
+ };
13
18
  ---
19
+
20
+ <DocsLayout {...seo} robots={exists ? "index, follow" : "noindex"}>
21
+ <AstroDocsApp client:load pathname={pathname} />
22
+ </DocsLayout>
@@ -1,5 +1,5 @@
1
1
  import type { APIRoute } from "astro";
2
- import { llmsFull } from "@heyo-sh/heyo-docs";
2
+ import { llmsFull } from "@heyo-sh/heyo-docs/llm";
3
3
 
4
4
  import config from "../../heyo-docs.config";
5
5
  import { pages } from "virtual:heyo-docs-content/server";
@@ -1,5 +1,5 @@
1
1
  import type { APIRoute } from "astro";
2
- import { llmsIndex } from "@heyo-sh/heyo-docs";
2
+ import { llmsIndex } from "@heyo-sh/heyo-docs/llm";
3
3
 
4
4
  import config from "../../heyo-docs.config";
5
5
  import { pages } from "virtual:heyo-docs-content/server";
@@ -1,5 +1,5 @@
1
1
  import type { APIRoute } from "astro";
2
- import { rssXml } from "@heyo-sh/heyo-docs";
2
+ import { rssXml } from "@heyo-sh/heyo-docs/rss";
3
3
 
4
4
  import config from "../../heyo-docs.config";
5
5
  import { pages } from "virtual:heyo-docs-content/server";
@@ -1,8 +1,8 @@
1
1
  import type { APIRoute } from "astro";
2
- import { sitemapXml } from "@heyo-sh/heyo-docs";
2
+ import { sitemapXml } from "@heyo-sh/heyo-docs/seo";
3
3
 
4
4
  import config from "../../heyo-docs.config";
5
- import { createDocsModel } from "@heyo-sh/heyo-docs";
5
+ import { createDocsModel } from "@heyo-sh/heyo-docs/model";
6
6
  import { openApiDocuments } from "virtual:heyo-docs-openapi";
7
7
  import { pages } from "virtual:heyo-docs-content";
8
8
 
@@ -1,26 +1,26 @@
1
1
  declare module "virtual:heyo-docs-content" {
2
- import type { DocsPage } from "@heyo-sh/heyo-docs";
2
+ import type { DocsPage } from "@heyo-sh/heyo-docs/types";
3
3
  export const pages: DocsPage[];
4
4
  }
5
5
 
6
6
  declare module "virtual:heyo-docs-config" {
7
- import type { HeyoDocsConfig } from "@heyo-sh/heyo-docs";
7
+ import type { HeyoDocsConfig } from "@heyo-sh/heyo-docs/types";
8
8
  export const config: HeyoDocsConfig;
9
9
  }
10
10
 
11
11
  declare module "virtual:heyo-docs-theme.css";
12
12
 
13
13
  declare module "virtual:heyo-docs-content/server" {
14
- import type { MarkdownPage } from "@heyo-sh/heyo-docs";
14
+ import type { MarkdownPage } from "@heyo-sh/heyo-docs/types";
15
15
  export const pages: MarkdownPage[];
16
16
  }
17
17
 
18
18
  declare module "virtual:heyo-docs-openapi" {
19
- import type { OpenApiDocumentSource } from "@heyo-sh/heyo-docs";
19
+ import type { OpenApiDocumentSource } from "@heyo-sh/heyo-docs/types";
20
20
  export const openApiDocuments: OpenApiDocumentSource[];
21
21
  }
22
22
 
23
23
  declare module "virtual:heyo-docs-openapi/index" {
24
- import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs";
24
+ import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs/types";
25
25
  export const openApiEndpoints: OpenApiEndpoint[];
26
26
  }
@@ -1,13 +1,12 @@
1
1
  import type { Metadata } from "next";
2
2
  import { notFound, redirect } from "next/navigation";
3
- import {
4
- navigationPages,
5
- openApiEndpointDetail,
6
- } from "@heyo-sh/heyo-docs/node";
3
+ import { nextDocsSeo } from "@heyo-sh/heyo-docs/seo/next";
4
+ import { navigationPages } from "@heyo-sh/heyo-docs/navigation";
5
+ import { openApiEndpointDetail } from "@heyo-sh/heyo-docs/openapi";
6
+ import { serializeJsonLd } from "@heyo-sh/heyo-docs/seo";
7
7
 
8
8
  import { NextDocsApp } from "../components/docs-app";
9
9
  import { docsContext, docsModel, pathnameForSegments } from "../lib/docs";
10
- import { docsSeo } from "../lib/seo";
11
10
 
12
11
  interface PageProps {
13
12
  params: Promise<{ slug?: string[] }>;
@@ -41,7 +40,7 @@ export async function generateMetadata({
41
40
  title: `Not found | ${context.config.title}`,
42
41
  robots: { index: false, follow: false },
43
42
  };
44
- return docsSeo({ ...context, pathname }).metadata;
43
+ return nextDocsSeo({ ...context, pathname }).metadata;
45
44
  }
46
45
 
47
46
  export default async function DocsPage({ params }: PageProps) {
@@ -55,18 +54,20 @@ export default async function DocsPage({ params }: PageProps) {
55
54
  if (!firstPage)
56
55
  throw new Error("No local documentation page is configured.");
57
56
 
58
- redirect(firstPage.slug);
57
+ // A minimal project owns `/` through content/index.mdx. Do not redirect
58
+ // the root route to itself.
59
+ if (firstPage.slug !== "/") redirect(firstPage.slug);
59
60
  }
60
61
  const context = docsContext(pathname);
61
62
  if (!context.page && !context.endpoint) notFound();
62
- const { structuredData } = docsSeo({ ...context, pathname });
63
+ const { structuredData } = nextDocsSeo({ ...context, pathname });
63
64
 
64
65
  return (
65
66
  <>
66
67
  <script
67
68
  type="application/ld+json"
68
69
  dangerouslySetInnerHTML={{
69
- __html: JSON.stringify(structuredData).replace(/</g, "\\u003c"),
70
+ __html: serializeJsonLd(structuredData),
70
71
  }}
71
72
  />
72
73
  <NextDocsApp
@@ -1,58 +1,23 @@
1
1
  "use client";
2
2
 
3
- import {
4
- DocsApp,
5
- openApiEndpointDataPath,
6
- type OpenApiEndpoint,
7
- } from "@heyo-sh/heyo-docs";
8
- import {
9
- createContext,
10
- forwardRef,
11
- useCallback,
12
- useContext,
13
- useEffect,
14
- useRef,
15
- useState,
16
- type ComponentPropsWithoutRef,
17
- type MouseEvent,
18
- } from "react";
3
+ import Link from "next/link";
4
+ import { DocsApp } from "@heyo-sh/heyo-docs";
5
+ import type { DocsLinkProps } from "@heyo-sh/heyo-docs/link";
6
+ import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs/types";
7
+ import { useDocsTheme } from "@heyo-sh/heyo-docs/theme/provider";
8
+ import { forwardRef } from "react";
9
+ import { __HEYO_THEME_IDENTIFIER__ } from "@heyo-sh/heyo-docs/theme/__HEYO_THEME__";
19
10
 
20
11
  import { docsConfig, openApiEndpoints, pages } from "../_heyo-docs/content";
21
12
  import { iconSet } from "../heyo-docs-icons";
22
- import { useTheme } from "./theme-provider";
23
13
 
24
- type Navigate = (href: string) => void;
25
-
26
- const NextNavigationContext = createContext<Navigate | undefined>(undefined);
27
-
28
- const NextDocsLink = forwardRef<
29
- HTMLAnchorElement,
30
- ComponentPropsWithoutRef<"a">
31
- >(function NextDocsLink({ href, onClick, target, ...props }, ref) {
32
- const navigate = useContext(NextNavigationContext);
33
-
34
- const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {
35
- onClick?.(event);
36
- if (
37
- !navigate ||
38
- event.defaultPrevented ||
39
- event.button !== 0 ||
40
- event.metaKey ||
41
- event.altKey ||
42
- event.ctrlKey ||
43
- event.shiftKey ||
44
- target
45
- )
46
- return;
47
-
48
- event.preventDefault();
49
- navigate(href ?? "/");
50
- };
51
-
52
- return (
53
- <a {...props} href={href} onClick={handleClick} ref={ref} target={target} />
54
- );
55
- });
14
+ const NextDocsLink = forwardRef<HTMLAnchorElement, DocsLinkProps>(
15
+ function NextDocsLink({ href = "/", ...props }, ref) {
16
+ // Next owns history, RSC payloads, metadata and scroll restoration. Docs
17
+ // links must not emulate routing with pushState in a client component.
18
+ return <Link {...props} href={href} ref={ref} />;
19
+ },
20
+ );
56
21
 
57
22
  export function NextDocsApp({
58
23
  currentOpenApiEndpoint,
@@ -61,78 +26,21 @@ export function NextDocsApp({
61
26
  currentOpenApiEndpoint?: OpenApiEndpoint;
62
27
  pathname: string;
63
28
  }) {
64
- const { mounted, resolvedTheme, setTheme } = useTheme();
65
- const [activePathname, setActivePathname] = useState(pathname);
66
- const [activeOpenApiEndpoint, setActiveOpenApiEndpoint] = useState(
67
- currentOpenApiEndpoint,
68
- );
69
- const navigationId = useRef(0);
70
-
71
- const navigate = useCallback(async (href: string, updateHistory = true) => {
72
- const destination = new URL(href, window.location.href);
73
- if (destination.origin !== window.location.origin) {
74
- window.location.assign(href);
75
- return;
76
- }
77
-
78
- const nextPathname = destination.pathname;
79
- const indexedEndpoint = openApiEndpoints.find(
80
- (endpoint) => endpoint.slug === nextPathname,
81
- );
82
- const page = pages.find((candidate) => candidate.slug === nextPathname);
83
- if (!indexedEndpoint && !page) {
84
- window.location.assign(href);
85
- return;
86
- }
87
-
88
- const currentNavigation = ++navigationId.current;
89
- let endpoint: OpenApiEndpoint | undefined;
90
- if (indexedEndpoint) {
91
- const response = await fetch(
92
- openApiEndpointDataPath(indexedEndpoint.slug),
93
- );
94
- if (!response.ok) {
95
- window.location.assign(href);
96
- return;
97
- }
98
- endpoint = (await response.json()) as OpenApiEndpoint;
99
- }
100
- if (currentNavigation !== navigationId.current) return;
101
-
102
- if (updateHistory) window.history.pushState({}, "", destination);
103
- document.title =
104
- page?.seo.title ?? `${indexedEndpoint!.title} | ${docsConfig.title}`;
105
- setActiveOpenApiEndpoint(endpoint);
106
- setActivePathname(nextPathname);
107
- }, []);
108
-
109
- useEffect(() => {
110
- const onPopState = () => {
111
- void navigate(window.location.href, false);
112
- };
113
-
114
- window.addEventListener("popstate", onPopState);
115
- return () => window.removeEventListener("popstate", onPopState);
116
- }, [navigate]);
29
+ const { mounted, resolvedTheme, toggleTheme } = useDocsTheme();
117
30
 
118
31
  return (
119
- <NextNavigationContext.Provider value={navigate}>
120
- <DocsApp
121
- config={docsConfig}
122
- iconSet={iconSet}
123
- isDark={mounted ? resolvedTheme === "dark" : undefined}
124
- link={NextDocsLink}
125
- onThemeToggle={
126
- mounted
127
- ? () => setTheme(resolvedTheme === "dark" ? "light" : "dark")
128
- : undefined
129
- }
130
- currentOpenApiEndpoint={activeOpenApiEndpoint}
131
- openApiEndpoints={openApiEndpoints}
132
- openApiRequestUrl="/heyo-docs-internal/openapi-request"
133
- pages={pages}
134
- pathname={activePathname}
135
- />
136
- </NextNavigationContext.Provider>
32
+ <DocsApp
33
+ config={docsConfig}
34
+ currentOpenApiEndpoint={currentOpenApiEndpoint}
35
+ iconSet={iconSet}
36
+ isDark={mounted ? resolvedTheme === "dark" : undefined}
37
+ link={NextDocsLink}
38
+ onThemeToggle={mounted ? toggleTheme : undefined}
39
+ openApiEndpoints={openApiEndpoints}
40
+ openApiRequestUrl="/heyo-docs-internal/openapi-request"
41
+ pages={pages}
42
+ pathname={pathname}
43
+ theme={__HEYO_THEME_IDENTIFIER__}
44
+ />
137
45
  );
138
46
  }
@@ -31,7 +31,7 @@ import {
31
31
  RiStarLine,
32
32
  RiSunLine,
33
33
  } from "@remixicon/react";
34
- import type { IconSet } from "@heyo-sh/heyo-docs";
34
+ import type { IconSet } from "@heyo-sh/heyo-docs/types";
35
35
 
36
36
  /** Statically selected icons keep unused packs out of the client bundle. */
37
37
  export const iconSet = {
@@ -1,21 +1,20 @@
1
- import { createAiChatResponse } from "@heyo-sh/heyo-docs/ai";
2
-
3
1
  import config from "../../../heyo-docs.config";
4
2
  import { docsPages, markdownPages } from "../../_heyo-docs/server";
5
3
 
6
4
  export const runtime = "nodejs";
7
5
 
8
6
  export async function POST(request: Request) {
9
- const apiKey = process.env.OPENAI_API_KEY;
10
- if (!apiKey)
7
+ if (!config.ai?.chat)
11
8
  return Response.json(
12
- { error: "OPENAI_API_KEY is not configured." },
13
- { status: 500 },
9
+ { error: "AI chat is not configured." },
10
+ { status: 404 },
14
11
  );
15
12
 
13
+ // Pi's provider catalogue is a server-only optional feature. Importing it
14
+ // only for an enabled request keeps static docs builds free of AI runtime.
15
+ const { createAiChatResponse } = await import("@heyo-sh/heyo-docs/ai");
16
16
  return createAiChatResponse(request, {
17
17
  ai: config.ai,
18
- auth: { type: "api-key", token: apiKey },
19
18
  markdownPages,
20
19
  pages: docsPages,
21
20
  title: config.title,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  markdownForPage,
3
3
  pathnameFromMarkdownPath,
4
- } from "@heyo-sh/heyo-docs/node";
4
+ } from "@heyo-sh/heyo-docs/llm";
5
5
 
6
6
  import { markdownPages } from "../../../lib/docs";
7
7