Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions apps/framework-docs-v2/.npmrc

This file was deleted.

60 changes: 2 additions & 58 deletions apps/framework-docs-v2/content/templates/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,13 @@ order: 2
category: getting-started
---

import { CTACards, CTACard } from "@/components/mdx";
import { Badge } from "@/components/ui/badge";
import Link from "next/link";
import { TemplatesGridServer } from "@/components/mdx";
import { TemplatesGridServer, CommandSnippet } from "@/components/mdx";

# Templates & Apps

Moose provides two ways to get started: **templates** and **demo apps**. Templates are simple skeleton applications that you can initialize with `moose init`, while demo apps are more advanced examples available on GitHub that showcase real-world use cases and integrations.

**Initialize a template:**
```bash filename="Terminal" copy
moose init PROJECT_NAME TEMPLATE_NAME
```

**List available templates:**
```bash filename="Terminal" copy
moose template list
```

## Popular Apps

<CTACards columns={2}>
<CTACard
title="Nextjs + Express + MCP demo app: Aircraft data"
description="Complete demo application featuring real-time aircraft transponder data with MCP chat integration."
ctaLink="#plane-transponder-demo"
ctaLabel="Details"
secondaryCtaLink="https://github.com/514-labs/planes"
secondaryCtaLabel="Github →"
badge={{ variant: "default", text: "Express APIs + MCP Demo" }}
/>

<CTACard
title="Postgres to ClickHouse CDC with Debezium"
description="Easy-to-run demo of a CDC pipeline using Debezium, PostgreSQL, Redpanda, and ClickHouse."
ctaLink="#postgres-clickhouse-cdc"
ctaLabel="Details"
secondaryCtaLink="https://github.com/514-labs/debezium-cdc"
secondaryCtaLabel="Github →"
badge={{ variant: "default", text: "CDC Demo" }}
/>

<CTACard
title="User-facing analytics reference app (Postgres + Clickhouse + React)"
description="Complete reference architecture showing how to add a dedicated analytics microservice to an existing application."
ctaLink="#foobar-ufa"
ctaLabel="Details"
secondaryCtaLink="https://github.com/514-labs/area-code/tree/main/ufa"
secondaryCtaLabel="Github →"
badge={{ variant: "default", text: "Reference Architecture" }}
/>

<CTACard
title="User-facing analytics reference app (Clickhouse Cloud + React)"
description="Simplified version of the reference architecture using ClickHouse Cloud with React frontend and chat analytics."
ctaLink="#foobar-ufa-lite"
ctaLabel="Details"
secondaryCtaLink="https://github.com/514-labs/area-code/tree/main/ufa-lite"
secondaryCtaLabel="Github →"
badge={{ variant: "default", text: "ClickHouse Cloud demo" }}
/>
</CTACards>
---
<CommandSnippet />

## Browse Apps and Templates

