@heyo-sh/create-heyo-docs 0.1.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 (146) hide show
  1. package/LICENSE +21 -0
  2. package/deployments/cloudflare/astro/package.json +12 -0
  3. package/deployments/cloudflare/astro/platform.astro.ts +4 -0
  4. package/deployments/cloudflare/astro/wrangler.jsonc +6 -0
  5. package/deployments/cloudflare/next/open-next.config.ts +3 -0
  6. package/deployments/cloudflare/next/package.json +13 -0
  7. package/deployments/cloudflare/next/wrangler.jsonc +11 -0
  8. package/deployments/cloudflare/react-router/app/entry.server.tsx +48 -0
  9. package/deployments/cloudflare/react-router/package.json +21 -0
  10. package/deployments/cloudflare/react-router/platform.vite.ts +6 -0
  11. package/deployments/cloudflare/react-router/react-router.config.ts +20 -0
  12. package/deployments/cloudflare/react-router/workers/app.ts +12 -0
  13. package/deployments/cloudflare/react-router/wrangler.jsonc +10 -0
  14. package/deployments/vercel/astro/package.json +11 -0
  15. package/deployments/vercel/astro/platform.astro.ts +4 -0
  16. package/deployments/vercel/astro/vercel.json +4 -0
  17. package/deployments/vercel/next/package.json +8 -0
  18. package/deployments/vercel/next/vercel.json +3 -0
  19. package/deployments/vercel/react-router/package.json +12 -0
  20. package/deployments/vercel/react-router/platform.vite.ts +4 -0
  21. package/deployments/vercel/react-router/react-router.config.ts +22 -0
  22. package/deployments/vercel/react-router/vercel.json +4 -0
  23. package/dist/index.d.ts +13 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +328 -0
  26. package/dist/package-manager.d.ts +6 -0
  27. package/dist/package-manager.d.ts.map +1 -0
  28. package/dist/project-name.d.ts +3 -0
  29. package/dist/project-name.d.ts.map +1 -0
  30. package/dist/scaffold.d.ts +5 -0
  31. package/dist/scaffold.d.ts.map +1 -0
  32. package/dist/types.d.ts +19 -0
  33. package/dist/types.d.ts.map +1 -0
  34. package/dist/utils.d.ts +8 -0
  35. package/dist/utils.d.ts.map +1 -0
  36. package/package.json +36 -0
  37. package/templates/astro/astro.config.ts +15 -0
  38. package/templates/astro/components.json +25 -0
  39. package/templates/astro/content/getting-started.mdx +16 -0
  40. package/templates/astro/content/index.mdx +22 -0
  41. package/templates/astro/content/mdx-components.mdx +44 -0
  42. package/templates/astro/heyo-docs.config.ts +24 -0
  43. package/templates/astro/package.json +34 -0
  44. package/templates/astro/platform.astro.ts +4 -0
  45. package/templates/astro/public/apple-touch-icon.png +0 -0
  46. package/templates/astro/public/favicon-96x96.png +0 -0
  47. package/templates/astro/public/favicon.ico +0 -0
  48. package/templates/astro/public/favicon.svg +1 -0
  49. package/templates/astro/public/logo.svg +12 -0
  50. package/templates/astro/public/site.webmanifest +21 -0
  51. package/templates/astro/public/web-app-manifest-192x192.png +0 -0
  52. package/templates/astro/public/web-app-manifest-512x512.png +0 -0
  53. package/templates/astro/src/components/docs-app.tsx +165 -0
  54. package/templates/astro/src/components/theme-provider.tsx +106 -0
  55. package/templates/astro/src/env.d.ts +2 -0
  56. package/templates/astro/src/heyo-docs-icons.tsx +79 -0
  57. package/templates/astro/src/layouts/docs-layout.astro +70 -0
  58. package/templates/astro/src/lib/docs.ts +31 -0
  59. package/templates/astro/src/lib/openapi-request.ts +160 -0
  60. package/templates/astro/src/lib/seo.ts +221 -0
  61. package/templates/astro/src/lib/theme.ts +74 -0
  62. package/templates/astro/src/pages/[...slug].astro +50 -0
  63. package/templates/astro/src/pages/[...slug].md.ts +28 -0
  64. package/templates/astro/src/pages/heyo-docs-internal/openapi-request.ts +8 -0
  65. package/templates/astro/src/pages/llms-full.txt.ts +13 -0
  66. package/templates/astro/src/pages/llms.txt.ts +13 -0
  67. package/templates/astro/src/pages/robots.txt.ts +19 -0
  68. package/templates/astro/src/pages/rss.xml.ts +13 -0
  69. package/templates/astro/src/pages/sitemap.xml.ts +19 -0
  70. package/templates/astro/src/styles/app.css +8 -0
  71. package/templates/astro/src/virtual.d.ts +19 -0
  72. package/templates/astro/tsconfig.json +12 -0
  73. package/templates/next/app/[[...slug]]/page.tsx +59 -0
  74. package/templates/next/app/app.css +8 -0
  75. package/templates/next/app/components/docs-app.tsx +139 -0
  76. package/templates/next/app/components/theme-provider.tsx +93 -0
  77. package/templates/next/app/error.tsx +8 -0
  78. package/templates/next/app/heyo-docs-icons.tsx +70 -0
  79. package/templates/next/app/heyo-docs-internal/markdown/[[...slug]]/route.ts +26 -0
  80. package/templates/next/app/heyo-docs-internal/openapi-request/route.ts +5 -0
  81. package/templates/next/app/layout.tsx +79 -0
  82. package/templates/next/app/lib/docs.ts +43 -0
  83. package/templates/next/app/lib/openapi-request.ts +147 -0
  84. package/templates/next/app/lib/seo.ts +189 -0
  85. package/templates/next/app/lib/theme.ts +61 -0
  86. package/templates/next/app/llms-full.txt/route.ts +10 -0
  87. package/templates/next/app/llms.txt/route.ts +10 -0
  88. package/templates/next/app/not-found.tsx +13 -0
  89. package/templates/next/app/robots.txt/route.ts +16 -0
  90. package/templates/next/app/rss.xml/route.ts +10 -0
  91. package/templates/next/app/sitemap.xml/route.ts +14 -0
  92. package/templates/next/components.json +20 -0
  93. package/templates/next/content/getting-started.mdx +16 -0
  94. package/templates/next/content/index.mdx +22 -0
  95. package/templates/next/content/mdx-components.mdx +41 -0
  96. package/templates/next/heyo-docs.config.ts +24 -0
  97. package/templates/next/mdx.d.ts +6 -0
  98. package/templates/next/next-env.d.ts +7 -0
  99. package/templates/next/next.config.ts +23 -0
  100. package/templates/next/package.json +40 -0
  101. package/templates/next/postcss.config.mjs +5 -0
  102. package/templates/next/public/apple-touch-icon.png +0 -0
  103. package/templates/next/public/favicon-96x96.png +0 -0
  104. package/templates/next/public/favicon.ico +0 -0
  105. package/templates/next/public/favicon.svg +1 -0
  106. package/templates/next/public/logo.svg +12 -0
  107. package/templates/next/public/site.webmanifest +21 -0
  108. package/templates/next/public/web-app-manifest-192x192.png +0 -0
  109. package/templates/next/public/web-app-manifest-512x512.png +0 -0
  110. package/templates/next/scripts/generate-heyo-docs.ts +50 -0
  111. package/templates/next/tsconfig.json +27 -0
  112. package/templates/react-router/app/app.css +8 -0
  113. package/templates/react-router/app/components/theme-provider.tsx +106 -0
  114. package/templates/react-router/app/heyo-docs-icons.tsx +71 -0
  115. package/templates/react-router/app/lib/theme.ts +74 -0
  116. package/templates/react-router/app/root.tsx +140 -0
  117. package/templates/react-router/app/routes/docs.tsx +179 -0
  118. package/templates/react-router/app/routes/home.tsx +1 -0
  119. package/templates/react-router/app/routes/llms-full.ts +13 -0
  120. package/templates/react-router/app/routes/llms.ts +13 -0
  121. package/templates/react-router/app/routes/markdown.ts +25 -0
  122. package/templates/react-router/app/routes/openapi-request.ts +159 -0
  123. package/templates/react-router/app/routes/page.tsx +1 -0
  124. package/templates/react-router/app/routes/robots.ts +19 -0
  125. package/templates/react-router/app/routes/rss.ts +13 -0
  126. package/templates/react-router/app/routes/sitemap.ts +18 -0
  127. package/templates/react-router/app/routes.ts +13 -0
  128. package/templates/react-router/app/virtual.d.ts +19 -0
  129. package/templates/react-router/components.json +25 -0
  130. package/templates/react-router/content/getting-started.mdx +16 -0
  131. package/templates/react-router/content/index.mdx +22 -0
  132. package/templates/react-router/content/mdx-components.mdx +293 -0
  133. package/templates/react-router/heyo-docs.config.ts +24 -0
  134. package/templates/react-router/package.json +36 -0
  135. package/templates/react-router/platform.vite.ts +2 -0
  136. package/templates/react-router/public/apple-touch-icon.png +0 -0
  137. package/templates/react-router/public/favicon-96x96.png +0 -0
  138. package/templates/react-router/public/favicon.ico +0 -0
  139. package/templates/react-router/public/favicon.svg +1 -0
  140. package/templates/react-router/public/logo.svg +12 -0
  141. package/templates/react-router/public/site.webmanifest +21 -0
  142. package/templates/react-router/public/web-app-manifest-192x192.png +0 -0
  143. package/templates/react-router/public/web-app-manifest-512x512.png +0 -0
  144. package/templates/react-router/react-router.config.ts +20 -0
  145. package/templates/react-router/tsconfig.json +20 -0
  146. package/templates/react-router/vite.config.ts +17 -0
