diff --git a/.gitignore b/.gitignore index 3e14da3..9130a59 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # dependencies /node_modules +/content/node_modules /.pnp .pnp.js diff --git a/content/docs.site.json b/content/docs.site.json index c9ea6d1..7686185 100644 --- a/content/docs.site.json +++ b/content/docs.site.json @@ -22,6 +22,20 @@ "radius": "0.5rem" } }, + "products": [ + { + "title": "Documentation", + "description": "Core documentation engine", + "url": "/docs/core", + "icon": "FileText" + }, + { + "title": "Platform", + "description": "Enterprise platform docs", + "url": "/docs/platform", + "icon": "Layers" + } + ], "layout": { "navbar": { "enabled": true, diff --git a/content/docs/components/meta.json b/content/docs/core/components/meta.json similarity index 100% rename from content/docs/components/meta.json rename to content/docs/core/components/meta.json diff --git a/content/docs/components/objectui-embed.mdx b/content/docs/core/components/objectui-embed.mdx similarity index 100% rename from content/docs/components/objectui-embed.mdx rename to content/docs/core/components/objectui-embed.mdx diff --git a/content/docs/development-plan.mdx b/content/docs/core/development-plan.mdx similarity index 100% rename from content/docs/development-plan.mdx rename to content/docs/core/development-plan.mdx diff --git a/content/docs/getting-started/architecture.mdx b/content/docs/core/getting-started/architecture.mdx similarity index 100% rename from content/docs/getting-started/architecture.mdx rename to content/docs/core/getting-started/architecture.mdx diff --git a/content/docs/getting-started/configuration.mdx b/content/docs/core/getting-started/configuration.mdx similarity index 100% rename from content/docs/getting-started/configuration.mdx rename to content/docs/core/getting-started/configuration.mdx diff --git a/content/docs/getting-started/installation.mdx b/content/docs/core/getting-started/installation.mdx similarity index 100% rename from content/docs/getting-started/installation.mdx rename to content/docs/core/getting-started/installation.mdx diff --git a/content/docs/getting-started/meta.json b/content/docs/core/getting-started/meta.json similarity index 100% rename from content/docs/getting-started/meta.json rename to content/docs/core/getting-started/meta.json diff --git a/content/docs/index.mdx b/content/docs/core/index.mdx similarity index 100% rename from content/docs/index.mdx rename to content/docs/core/index.mdx diff --git a/content/docs/meta.json b/content/docs/core/meta.json similarity index 100% rename from content/docs/meta.json rename to content/docs/core/meta.json diff --git a/content/docs/platform/index.mdx b/content/docs/platform/index.mdx new file mode 100644 index 0000000..6b4f2c8 --- /dev/null +++ b/content/docs/platform/index.mdx @@ -0,0 +1,12 @@ +--- +title: Platform Documentation +description: Enterprise low-code platform documentation +--- + +# Platform Documentation + +Welcome to the Platform documentation. This section covers the enterprise low-code platform features and capabilities. + +## Getting Started + +Explore the platform features and learn how to build enterprise applications. diff --git a/content/docs/platform/meta.json b/content/docs/platform/meta.json new file mode 100644 index 0000000..97d7430 --- /dev/null +++ b/content/docs/platform/meta.json @@ -0,0 +1,6 @@ +{ + "title": "Platform", + "pages": [ + "index" + ] +} diff --git a/content/package-lock.json b/content/package-lock.json new file mode 100644 index 0000000..2af4e19 --- /dev/null +++ b/content/package-lock.json @@ -0,0 +1,22 @@ +{ + "name": "content", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "content", + "dependencies": { + "lucide-react": "^0.562.0" + } + }, + "node_modules/lucide-react": { + "version": "0.562.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz", + "integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + } + } +} diff --git a/content/package.json b/content/package.json new file mode 100644 index 0000000..eb76c36 --- /dev/null +++ b/content/package.json @@ -0,0 +1,7 @@ +{ + "name": "content", + "private": true, + "dependencies": { + "lucide-react": "^0.562.0" + } +} diff --git a/packages/cli/src/commands/build.mjs b/packages/cli/src/commands/build.mjs index 93e520b..c6f6666 100644 --- a/packages/cli/src/commands/build.mjs +++ b/packages/cli/src/commands/build.mjs @@ -50,7 +50,7 @@ export function registerBuildCommand(cli) { DOCS_DIR: docsDir }; - const nextCmd = 'npm'; + const nextCmd = 'pnpm'; const args = ['run', 'build']; const child = spawn(nextCmd, args, { diff --git a/packages/cli/src/commands/dev.mjs b/packages/cli/src/commands/dev.mjs index 4054e5c..99cdb93 100644 --- a/packages/cli/src/commands/dev.mjs +++ b/packages/cli/src/commands/dev.mjs @@ -35,7 +35,7 @@ export function registerDevCommand(cli) { PORT: options.port }; - const nextCmd = 'npm'; + const nextCmd = 'pnpm'; const args = ['run', 'dev', '--', '-p', options.port]; let child; diff --git a/packages/cli/src/commands/start.mjs b/packages/cli/src/commands/start.mjs index ae2da7e..bb9e52a 100644 --- a/packages/cli/src/commands/start.mjs +++ b/packages/cli/src/commands/start.mjs @@ -59,7 +59,7 @@ export function registerStartCommand(cli) { }; - const child = spawn('npm', ['start'], { + const child = spawn('pnpm', ['start'], { cwd: nextAppDir, stdio: 'inherit', env: env diff --git a/packages/site/app/[lang]/docs/[[...slug]]/page.tsx b/packages/site/app/[lang]/docs/[[...slug]]/page.tsx index 566674d..5d8d64e 100644 --- a/packages/site/app/[lang]/docs/[[...slug]]/page.tsx +++ b/packages/site/app/[lang]/docs/[[...slug]]/page.tsx @@ -1,4 +1,4 @@ -import { source } from '@/lib/source'; +import { coreLoader, platformLoader } from '@/lib/source'; import type { Metadata } from 'next'; import { DocsPage, DocsBody } from 'fumadocs-ui/page'; import { notFound } from 'next/navigation'; @@ -8,6 +8,12 @@ import { Steps, Step } from 'fumadocs-ui/components/steps'; import { Card, Cards } from 'fumadocs-ui/components/card'; import { Callout } from 'fumadocs-ui/components/callout'; +// Map of root names to their loaders +const loaderMap: Record = { + 'core': coreLoader, + 'platform': platformLoader, +}; + interface PageProps { params: Promise<{ lang: string; @@ -18,19 +24,29 @@ interface PageProps { export default async function Page({ params }: PageProps) { const { lang, slug = [] } = await params; - const page = source.getPage(slug, lang); + // Determine the current root from the URL + const currentRoot = slug.length > 0 ? slug[0] : 'core'; + + // Get the page path (everything after the root) + const pagePath = slug.slice(1); + + // Get the appropriate loader + const currentLoader = loaderMap[currentRoot] || coreLoader; + + const page = currentLoader.getPage(pagePath, lang); if (!page) { notFound(); } - const MDX = page.data.body as any; + const pageData = page.data as any; + const MDX = pageData.body; return ( 2 ? 'clerk' : 'normal', @@ -51,12 +67,31 @@ export default async function Page({ params }: PageProps) { export async function generateStaticParams() { - return source.generateParams(); + // Generate params for all loaders + const coreParams = coreLoader.generateParams().map(param => ({ + ...param, + slug: ['core', ...(param.slug || [])], + })); + + const platformParams = platformLoader.generateParams().map(param => ({ + ...param, + slug: ['platform', ...(param.slug || [])], + })); + + return [...coreParams, ...platformParams]; } export async function generateMetadata({ params }: PageProps): Promise { const { lang, slug = [] } = await params; - const page = source.getPage(slug, lang); + + // Determine the current root + const currentRoot = slug.length > 0 ? slug[0] : 'core'; + const pagePath = slug.slice(1); + + // Get the appropriate loader + const currentLoader = loaderMap[currentRoot] || coreLoader; + + const page = currentLoader.getPage(pagePath, lang); if (!page) notFound(); diff --git a/packages/site/app/[lang]/docs/layout.tsx b/packages/site/app/[lang]/docs/layout.tsx index b2d0326..7c5d988 100644 --- a/packages/site/app/[lang]/docs/layout.tsx +++ b/packages/site/app/[lang]/docs/layout.tsx @@ -1,27 +1,94 @@ -import { source } from '@/lib/source'; +import { coreLoader, platformLoader } from '@/lib/source'; import { DocsLayout } from 'fumadocs-ui/layouts/docs'; import type { ReactNode } from 'react'; import { baseOptions } from '@/app/layout.config'; import { siteConfig } from '@/lib/site-config'; +import { + Box, + Layers, + Package, + Blocks, + Component, + Database, + Settings, + Zap, + Code, + FileText +} from 'lucide-react'; + +// Icon mapping for dynamic icon rendering +// Supports common icons for documentation products +const iconMap: Record = { + Box, + Layers, + Package, + Blocks, + Component, + Database, + Settings, + Zap, + Code, + FileText, +}; + +// Map of root names to their loaders +const loaderMap: Record = { + 'core': coreLoader, + 'platform': platformLoader, +}; export default async function Layout({ params, children, }: { - params: Promise<{ lang: string }>; + params: Promise<{ lang: string; slug?: string[] }>; children: ReactNode; }) { - const { lang } = await params; + const { lang, slug = [] } = await params; + + // Determine the current root from the URL + // The first slug segment indicates which root we're viewing (core, platform, etc.) + const currentRoot = slug.length > 0 ? slug[0] : 'core'; + + // Get the appropriate loader for the current root + const currentLoader = loaderMap[currentRoot] || coreLoader; + + // Get the page tree for the current root + const tree = currentLoader.pageTree[lang]; + + // Build tabs/root toggle options from products config if available + const rootToggleTabs = siteConfig.products && siteConfig.products.length > 0 + ? siteConfig.products.map(product => { + const Icon = iconMap[product.icon] || Box; + return { + title: product.title, + description: product.description, + url: `/${lang}${product.url}`, + icon: ( +
+ +
+ ), + }; + }) + : siteConfig.layout.sidebar.tabs && siteConfig.layout.sidebar.tabs.length > 0 + ? siteConfig.layout.sidebar.tabs.map(tab => ({ + title: tab.title, + url: `/${lang}${tab.url}`, + description: tab.description, + })) + : undefined; return ( {siteConfig.layout.sidebar.footer.html ? ( @@ -31,12 +98,6 @@ export default async function Layout({ )} ) : undefined, - tabs: siteConfig.layout.sidebar.tabs && siteConfig.layout.sidebar.tabs.length > 0 ? - siteConfig.layout.sidebar.tabs.map(tab => ({ - title: tab.title, - url: tab.url, - description: tab.description, - })) : undefined, banner: siteConfig.layout.sidebar.banner ? (
diff --git a/packages/site/app/api/search/route.ts b/packages/site/app/api/search/route.ts index 793e090..9b08e5c 100644 --- a/packages/site/app/api/search/route.ts +++ b/packages/site/app/api/search/route.ts @@ -1,12 +1,21 @@ -import { source } from '@/lib/source'; +import { coreLoader, platformLoader } from '@/lib/source'; import { createSearchAPI } from 'fumadocs-core/search/server'; export const { GET } = createSearchAPI('advanced', { - indexes: source.getPages().map((page) => ({ - title: page.data.title, - description: page.data.description, - url: page.url, - id: page.url, - structuredData: page.data.structuredData, - })), + indexes: [ + ...coreLoader.getPages().map((page) => ({ + title: page.data.title || '', + description: page.data.description || '', + url: page.url, + id: page.url, + structuredData: (page.data as any).structuredData, + })), + ...platformLoader.getPages().map((page) => ({ + title: page.data.title || '', + description: page.data.description || '', + url: page.url, + id: page.url, + structuredData: (page.data as any).structuredData, + })), + ], }); diff --git a/packages/site/docs.site.json b/packages/site/docs.site.json index c9ea6d1..7686185 100644 --- a/packages/site/docs.site.json +++ b/packages/site/docs.site.json @@ -22,6 +22,20 @@ "radius": "0.5rem" } }, + "products": [ + { + "title": "Documentation", + "description": "Core documentation engine", + "url": "/docs/core", + "icon": "FileText" + }, + { + "title": "Platform", + "description": "Enterprise platform docs", + "url": "/docs/platform", + "icon": "Layers" + } + ], "layout": { "navbar": { "enabled": true, diff --git a/packages/site/lib/site-config.ts b/packages/site/lib/site-config.ts index f5c5f26..b061fc5 100644 --- a/packages/site/lib/site-config.ts +++ b/packages/site/lib/site-config.ts @@ -27,6 +27,12 @@ export interface SiteConfig { radius: string; }; }; + products?: Array<{ + title: string; + description: string; + url: string; + icon: string; + }>; layout: { navbar: { enabled: boolean; diff --git a/packages/site/lib/source.ts b/packages/site/lib/source.ts index 774f52f..cfcd196 100644 --- a/packages/site/lib/source.ts +++ b/packages/site/lib/source.ts @@ -1,16 +1,23 @@ import { loader } from 'fumadocs-core/source'; -import { docs, meta } from '@/.source/server'; +import { core, platform } from '@/.source/server'; import { toFumadocsSource } from 'fumadocs-mdx/runtime/server'; import { i18n } from './i18n'; -const mainSource = toFumadocsSource(docs, meta); +const coreSource = toFumadocsSource(core.docs, core.meta); +const platformSource = toFumadocsSource(platform.docs, platform.meta); -export const source = loader({ - baseUrl: '/docs', - source: { - files: [ - ...mainSource.files, - ], - }, +// Create separate loaders for each documentation root +export const coreLoader = loader({ + baseUrl: '/docs/core', + source: coreSource, i18n, }); + +export const platformLoader = loader({ + baseUrl: '/docs/platform', + source: platformSource, + i18n, +}); + +// Default export for backward compatibility +export const source = coreLoader; diff --git a/packages/site/next.config.mjs b/packages/site/next.config.mjs index bfee7f4..fc8cb2a 100644 --- a/packages/site/next.config.mjs +++ b/packages/site/next.config.mjs @@ -7,6 +7,7 @@ const nextConfig = { reactStrictMode: true, distDir: '.next', images: { unoptimized: true }, + transpilePackages: ['lucide-react'], }; export default withMDX(nextConfig); diff --git a/packages/site/package.json b/packages/site/package.json index 6b70876..6efdbfa 100644 --- a/packages/site/package.json +++ b/packages/site/package.json @@ -9,14 +9,8 @@ "lint": "next lint", "test": "echo \"No test specified\" && exit 0" }, - "peerDependencies": { - }, "dependencies": { "@fumadocs/ui": "^16.4.7", - "fumadocs-core": "^16.4.7", - "fumadocs-mdx": "^14.2.5", - "fumadocs-ui": "^16.4.7", - "next": "^16.1.2", "@tailwindcss/postcss": "^4.1.18", "@types/mdx": "^2.0.13", "@types/node": "^25.0.8", @@ -24,6 +18,11 @@ "autoprefixer": "^10.4.23", "client-only": "^0.0.1", "dotenv": "^16.4.5", + "fumadocs-core": "^16.4.7", + "fumadocs-mdx": "^14.2.5", + "fumadocs-ui": "^16.4.7", + "lucide-react": "^0.562.0", + "next": "^16.1.2", "openai": "^4.0.0", "postcss": "^8.5.6", "react": "^19.2.3", diff --git a/packages/site/source.config.ts b/packages/site/source.config.ts index 99fd4b0..410ade7 100644 --- a/packages/site/source.config.ts +++ b/packages/site/source.config.ts @@ -18,10 +18,19 @@ function resolveContentDir(dir: string) { const docsDir = resolveContentDir('content/docs'); -export const { docs, meta } = defineDocs({ - dir: docsDir, +// Define multiple roots for the documentation +export const core = defineDocs({ + dir: path.join(docsDir, 'core'), }); +export const platform = defineDocs({ + dir: path.join(docsDir, 'platform'), +}); + +// Export combined docs for backward compatibility +export const docs = core.docs; +export const meta = core.meta; + export default defineConfig({ mdxOptions: { rehypeCodeOptions: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dbc862..8189c8a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,6 +102,9 @@ importers: fumadocs-ui: specifier: ^16.4.7 version: 16.4.7(@types/react@19.2.8)(fumadocs-core@16.4.7(@types/react@19.2.8)(lucide-react@0.562.0(react@19.2.3))(next@16.1.2(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)(zod@4.3.5))(next@16.1.2(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)(tailwindcss@4.1.18) + lucide-react: + specifier: ^0.562.0 + version: 0.562.0(react@19.2.3) next: specifier: ^16.1.2 version: 16.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)