Expand Down
2 changes: 2 additions & 0 deletions apps/framework-docs-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
"@next/mdx": "^16.0.1",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-navigation-menu": "^1.2.13",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.1.7",
Expand Down
12 changes: 9 additions & 3 deletions apps/framework-docs-v2/src/app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ export async function generateStaticParams() {
const slugs = getAllSlugs();

// Generate params for each slug
// Note: templates is excluded from getAllSlugs() as it is now an explicit page
const allParams: { slug: string[] }[] = slugs.map((slug) => ({
slug: slug.split("/"),
}));

// Also add section index routes (moosestack, ai, hosting, templates)
// These map to section/index.mdx files
// Also add section index routes (moosestack, ai, hosting, guides)
// Note: templates is now an explicit page, so it's excluded here
allParams.push(
{ slug: ["moosestack"] },
{ slug: ["ai"] },
{ slug: ["hosting"] },
{ slug: ["templates"] },
{ slug: ["guides"] },
);

return allParams;
Expand Down Expand Up @@ -81,6 +82,11 @@ export default async function DocPage({ params }: PageProps) {

const slug = slugArray.join("/");

// Templates is now an explicit page, so it should not be handled by this catch-all route
if (slug.startsWith("templates/")) {
notFound();
}

let content;
try {
content = await parseMarkdownContent(slug);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { notFound } from "next/navigation";
import type { Metadata } from "next";
import { parseMarkdownContent } from "@/lib/content";
import { TOCNav } from "@/components/navigation/toc-nav";
import { MDXRenderer } from "@/components/mdx-renderer";
import { DocBreadcrumbs } from "@/components/navigation/doc-breadcrumbs";
import { buildDocBreadcrumbs } from "@/lib/breadcrumbs";

export const dynamic = "force-dynamic";

export async function generateMetadata(): Promise<Metadata> {
try {
const content = await parseMarkdownContent(
"guides/strategy/platform-engineering",
);
return {
title:
content.frontMatter.title ?
`${content.frontMatter.title} | MooseStack Documentation`
: "Platform Engineering | MooseStack Documentation",
description:
content.frontMatter.description ||
"Guide to platform engineering strategy with MooseStack",
};
} catch (error) {
return {
title: "Platform Engineering | MooseStack Documentation",
description: "Guide to platform engineering strategy with MooseStack",
};
}
}

export default async function PlatformEngineeringPage() {
let content;
try {
content = await parseMarkdownContent(
"guides/strategy/platform-engineering",
);
} catch (error) {
notFound();
}

const breadcrumbs = buildDocBreadcrumbs(
"guides/strategy/platform-engineering",
typeof content.frontMatter.title === "string" ?
content.frontMatter.title
: undefined,
);

return (
<>
<div className="flex w-full flex-col gap-6 pt-4">
<DocBreadcrumbs items={breadcrumbs} />
<article className="prose prose-slate dark:prose-invert max-w-none w-full min-w-0">
{content.isMDX ?
<MDXRenderer source={content.content} />
: <div dangerouslySetInnerHTML={{ __html: content.content }} />}
</article>
</div>
<TOCNav
headings={content.headings}
helpfulLinks={content.frontMatter.helpfulLinks}
/>
</>
);
}
31 changes: 31 additions & 0 deletions apps/framework-docs-v2/src/app/templates/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ReactNode } from "react";
import { Suspense } from "react";
import { TemplatesSideNav } from "./templates-side-nav";
import { AnalyticsProvider } from "@/components/analytics-provider";
import { SidebarInset } from "@/components/ui/sidebar";

interface TemplatesLayoutProps {
children: ReactNode;
}

export default async function TemplatesLayout({
children,
}: TemplatesLayoutProps) {
return (
<AnalyticsProvider>
<div className="flex flex-1">
<Suspense fallback={<div className="w-64" />}>
<TemplatesSideNav />
</Suspense>
<SidebarInset>
<div className="container flex-1 pt-6 pb-12 lg:pt-8">
{/* Reserve space for the right TOC on xl+ screens */}
<main className="relative flex flex-col gap-10 xl:grid xl:grid-cols-[minmax(0,1fr)_240px] xl:gap-12">
{children}
</main>
</div>
</SidebarInset>
</div>
</AnalyticsProvider>
);
}
62 changes: 62 additions & 0 deletions apps/framework-docs-v2/src/app/templates/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { notFound } from "next/navigation";
import type { Metadata } from "next";
import { parseMarkdownContent } from "@/lib/content";
import { TOCNav } from "@/components/navigation/toc-nav";
import { MDXRenderer } from "@/components/mdx-renderer";
import { DocBreadcrumbs } from "@/components/navigation/doc-breadcrumbs";
import { buildDocBreadcrumbs } from "@/lib/breadcrumbs";

export const dynamic = "force-dynamic";

export async function generateMetadata(): Promise<Metadata> {
try {
const content = await parseMarkdownContent("templates/index");
return {
title:
content.frontMatter.title ?
`${content.frontMatter.title} | MooseStack Documentation`
: "Templates & Apps | MooseStack Documentation",
description:
content.frontMatter.description ||
"Browse templates and demo apps for MooseStack",
};
} catch (error) {
return {
title: "Templates & Apps | MooseStack Documentation",
description: "Browse templates and demo apps for MooseStack",
};
}
}

export default async function TemplatesPage() {
let content;
try {
content = await parseMarkdownContent("templates/index");
} catch (error) {
notFound();
}

const breadcrumbs = buildDocBreadcrumbs(
"templates/index",
typeof content.frontMatter.title === "string" ?
content.frontMatter.title
: undefined,
);

return (
<>
<div className="flex w-full flex-col gap-6 pt-4">
<DocBreadcrumbs items={breadcrumbs} />
<article className="prose prose-slate dark:prose-invert max-w-none w-full min-w-0">
{content.isMDX ?
<MDXRenderer source={content.content} />
: <div dangerouslySetInnerHTML={{ __html: content.content }} />}
</article>
</div>
<TOCNav
headings={content.headings}
helpfulLinks={content.frontMatter.helpfulLinks}
/>
</>
);
}
Loading
Loading