@@ -0,0 +1,189 @@
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
+ }
@@ -0,0 +1,61 @@
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
+ }
@@ -0,0 +1,10 @@
1
+ import { llmsFull } from "@heyo-sh/heyo-docs/node";
2
+
3
+ import { config, markdownPages } from "../lib/docs";
4
+
5
+ export function GET(request: Request) {
6
+ const siteUrl = config.siteUrl ?? new URL(request.url).origin;
7
+ return new Response(llmsFull(markdownPages, siteUrl), {
8
+ headers: { "content-type": "text/plain; charset=utf-8" },
9
+ });
10
+ }
@@ -0,0 +1,10 @@
1
+ import { llmsIndex } from "@heyo-sh/heyo-docs/node";
2
+
3
+ import { config, markdownPages } from "../lib/docs";
4
+
5
+ export function GET(request: Request) {
6
+ const siteUrl = config.siteUrl ?? new URL(request.url).origin;
7
+ return new Response(llmsIndex(markdownPages, config, siteUrl), {
8
+ headers: { "content-type": "text/plain; charset=utf-8" },
9
+ });
10
+ }
@@ -0,0 +1,13 @@
1
+ import type { Metadata } from "next";
2
+
3
+ import config from "../heyo-docs.config";
4
+ import { NextDocsApp } from "./components/docs-app";
5
+
6
+ export const metadata: Metadata = {
7
+ title: `Not found | ${config.title}`,
8
+ robots: { index: false, follow: false },
9
+ };
10
+
11
+ export default function NotFound() {
12
+ return <NextDocsApp pathname="/__not-found" />;
13
+ }
@@ -0,0 +1,16 @@
1
+ import { config } from "../lib/docs";
2
+
3
+ export function GET(request: Request) {
4
+ const siteUrl = config.siteUrl ?? new URL(request.url).origin;
5
+ return new Response(
6
+ [
7
+ "User-agent: *",
8
+ "Allow: /",
9
+ "Disallow: /__heyo-docs/",
10
+ "",
11
+ `Sitemap: ${siteUrl}/sitemap.xml`,
12
+ "",
13
+ ].join("\n"),
14
+ { headers: { "content-type": "text/plain; charset=utf-8" } },
15
+ );
16
+ }
@@ -0,0 +1,10 @@
1
+ import { rssXml } from "@heyo-sh/heyo-docs/node";
2
+
3
+ import { config, markdownPages } from "../lib/docs";
4
+
5
+ export function GET(request: Request) {
6
+ const siteUrl = config.siteUrl ?? new URL(request.url).origin;
7
+ return new Response(rssXml(markdownPages, config, siteUrl), {
8
+ headers: { "content-type": "application/rss+xml; charset=utf-8" },
9
+ });
10
+ }
@@ -0,0 +1,14 @@
1
+ import { sitemapXml } from "@heyo-sh/heyo-docs/node";
2
+
3
+ import { config, docsModel } from "../lib/docs";
4
+
5
+ export function GET(request: Request) {
6
+ const siteUrl = config.siteUrl ?? new URL(request.url).origin;
7
+ return new Response(
8
+ sitemapXml(
9
+ siteUrl,
10
+ [...docsModel.pages, ...docsModel.endpoints].map((page) => page.slug),
11
+ ),
12
+ { headers: { "content-type": "application/xml; charset=utf-8" } },
13
+ );
14
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "base-mira",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "",
8
+ "css": "app/app.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components",
15
+ "utils": "@/lib/utils",
16
+ "ui": "@/components/ui",
17
+ "lib": "@/lib",
18
+ "hooks": "@/hooks"
19
+ }
20
+ }
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: Getting started
3
+ description: Run your new documentation site locally.
4
+ ---
5
+
6
+ # Getting started
7
+
8
+ Install dependencies with your chosen package manager and start the development server.
9
+
10
+ ## Create a page
11
+
12
+ Create `content/guides/deploying.mdx` to get the `/guides/deploying` route. Its frontmatter controls its title and description.
13
+
14
+ ## Configure the documentation
15
+
16
+ Use `heyo-docs.config.ts` to change the title, colors, tabs, sidebar groups, footer links and selected theme without regenerating your project. Add pages or directories to a section's `pages` list to control the sidebar order.
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Welcome to {{PROJECT_NAME}}
3
+ description: Everything you need to document your product with Heyo Docs.
4
+ ---
5
+
6
+ # Welcome to {{PROJECT_NAME}}
7
+
8
+ Start with this page, then add focused MDX files to the `content` directory. Heyo Docs turns the directory structure into routes; use `groups` in `heyo-docs.config.ts` to control sidebar navigation and its order.
9
+
10
+ ## What is included?
11
+
12
+ - A Next.js App Router application.
13
+ - The selected documentation theme from `heyo-docs`.
14
+ - Searchable page metadata, SEO tags, `robots.txt`, a sitemap, RSS, LLM files, Markdown mirrors, and a 404 page.
15
+
16
+ ## Edit this page
17
+
18
+ ```mdx
19
+ ## A new section
20
+
21
+ Content updates reload in development.
22
+ ```
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: MDX components
3
+ description: Every built-in MDX component is available without an import.
4
+ ---
5
+
6
+ # MDX components
7
+
8
+ Every built-in component is available in a Next.js MDX page without an import.
9
+
10
+ ## Callout
11
+
12
+ <Callout
13
+ type="tip"
14
+ title="No imports needed"
15
+ description="Use the documentation components directly in your MDX files."
16
+ />
17
+
18
+ ## Tabs
19
+
20
+ <Tabs defaultValue="npm" variant="line">
21
+ <Tab title="npm" value="npm">
22
+ npm run dev
23
+ </Tab>
24
+ <Tab title="Bun" value="bun">
25
+ bun run dev
26
+ </Tab>
27
+ </Tabs>
28
+
29
+ ## Code blocks
30
+
31
+ `CodeBlock` preserves every newline as a hard code line.
32
+
33
+ <CodeBlock language="tsx" title="app/page.tsx" showLineNumbers>
34
+ {`export default function Page() {
35
+ return <h1>Hello</h1>;
36
+ }`}
37
+ </CodeBlock>
38
+
39
+ ## More components
40
+
41
+ `Accordion`, `Button`, `Columns`, `File`, `GitHub`, `HoverCard`, `Image`, `Mermaid`, `RelatedTopics`, `Steps`, `Tree`, `Video`, and the remaining primitives use the same MDX contract as every Heyo Docs template.
@@ -0,0 +1,24 @@
1
+ import { heyoDocs } from "@heyo-sh/heyo-docs/config";
2
+
3
+ export default heyoDocs({
4
+ title: "{{PROJECT_NAME}}",
5
+ description: "Developer documentation",
6
+ content: "./content",
7
+ theme: "{{THEME}}",
8
+ mode: "system",
9
+ groups: [
10
+ {
11
+ group: "Documentation",
12
+ icon: "globe",
13
+ sections: [
14
+ {
15
+ section: "Get started",
16
+ pages: ["index"],
17
+ },
18
+ ],
19
+ },
20
+ ],
21
+ branding: { name: "{{PROJECT_NAME}}" },
22
+ // Set this before deploying to publish canonical and absolute social URLs.
23
+ // siteUrl: "https://docs.example.com",
24
+ });
@@ -0,0 +1,6 @@
1
+ declare module "*.mdx" {
2
+ import type { ComponentType } from "react";
3
+
4
+ const MDXContent: ComponentType;
5
+ export default MDXContent;
6
+ }
@@ -0,0 +1,7 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/types/routes.d.ts";
4
+ import "./.next/types/root-params.d.ts";
5
+
6
+ // NOTE: This file should not be edited
7
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -0,0 +1,23 @@
1
+ import createMDX from "@next/mdx";
2
+ import type { NextConfig } from "next";
3
+ import { heyoDocsMdxOptions } from "@heyo-sh/heyo-docs/next";
4
+
5
+ const nextConfig: NextConfig = {
6
+ pageExtensions: ["ts", "tsx", "md", "mdx"],
7
+ async rewrites() {
8
+ return {
9
+ beforeFiles: [
10
+ {
11
+ source: "/:path*.md",
12
+ destination: "/heyo-docs-internal/markdown/:path*",
13
+ },
14
+ ],
15
+ };
16
+ },
17
+ };
18
+
19
+ const withMdx = createMDX({
20
+ options: heyoDocsMdxOptions({ root: process.cwd() }) as never,
21
+ });
22
+
23
+ export default withMdx(nextConfig);
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "packageManager": "{{PACKAGE_MANAGER}}",
7
+ "scripts": {
8
+ "predev": "tsx scripts/generate-heyo-docs.ts",
9
+ "dev": "concurrently --kill-others-on-fail \"next dev\" \"tsx scripts/generate-heyo-docs.ts --watch\"",
10
+ "build": "tsx scripts/generate-heyo-docs.ts && next build",
11
+ "start": "next start",
12
+ "typecheck": "tsx scripts/generate-heyo-docs.ts && tsc --noEmit"
13
+ },
14
+ "dependencies": {
15
+ "@fontsource-variable/figtree": "^5.3.0",
16
+ "@remixicon/react": "^4.9.0",
17
+ "@heyo-sh/heyo-docs": "{{HEYO_DOCS_VERSION}}",
18
+ "next": "16.3.2",
19
+ "react": "19.2.8",
20
+ "react-dom": "19.2.8",
21
+ "shadcn": "^4.19.0",
22
+ "tw-animate-css": "^1.4.0"
23
+ },
24
+ "devDependencies": {
25
+ "@next/mdx": "16.3.2",
26
+ "@mdx-js/loader": "3.1.0",
27
+ "@mdx-js/react": "3.1.0",
28
+ "@tailwindcss/postcss": "^4.1.14",
29
+ "@types/node": "24.10.1",
30
+ "@types/react": "19.2.7",
31
+ "@types/react-dom": "19.2.3",
32
+ "concurrently": "^9.2.1",
33
+ "rehype-slug": "6.0.0",
34
+ "remark-frontmatter": "5.0.0",
35
+ "remark-gfm": "^4.0.1",
36
+ "tailwindcss": "^4.1.14",
37
+ "tsx": "^4.20.6",
38
+ "typescript": "5.9.3"
39
+ }
40
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };