@heyo-sh/create-heyo-docs 1.0.1 → 2.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 +4 -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 +4 -1
  6. package/deployments/cloudflare/react-router/app/cloudflare-env.d.ts +4 -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,74 +0,0 @@
1
- export type Theme = "dark" | "light" | "system";
2
- export type ResolvedTheme = Exclude<Theme, "system">;
3
-
4
- export const DEFAULT_THEME: Theme = "system";
5
- export const THEME_STORAGE_KEY = "heyo-docs-theme";
6
-
7
- const themeValues = new Set<Theme>(["light", "dark", "system"]);
8
-
9
- export function isTheme(value: string | null): value is Theme {
10
- return value !== null && themeValues.has(value as Theme);
11
- }
12
-
13
- export function getStoredTheme(
14
- storageKey: string,
15
- fallbackTheme: Theme,
16
- ): Theme {
17
- if (typeof window === "undefined") return fallbackTheme;
18
-
19
- try {
20
- const storedTheme = window.localStorage.getItem(storageKey);
21
- return isTheme(storedTheme) ? storedTheme : fallbackTheme;
22
- } catch {
23
- return fallbackTheme;
24
- }
25
- }
26
-
27
- export function getSystemTheme(): ResolvedTheme {
28
- return window.matchMedia("(prefers-color-scheme: dark)").matches
29
- ? "dark"
30
- : "light";
31
- }
32
-
33
- export function resolveTheme(theme: Theme): ResolvedTheme {
34
- return theme === "system" ? getSystemTheme() : theme;
35
- }
36
-
37
- export function applyTheme(theme: Theme): ResolvedTheme {
38
- const resolvedTheme = resolveTheme(theme);
39
- const root = window.document.documentElement;
40
-
41
- root.classList.remove("light", "dark");
42
- root.classList.add(resolvedTheme);
43
- root.style.colorScheme = resolvedTheme;
44
-
45
- return resolvedTheme;
46
- }
47
-
48
- export function getThemeScript(storageKey: string, defaultTheme: Theme) {
49
- return `(() => {
50
- const storageKey = ${JSON.stringify(storageKey)};
51
- const fallbackTheme = ${JSON.stringify(defaultTheme)};
52
- const isTheme = (value) => value === "light" || value === "dark" || value === "system";
53
-
54
- const storedTheme = (() => {
55
- try {
56
- const value = window.localStorage.getItem(storageKey);
57
- return isTheme(value) ? value : fallbackTheme;
58
- } catch {
59
- return fallbackTheme;
60
- }
61
- })();
62
-
63
- const resolvedTheme = storedTheme === "system"
64
- ? window.matchMedia("(prefers-color-scheme: dark)").matches
65
- ? "dark"
66
- : "light"
67
- : storedTheme;
68
-
69
- const root = document.documentElement;
70
- root.classList.remove("light", "dark");
71
- root.classList.add(resolvedTheme);
72
- root.style.colorScheme = resolvedTheme;
73
- })();`;
74
- }
@@ -1,93 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- createContext,
5
- useContext,
6
- useEffect,
7
- useState,
8
- type ReactNode,
9
- } from "react";
10
-
11
- import {
12
- applyTheme,
13
- DEFAULT_THEME,
14
- getStoredTheme,
15
- type ResolvedTheme,
16
- THEME_STORAGE_KEY,
17
- type Theme,
18
- } from "../lib/theme";
19
-
20
- type ThemeProviderState = {
21
- theme: Theme;
22
- resolvedTheme: ResolvedTheme;
23
- mounted: boolean;
24
- setTheme: (theme: Theme) => void;
25
- };
26
-
27
- const ThemeProviderContext = createContext<ThemeProviderState | undefined>(
28
- undefined,
29
- );
30
-
31
- export function ThemeProvider({
32
- children,
33
- defaultTheme = DEFAULT_THEME,
34
- storageKey = THEME_STORAGE_KEY,
35
- }: {
36
- children: ReactNode;
37
- defaultTheme?: Theme;
38
- storageKey?: string;
39
- }) {
40
- const [theme, setThemeState] = useState<Theme>(defaultTheme);
41
- const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>(
42
- defaultTheme === "system" ? "light" : defaultTheme,
43
- );
44
- const [mounted, setMounted] = useState(false);
45
-
46
- useEffect(() => {
47
- const syncTheme = () => {
48
- const nextTheme = getStoredTheme(storageKey, defaultTheme);
49
- setThemeState(nextTheme);
50
- setResolvedTheme(applyTheme(nextTheme));
51
- };
52
- syncTheme();
53
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
54
- const onSystemThemeChange = () => syncTheme();
55
- const onStorage = (event: StorageEvent) => {
56
- if (event.key === null || event.key === storageKey) syncTheme();
57
- };
58
- mediaQuery.addEventListener("change", onSystemThemeChange);
59
- window.addEventListener("storage", onStorage);
60
- setMounted(true);
61
- return () => {
62
- mediaQuery.removeEventListener("change", onSystemThemeChange);
63
- window.removeEventListener("storage", onStorage);
64
- };
65
- }, [defaultTheme, storageKey]);
66
-
67
- return (
68
- <ThemeProviderContext.Provider
69
- value={{
70
- theme,
71
- resolvedTheme,
72
- mounted,
73
- setTheme: (nextTheme) => {
74
- try {
75
- window.localStorage.setItem(storageKey, nextTheme);
76
- } catch {
77
- // The requested preference still applies when storage is unavailable.
78
- }
79
- setThemeState(nextTheme);
80
- setResolvedTheme(applyTheme(nextTheme));
81
- },
82
- }}
83
- >
84
- {children}
85
- </ThemeProviderContext.Provider>
86
- );
87
- }
88
-
89
- export function useTheme() {
90
- const context = useContext(ThemeProviderContext);
91
- if (!context) throw new Error("useTheme must be used within a ThemeProvider");
92
- return context;
93
- }
@@ -1,189 +0,0 @@
1
- import type { Metadata } from "next";
2
- import {
3
- type ChangelogGroupConfig,
4
- type DocsPage,
5
- type HeyoDocsConfig,
6
- type NavigationGroup,
7
- type OpenApiEndpoint,
8
- } from "@heyo-sh/heyo-docs";
9
- import {
10
- navigationGroupContainsPath,
11
- navigationPages,
12
- navigationSectionPathForPath,
13
- } from "@heyo-sh/heyo-docs/node";
14
-
15
- interface DocsSeoInput {
16
- config: HeyoDocsConfig;
17
- pathname: string;
18
- page?: DocsPage;
19
- endpoint?: OpenApiEndpoint;
20
- changelogGroup?: ChangelogGroupConfig;
21
- navigation: NavigationGroup[];
22
- }
23
-
24
- function canonicalFor({ config, pathname, page }: DocsSeoInput) {
25
- return (
26
- page?.seo.canonical ??
27
- (config.siteUrl ? `${config.siteUrl}${pathname}` : undefined)
28
- );
29
- }
30
-
31
- function website(config: HeyoDocsConfig) {
32
- return {
33
- "@type": "WebSite",
34
- name: config.title,
35
- ...(config.siteUrl ? { url: config.siteUrl } : {}),
36
- };
37
- }
38
-
39
- function breadcrumbItems({
40
- changelogGroup,
41
- navigation,
42
- pathname,
43
- title,
44
- }: Pick<DocsSeoInput, "changelogGroup" | "navigation" | "pathname"> & {
45
- title: string;
46
- }) {
47
- if (changelogGroup) return [{ label: changelogGroup.group, href: pathname }];
48
- const group = navigation.find((candidate) =>
49
- navigationGroupContainsPath(candidate, pathname),
50
- );
51
- const sections = group
52
- ? navigationSectionPathForPath(group.sections, pathname)
53
- : undefined;
54
- if (!group) return [{ label: title, href: pathname }];
55
- return [
56
- { label: group.group, href: navigationPages(group.sections)[0]?.slug },
57
- ...(sections ?? []).map((section) => ({
58
- label: section.section,
59
- href: navigationPages([section])[0]?.slug,
60
- })),
61
- { label: title, href: pathname },
62
- ];
63
- }
64
-
65
- function absoluteUrl(siteUrl: string | undefined, href: string | undefined) {
66
- if (!siteUrl || !href) return undefined;
67
- return /^https?:\/\//.test(href)
68
- ? href
69
- : new URL(href, `${siteUrl}/`).toString();
70
- }
71
-
72
- /** Next Metadata plus JSON-LD for MDX, changelog and generated API pages. */
73
- export function docsSeo(input: DocsSeoInput): {
74
- metadata: Metadata;
75
- structuredData: unknown[];
76
- } {
77
- const { changelogGroup, config, endpoint, navigation, page, pathname } =
78
- input;
79
- const title = page?.seo.title ?? `${endpoint!.title} | ${config.title}`;
80
- const description =
81
- page?.seo.description ??
82
- endpoint?.description ??
83
- `${endpoint!.method.toUpperCase()} ${endpoint!.path} API endpoint.`;
84
- const canonical = canonicalFor(input);
85
- const pageType = endpoint
86
- ? {
87
- "@context": "https://schema.org",
88
- "@type": "APIReference",
89
- headline: title,
90
- description,
91
- ...(canonical ? { url: canonical } : {}),
92
- isPartOf: website(config),
93
- mainEntity: {
94
- "@type": "EntryPoint",
95
- name:
96
- endpoint.operationId ??
97
- `${endpoint.method.toUpperCase()} ${endpoint.path}`,
98
- httpMethod: endpoint.method.toUpperCase(),
99
- urlTemplate: endpoint.servers[0]
100
- ? `${endpoint.servers[0].replace(/\/$/, "")}${endpoint.path}`
101
- : endpoint.path,
102
- ...(endpoint.requestBody?.contentType
103
- ? { encodingType: endpoint.requestBody.contentType }
104
- : {}),
105
- ...(endpoint.responses[0]?.contentType
106
- ? { contentType: endpoint.responses[0].contentType }
107
- : {}),
108
- },
109
- }
110
- : changelogGroup
111
- ? {
112
- "@context": "https://schema.org",
113
- "@type": "CollectionPage",
114
- headline: title,
115
- description,
116
- ...(canonical ? { url: canonical } : {}),
117
- isPartOf: website(config),
118
- ...(page?.changelogUpdates?.length
119
- ? {
120
- hasPart: page.changelogUpdates.map((update) => ({
121
- "@type": "TechArticle",
122
- headline: update.label,
123
- ...(update.tags.length
124
- ? { keywords: update.tags.join(", ") }
125
- : {}),
126
- ...(canonical ? { url: `${canonical}#${update.id}` } : {}),
127
- })),
128
- }
129
- : {}),
130
- }
131
- : {
132
- "@context": "https://schema.org",
133
- "@type": "TechArticle",
134
- headline: title,
135
- description,
136
- ...(canonical ? { url: canonical } : {}),
137
- isPartOf: website(config),
138
- };
139
- const crumbs = breadcrumbItems({
140
- changelogGroup,
141
- navigation,
142
- pathname,
143
- title: page?.title ?? endpoint!.title,
144
- });
145
- const structuredData = [
146
- pageType,
147
- {
148
- "@context": "https://schema.org",
149
- "@type": "BreadcrumbList",
150
- itemListElement: [
151
- { label: config.title, href: config.siteUrl },
152
- ...crumbs,
153
- ].map((item, index, items) => ({
154
- "@type": "ListItem",
155
- position: index + 1,
156
- name: item.label,
157
- ...((
158
- index === items.length - 1
159
- ? canonical
160
- : absoluteUrl(config.siteUrl, item.href)
161
- )
162
- ? {
163
- item:
164
- index === items.length - 1
165
- ? canonical
166
- : absoluteUrl(config.siteUrl, item.href),
167
- }
168
- : {}),
169
- })),
170
- },
171
- ];
172
- return {
173
- metadata: {
174
- title,
175
- description,
176
- robots: { index: true, follow: true },
177
- alternates: canonical ? { canonical } : undefined,
178
- openGraph: {
179
- type: "article",
180
- siteName: config.title,
181
- title,
182
- description,
183
- ...(canonical ? { url: canonical } : {}),
184
- },
185
- twitter: { card: "summary", title, description },
186
- },
187
- structuredData,
188
- };
189
- }
@@ -1,61 +0,0 @@
1
- export type Theme = "dark" | "light" | "system";
2
- export type ResolvedTheme = Exclude<Theme, "system">;
3
-
4
- export const DEFAULT_THEME: Theme = "system";
5
- export const THEME_STORAGE_KEY = "heyo-docs-theme";
6
-
7
- const themeValues = new Set<Theme>(["light", "dark", "system"]);
8
-
9
- export function isTheme(value: string | null): value is Theme {
10
- return value !== null && themeValues.has(value as Theme);
11
- }
12
-
13
- export function getStoredTheme(
14
- storageKey: string,
15
- fallbackTheme: Theme,
16
- ): Theme {
17
- if (typeof window === "undefined") return fallbackTheme;
18
- try {
19
- const storedTheme = window.localStorage.getItem(storageKey);
20
- return isTheme(storedTheme) ? storedTheme : fallbackTheme;
21
- } catch {
22
- return fallbackTheme;
23
- }
24
- }
25
-
26
- export function applyTheme(theme: Theme): ResolvedTheme {
27
- const resolvedTheme =
28
- theme === "system"
29
- ? window.matchMedia("(prefers-color-scheme: dark)").matches
30
- ? "dark"
31
- : "light"
32
- : theme;
33
- const root = window.document.documentElement;
34
- root.classList.remove("light", "dark");
35
- root.classList.add(resolvedTheme);
36
- root.style.colorScheme = resolvedTheme;
37
- return resolvedTheme;
38
- }
39
-
40
- export function getThemeScript(storageKey: string, defaultTheme: Theme) {
41
- return `(() => {
42
- const storageKey = ${JSON.stringify(storageKey)};
43
- const fallbackTheme = ${JSON.stringify(defaultTheme)};
44
- const isTheme = (value) => value === "light" || value === "dark" || value === "system";
45
- const storedTheme = (() => {
46
- try {
47
- const value = window.localStorage.getItem(storageKey);
48
- return isTheme(value) ? value : fallbackTheme;
49
- } catch {
50
- return fallbackTheme;
51
- }
52
- })();
53
- const resolvedTheme = storedTheme === "system"
54
- ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
55
- : storedTheme;
56
- const root = document.documentElement;
57
- root.classList.remove("light", "dark");
58
- root.classList.add(resolvedTheme);
59
- root.style.colorScheme = resolvedTheme;
60
- })();`;
61
- }
@@ -1,20 +0,0 @@
1
- ---
2
- title: API overview
3
- description: Learn how to authenticate and explore the API reference.
4
- ---
5
-
6
- # API overview
7
-
8
- The API reference is generated from `openapi.json`. Use the endpoint pages to
9
- enter parameters, send a request, and copy a cURL or JavaScript example.
10
-
11
- ## Authentication
12
-
13
- The example API uses a Bearer token. Enter it once on any protected endpoint;
14
- Heyo Docs keeps it in this browser while you move between API pages.
15
-
16
- ## Custom pages first
17
-
18
- This ordinary MDX page belongs to the OpenAPI group. Its section is configured
19
- before the generated endpoint sections, so it always appears at the top of the
20
- sidebar.
@@ -1,22 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="960" height="360" viewBox="0 0 960 360" fill="none">
2
- <rect width="960" height="360" rx="24" fill="#F7F7F8"/>
3
- <g fill="#FFFFFF" stroke="#D4D4D8" stroke-width="2">
4
- <rect x="72" y="108" width="220" height="144" rx="18"/>
5
- <rect x="370" y="108" width="220" height="144" rx="18"/>
6
- <rect x="668" y="108" width="220" height="144" rx="18"/>
7
- </g>
8
- <g fill="#18181B" font-family="Arial, sans-serif" text-anchor="middle">
9
- <text x="182" y="166" font-size="17" font-weight="700">Content</text>
10
- <text x="182" y="194" font-size="14" fill="#71717A">MDX and assets</text>
11
- <text x="480" y="166" font-size="17" font-weight="700">Build</text>
12
- <text x="480" y="194" font-size="14" fill="#71717A">Vite bundles files</text>
13
- <text x="778" y="166" font-size="17" font-weight="700">Documentation</text>
14
- <text x="778" y="194" font-size="14" fill="#71717A">Static output</text>
15
- </g>
16
- <g stroke="#71717A" stroke-linecap="round" stroke-width="2">
17
- <path d="M314 180h34"/>
18
- <path d="m340 172 8 8-8 8"/>
19
- <path d="M612 180h34"/>
20
- <path d="m638 172 8 8-8 8"/>
21
- </g>
22
- </svg>
@@ -1,5 +0,0 @@
1
- Heyo Docs quick reference
2
-
3
- - Put MDX pages and local assets in content.
4
- - Use a relative path to bundle an image or downloadable file.
5
- - Use /path for assets in public.
@@ -1,38 +0,0 @@
1
- ---
2
- title: Changelog
3
- description: Mock release notes for the Heyo Docs example.
4
- ---
5
-
6
- # Changelog
7
-
8
- <Update label="April 2026" tags={["New", "Documentation"]}>
9
-
10
- ## Starter documentation
11
-
12
- New projects and runnable examples now include a structured Quickstart, basic
13
- configuration guide, deployment overview, and essential writing patterns.
14
-
15
- ## Square API group
16
-
17
- The example navigation now keeps the pinned Square OpenAPI schema in its own
18
- group, making large-schema behaviour easy to inspect.
19
-
20
- </Update>
21
-
22
- <Update label="March 2026" tags={["Improved", "Developer experience"]}>
23
-
24
- ## Clearer navigation
25
-
26
- External documentation links can display an icon, and sidebar groups now keep
27
- onboarding, API reference, and release notes separate.
28
-
29
- </Update>
30
-
31
- <Update label="February 2026" tags={["Fixed"]}>
32
-
33
- ## More predictable previews
34
-
35
- Preview builds now validate configured routes before mock release notes are
36
- published.
37
-
38
- </Update>
@@ -1,117 +0,0 @@
1
- ---
2
- title: Basic Configuration
3
- description: Set the identity, content source, and sidebar structure for a Heyo Docs site.
4
- ---
5
-
6
- # Basic Configuration
7
-
8
- `heyo-docs.config.ts` is the single source of truth for a Heyo Docs site.
9
- The framework integration and the documentation UI read the same validated
10
- object, so a change to navigation or metadata does not need to be repeated in
11
- multiple places.
12
-
13
- ## Start with the site model
14
-
15
- The generated project already includes a working configuration. Update the
16
- identity fields first, then point `content` at the directory that contains
17
- your MDX files.
18
-
19
- <CodeBlock language="ts" title="heyo-docs.config.ts" showLineNumbers>
20
- {`import { heyoDocs } from "@heyo-sh/heyo-docs";
21
-
22
- export default heyoDocs({
23
- title: "{{PROJECT_NAME}}",
24
- description: "Guides and reference for {{PROJECT_NAME}}.",
25
- content: "./content",
26
- theme: "grain",
27
- mode: "system",
28
- branding: { name: "{{PROJECT_NAME}}" },
29
- });`}
30
- </CodeBlock>
31
-
32
- Set `siteUrl` to the final public origin before publishing. It is used for
33
- canonical URLs, social metadata, the sitemap, RSS, and AI-facing discovery
34
- files.
35
-
36
- ## Organize the sidebar
37
-
38
- Use `groups` to define the order readers see. A group contains named sections
39
- and their MDX page references; a reference is relative to `content` and does
40
- not include the `.mdx` extension.
41
-
42
- <CodeBlock language="ts" title="heyo-docs.config.ts">
43
- {`groups: [
44
- {
45
- group: "Documentation",
46
- icon: "globe",
47
- sections: [
48
- {
49
- section: "Get Started",
50
- icon: "lightbulb",
51
- pages: ["quickstart", "configuration"],
52
- },
53
- {
54
- section: "Essentials",
55
- icon: "book",
56
- pages: ["essentials/text-styling", "essentials/code-blocks"],
57
- },
58
- ],
59
- },
60
- ],`}
61
- </CodeBlock>
62
-
63
- The order is meaningful: it controls the sidebar and the previous/next links at
64
- the end of each article. Use a page object with `title` and `src` when a
65
- sidebar entry should point to a page outside the local documentation.
66
-
67
- ## AI chat
68
-
69
- Add `ai.chat` to enable a documentation-aware chat through [Pi](https://github.com/badlogic/pi-mono).
70
- Use any provider identifier bundled with the installed Pi version, such as
71
- `openai`, `anthropic`, `google`, `openrouter`, or `xai`. Authentication stays
72
- server-only and is supplied by the route that handles the chat request.
73
-
74
- <CodeBlock language="ts" title="heyo-docs.config.ts">
75
- {`ai: {
76
- chat: {
77
- provider: "openai",
78
- model: "gpt-5-mini",
79
- variant: "right", // "center" shows the compact prompt first
80
- icon: "chat",
81
- text: "AI Chat",
82
- name: "Docs Assistant", // name shown in the drawer and message labels
83
- placeholder: "Ask AI about the docs", // used in the compact prompt and drawer
84
- },
85
- },`}
86
- </CodeBlock>
87
-
88
- `provider` and `model` are required. Keep the credential out of this
89
- configuration and pass it as `auth` to `createAiChatResponse` in the server
90
- route. Cloudflare routes obtain the key from the Worker `env` binding; Node.js
91
- routes can read their server environment there. GitHub Copilot and OpenAI Codex
92
- use `auth: { type: "oauth", getAccessToken }`; Amazon Bedrock uses either
93
- `{ type: "aws", region?, profile? }` and the AWS credential chain, or
94
- `{ type: "bedrock-bearer", token, region? }`. The model must be an actual model
95
- identifier, not the provider name. Amazon Bedrock requires a Node.js chat
96
- endpoint. `variant` defaults to `right`. `name`
97
- defaults to `AI`; it is used for the drawer title and the assistant's message
98
- label. `placeholder` defaults to
99
- `Ask AI about the docs` and is shared by the compact prompt and drawer input.
100
- The drawer stays open while
101
- readers navigate between documentation pages and does not block the rest of the
102
- page.
103
-
104
- Its chrome follows the selected documentation theme. For example, `grain` uses
105
- a full-height right panel with a left border, while the other themes keep a
106
- floating panel treatment.
107
-
108
- ## Verify the result
109
-
110
- Run the project's typecheck and build commands after changing configuration.
111
- They resolve each configured MDX page and report missing paths or malformed
112
- navigation before the site is deployed.
113
-
114
- <Callout type="info" title="Keep page metadata close to the page">
115
- Put a page's <code>title</code> and <code>description</code> in its MDX
116
- frontmatter. Keep shared site settings in <code>heyo-docs.config.ts</code>.
117
- </Callout>
@@ -1,70 +0,0 @@
1
- ---
2
- title: Deploying
3
- description: Build and publish your Heyo Docs site with the deployment target chosen during setup.
4
- ---
5
-
6
- # Deploying
7
-
8
- A Heyo Docs site is built as part of the framework application. The creator asks
9
- for a deployment target when the project is created and adds the corresponding
10
- configuration, so the same MDX content, navigation, search, and metadata are
11
- used locally and in production.
12
-
13
- ## Choose the target during setup
14
-
15
- Select Vercel or Cloudflare when running the creator if you already know where
16
- the site will live. The generated project includes the adapter and deployment
17
- configuration required by that platform. You can also choose to configure
18
- deployment later and keep the starter focused on local development.
19
-
20
- ## Build before publishing
21
-
22
- Run the production build on your machine before creating a deployment. It
23
- resolves every configured page, validates the navigation tree, and generates
24
- the sitemap, RSS feed, robots file, and AI-facing documentation endpoints.
25
-
26
- <CodeBlock language="bash" title="Terminal">
27
- {"bun run build"}
28
- </CodeBlock>
29
-
30
- Use the equivalent `npm run build`, `pnpm build`, or `yarn build` command
31
- when the project uses a different package manager.
32
-
33
- ## Cloudflare secrets
34
-
35
- For AI chat, save the provider key as a Worker secret:
36
-
37
- <CodeBlock language="bash" title="Terminal">
38
- {"bunx wrangler secret put OPENAI_API_KEY"}
39
- </CodeBlock>
40
-
41
- Keep the credential out of `heyo-docs.config.ts`. The Cloudflare overlay reads
42
- the native Worker `env.OPENAI_API_KEY` binding in the AI route, after the
43
- request reaches the Worker. It is never part of the documentation build or the
44
- browser bundle.
45
-
46
- <Callout type="tip" title="Set the canonical URL">
47
- Add the final public origin as <code>siteUrl</code> in
48
- <code>heyo-docs.config.ts</code> before the first production release. It keeps
49
- canonical links, social metadata, and generated discovery files consistent.
50
- </Callout>
51
-
52
- ## Publish the project
53
-
54
- For a generated Vercel or Cloudflare project, connect the repository in the
55
- provider dashboard or run the deployment script included by the selected setup.
56
- The provider builds the application with the same command you verified locally.
57
-
58
- <Steps>
59
- <Step title="Push the documentation source">
60
- Commit the MDX content and <code>heyo-docs.config.ts</code> together so the
61
- deployed navigation matches the reviewed pages.
62
- </Step>
63
- <Step title="Create a preview">
64
- Review the provider's preview URL for layout, links, search, and metadata.
65
- </Step>
66
- <Step title="Promote the production build">
67
- Publish once the preview is correct and the configured <code>siteUrl</code>
68
- matches the public domain.
69
- </Step>
70
- </Steps>