diff --git a/next-build.sh b/next-build.sh
index 7444d411..2b5c5ac5 100755
--- a/next-build.sh
+++ b/next-build.sh
@@ -20,7 +20,9 @@ fi
# Move API directory if building for export
if [ "$IS_EXPORT" = "true" ]; then
mkdir -p tmp
- mv src/app/api tmp/api-backup
+ mv src/app/api tmp/api-backup 2>/dev/null || true
+ # Also move proxy.ts as it's a server-side handler
+ mv src/proxy.ts tmp/proxy-backup.ts 2>/dev/null || true
fi
# Run Next.js build
@@ -29,7 +31,15 @@ STATUS=$?
# Restore API directory if it was moved
if [ "$IS_EXPORT" = "true" ]; then
- mv tmp/api-backup src/app/api
+ mv tmp/api-backup src/app/api 2>/dev/null || true
+ mv tmp/proxy-backup.ts src/proxy.ts 2>/dev/null || true
+
+ # Generate static .md files after build
+ if [ $STATUS -eq 0 ]; then
+ echo "Generating static .md files..."
+ npx tsx scripts/generate-md-files.ts
+ STATUS=$?
+ fi
fi
exit $STATUS
\ No newline at end of file
diff --git a/next-env.d.ts b/next-env.d.ts
index 9edff1c7..c4b7818f 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/types/routes.d.ts";
+import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/package.json b/package.json
index 9b45be6a..5d9e9163 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
"storybook": "^10.2.0",
"tailwindcss": "^4.1.18",
"tailwindcss-animate": "^1.0.7",
+ "tsx": "^4.21.0",
"tw-animate-css": "^1.4.0",
"typescript": "^5.6.2",
"unified": "^11.0.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 345e117d..ae9075c8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -131,13 +131,13 @@ importers:
version: 1.57.0
'@storybook/addon-docs':
specifier: ^10.2.0
- version: 10.2.0(@types/react@19.2.8)(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ version: 10.2.0(@types/react@19.2.8)(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
'@storybook/addon-themes':
specifier: ^10.2.0
version: 10.2.0(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
'@storybook/nextjs-vite':
specifier: ^10.2.0
- version: 10.2.0(@babel/core@7.28.6)(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ version: 10.2.0(@babel/core@7.28.6)(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
'@tailwindcss/postcss':
specifier: ^4.1.18
version: 4.1.18
@@ -219,6 +219,9 @@ importers:
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@4.1.18)
+ tsx:
+ specifier: ^4.21.0
+ version: 4.21.0
tw-animate-css:
specifier: ^1.4.0
version: 1.4.0
@@ -230,10 +233,10 @@ importers:
version: 11.0.5
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ version: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
vitest:
specifier: ^4.0.18
- version: 4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(yaml@2.8.2)
+ version: 4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
packages:
@@ -6064,6 +6067,11 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ tsx@4.21.0:
+ resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
tw-animate-css@1.4.0:
resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
@@ -7369,11 +7377,11 @@ snapshots:
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
- '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))':
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
glob: 11.1.0
react-docgen-typescript: 2.4.0(typescript@5.9.3)
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
optionalDependencies:
typescript: 5.9.3
@@ -8008,10 +8016,10 @@ snapshots:
storybook: 8.5.8(prettier@3.8.0)
ts-dedent: 2.2.0
- '@storybook/addon-docs@10.2.0(@types/react@19.2.8)(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
+ '@storybook/addon-docs@10.2.0(@types/react@19.2.8)(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
dependencies:
'@mdx-js/react': 3.1.1(@types/react@19.2.8)(react@19.2.3)
- '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
'@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@storybook/react-dom-shim': 10.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
react: 19.2.3
@@ -8095,13 +8103,13 @@ snapshots:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
- '@storybook/builder-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
+ '@storybook/builder-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
dependencies:
- '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
- '@vitest/mocker': 3.2.4(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
+ '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ '@vitest/mocker': 3.2.4(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
ts-dedent: 2.2.0
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
transitivePeerDependencies:
- esbuild
- msw
@@ -8173,14 +8181,14 @@ snapshots:
- supports-color
- utf-8-validate
- '@storybook/csf-plugin@10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
+ '@storybook/csf-plugin@10.2.0(esbuild@0.25.12)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
dependencies:
storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
unplugin: 2.3.11
optionalDependencies:
esbuild: 0.25.12
rollup: 4.57.0
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
webpack: 5.104.1(esbuild@0.25.12)
'@storybook/csf-plugin@8.5.8(storybook@8.5.8(prettier@3.8.0))':
@@ -8212,18 +8220,18 @@ snapshots:
dependencies:
storybook: 8.5.8(prettier@3.8.0)
- '@storybook/nextjs-vite@10.2.0(@babel/core@7.28.6)(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
+ '@storybook/nextjs-vite@10.2.0(@babel/core@7.28.6)(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
dependencies:
- '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
'@storybook/react': 10.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)
- '@storybook/react-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ '@storybook/react-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
next: 16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
styled-jsx: 5.1.6(@babel/core@7.28.6)(react@19.2.3)
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
- vite-plugin-storybook-nextjs: 3.1.9(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
+ vite-plugin-storybook-nextjs: 3.1.9(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
@@ -8261,11 +8269,11 @@ snapshots:
react-dom: 19.2.3(react@19.2.3)
storybook: 8.5.8(prettier@3.8.0)
- '@storybook/react-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
+ '@storybook/react-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))':
dependencies:
- '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
'@rollup/pluginutils': 5.3.0(rollup@4.57.0)
- '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
+ '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(rollup@4.57.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.104.1(esbuild@0.25.12))
'@storybook/react': 10.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)
empathic: 2.0.0
magic-string: 0.30.21
@@ -8275,7 +8283,7 @@ snapshots:
resolve: 1.22.11
storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
tsconfig-paths: 4.2.0
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
transitivePeerDependencies:
- esbuild
- msw
@@ -8845,23 +8853,23 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.0.3
- '@vitest/mocker@3.2.4(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))':
+ '@vitest/mocker@3.2.4(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
msw: 2.12.8(@types/node@25.0.9)(typescript@5.9.3)
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
- '@vitest/mocker@4.0.18(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))':
+ '@vitest/mocker@4.0.18(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
'@vitest/spy': 4.0.18
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
msw: 2.12.8(@types/node@25.0.9)(typescript@5.9.3)
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -8897,7 +8905,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vitest: 4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(yaml@2.8.2)
+ vitest: 4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
optional: true
'@vitest/utils@3.2.4':
@@ -13258,6 +13266,13 @@ snapshots:
tslib@2.8.1: {}
+ tsx@4.21.0:
+ dependencies:
+ esbuild: 0.27.2
+ get-tsconfig: 4.13.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
tw-animate-css@1.4.0: {}
type-check@0.4.0:
@@ -13513,7 +13528,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
- vite-plugin-storybook-nextjs@3.1.9(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)):
+ vite-plugin-storybook-nextjs@3.1.9(next@16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)):
dependencies:
'@next/env': 16.0.0
image-size: 2.0.2
@@ -13522,24 +13537,24 @@ snapshots:
next: 16.1.3(@babel/core@7.28.6)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
ts-dedent: 2.2.0
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
- vite-tsconfig-paths: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
+ vite-tsconfig-paths: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
transitivePeerDependencies:
- supports-color
- typescript
- vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)):
+ vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)):
dependencies:
debug: 4.4.3
globrex: 0.1.2
tsconfck: 3.1.6(typescript@5.9.3)
optionalDependencies:
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
transitivePeerDependencies:
- supports-color
- typescript
- vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2):
+ vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
dependencies:
esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3)
@@ -13553,12 +13568,13 @@ snapshots:
jiti: 2.6.1
lightningcss: 1.30.2
terser: 5.46.0
+ tsx: 4.21.0
yaml: 2.8.2
- vitest@4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(yaml@2.8.2):
+ vitest@4.0.18(@types/node@25.0.9)(@vitest/ui@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2):
dependencies:
'@vitest/expect': 4.0.18
- '@vitest/mocker': 4.0.18(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
+ '@vitest/mocker': 4.0.18(msw@2.12.8(@types/node@25.0.9)(typescript@5.9.3))(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))
'@vitest/pretty-format': 4.0.18
'@vitest/runner': 4.0.18
'@vitest/snapshot': 4.0.18
@@ -13575,7 +13591,7 @@ snapshots:
tinyexec: 1.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2)
+ vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 25.0.9
diff --git a/scripts/generate-md-files.ts b/scripts/generate-md-files.ts
new file mode 100644
index 00000000..fc1ea58c
--- /dev/null
+++ b/scripts/generate-md-files.ts
@@ -0,0 +1,81 @@
+#!/usr/bin/env tsx
+
+/**
+ * This script generates static .md files for all documentation pages
+ * It runs after the Next.js build to create plain text MDX files with frontmatter
+ */
+
+import matter from 'gray-matter'
+import fs from 'node:fs/promises'
+import path from 'node:path'
+
+const MARKDOWN_REGEX = /\.mdx?$/
+
+async function crawl(
+ dir: string,
+ filter?: (dir: string) => boolean,
+ files: string[] = [],
+): Promise {
+ const stat = await fs.lstat(dir)
+ if (stat.isDirectory()) {
+ const filenames = await fs.readdir(dir)
+ await Promise.all(filenames.map(async (filename) => crawl(`${dir}/${filename}`, filter, files)))
+ } else if (!filter || filter(dir)) {
+ files.push(dir)
+ }
+ return files
+}
+
+async function generateMdFiles() {
+ const MDX = process.env.MDX
+ if (!MDX) {
+ console.error('MDX environment variable not set')
+ process.exit(1)
+ }
+
+ const outputDir = process.env.DIST_DIR || 'out'
+ console.log(`Generating .md files in ${outputDir}...`)
+
+ try {
+ // Find all markdown files
+ const files = await crawl(
+ MDX,
+ (dir) => !dir.includes('node_modules') && MARKDOWN_REGEX.test(dir),
+ )
+
+ console.log(`Found ${files.length} markdown files`)
+
+ // Process each file
+ for (const file of files) {
+ const relativePath = file.replace(`${MDX}/`, '')
+ const slug = relativePath.replace(MARKDOWN_REGEX, '').toLowerCase().split('/')
+ const url = `/${slug.join('/')}`
+
+ // Read and parse the file
+ const str = await fs.readFile(file, { encoding: 'utf-8' })
+ const parsed = matter(str)
+
+ // Reconstruct the full MDX source with frontmatter
+ const frontmatterString = matter.stringify(parsed.content, parsed.data)
+
+ // Create output path
+ const mdPath = `${url}.md`
+ const fullPath = path.join(outputDir, mdPath)
+
+ // Ensure directory exists
+ const dir = path.dirname(fullPath)
+ await fs.mkdir(dir, { recursive: true })
+
+ // Write the .md file
+ await fs.writeFile(fullPath, frontmatterString, 'utf-8')
+ console.log(`Generated: ${mdPath}`)
+ }
+
+ console.log(`✓ Successfully generated ${files.length} .md files`)
+ } catch (error) {
+ console.error('Error generating .md files:', error)
+ process.exit(1)
+ }
+}
+
+generateMdFiles()
diff --git a/src/proxy.ts b/src/proxy.ts
new file mode 100644
index 00000000..1ac36e10
--- /dev/null
+++ b/src/proxy.ts
@@ -0,0 +1,52 @@
+import { parseDocsMetadata } from '@/utils/docs'
+import matter from 'gray-matter'
+import { NextRequest, NextResponse } from 'next/server'
+
+export default async function proxy(request: NextRequest) {
+ const { pathname } = request.nextUrl
+
+ // Check if the URL ends with .md
+ if (!pathname.endsWith('.md')) {
+ return NextResponse.next()
+ }
+
+ // Remove the .md suffix and leading slash to get the slug
+ const slugPath = pathname.slice(1, -3) // Remove leading '/' and trailing '.md'
+ const url = `/${slugPath}`
+
+ // Get MDX root directory
+ const MDX = process.env.MDX
+ if (!MDX) {
+ return new NextResponse(
+ 'MDX environment variable is not configured. Please set MDX to the path of your documentation root directory.',
+ { status: 500 },
+ )
+ }
+
+ try {
+ // Parse all docs to find the matching one
+ const docs = await parseDocsMetadata(MDX)
+ const doc = docs.find((d) => d.url.toLowerCase() === url.toLowerCase())
+
+ if (!doc) {
+ return new NextResponse(`Doc not found: ${url}`, { status: 404 })
+ }
+
+ // Reconstruct the full MDX source with frontmatter
+ const frontmatterString = matter.stringify(doc.content, doc.frontmatter)
+
+ // Return raw MDX source as plain text
+ return new NextResponse(frontmatterString, {
+ headers: {
+ 'Content-Type': 'text/markdown; charset=utf-8',
+ },
+ })
+ } catch (error) {
+ console.error('Error processing MDX source:', error)
+ return new NextResponse('Internal Server Error', { status: 500 })
+ }
+}
+
+export const config = {
+ matcher: '/:path*.md',
+}