Leadtype
Build

Use the source primitive

createDocsSource() is the framework-neutral way to render leadtype-authored MDX in your own docs app. This page shows the wiring on top of the most common hosts. Fumadocs has its own first-party adapter — see leadtype/fumadocs.

TL;DR

The primitive itself is identical across frameworks:

lib/source.ts

Wire createMdxSourcePlugins() into your bundler's remark stack, then call source.loadPage(slug) from your framework's page renderer. The "Wire into your framework" section below has minimal setups for each host.

Install

Plus an MDX integration for your bundler (@next/mdx, @astrojs/mdx, @mdx-js/rollup, etc.).

Wire into your framework

createMdxSourcePlugins() expands <include> partials and resolves <ExtractedTypeTable> at build time, while leaving every custom tag (<Callout>, <Tabs>, <Steps>, …) as JSX for your runtime components. Set typeTableBasePath to the source root that contains referenced TypeScript files; use path.resolve(process.cwd(), "docs") only when those files intentionally live under your docs folder.

Next App Router

The leadtype/next adapter wraps the common Next wiring so the page, route handler, and search hook each become a one-line export. Use it as the recommended path; fall back to calling createDocsSource() directly only when you need behavior the adapter doesn't expose.

next.config.mjs
app/docs/[[...slug]]/page.tsx

Add a sibling route.ts to serve raw markdown and content negotiation:

app/docs/[[...slug]]/route.ts

Pair with useLeadtypeSearch from leadtype/next/client when building a search input — see the search recipe.

TanStack Start

vite.config.ts
src/routes/docs/$.tsx

Generate docs-pages.json at build time by calling createDocsSource().listPages() from a build script and writing each page's slug, urlPath, and globKey (path relative to the catch-all route, POSIX separators).

Use createLoadPageData from leadtype/tanstack-start when you want adapter helpers for TanStack Router route params and page data. TanStack AI answer streaming lives separately under leadtype/search/tanstack.

Nuxt

nuxt.config.ts

Use createLoadPageData and the Nitro route handlers from leadtype/nuxt for page data, generated markdown, and Agent Readability artifacts. For search, use leadtype/search/vue with the generated JSON files.

Astro Content Collections

astro.config.mjs

Use Astro's native content collection schema for typed frontmatter. Call source.loadPage() from leadtype only when you need programmatic include resolution, search, or navigation. See Astro's content collections docs for the routing pattern.

SvelteKit + mdsvex

svelte.config.js

Use createLoadPageData, createEntries, and createDocsServerHandler from leadtype/sveltekit for page data, prerender entries, and markdown or JSON artifact responses. For search, use leadtype/search/svelte with the generated JSON files.

TanStack Start, Nuxt, Astro, and SvelteKit expose adapter helpers for native route data and handler shapes. The open follow-up work is to keep expanding those helpers without adding rendered UI components.

Implement the tag components

Import prop types from leadtype/mdx and implement against your framework:

lib/mdx-components.tsx

The full tag inventory and intersection patterns for React, Vue, Svelte, Solid, and Astro live in leadtype/mdx.

Build the sidebar from navigation

components/sidebar.tsx

Each page carries a toc field (DocsTableOfContentsItem[]) you can render as an "On this page" rail.

Match heading slugs

source.loadPage().toc uses slugifyDocsHeading to derive anchor IDs. Your rendered heading components need matching id attributes:

Wire Heading2 (and h3, etc.) into your mdxComponents map. Authors can still pin an explicit id on a heading.

Build a search index

app/api/search/route.ts

For provider-specific search (Vercel AI, TanStack, Cloudflare), feed the bundle into a leadtype/search/* adapter — see Add search.

Troubleshooting

  • <include> tags survive into the rendered output. You forgot to add createMdxSourcePlugins() to your MDX compiler's remark plugin list.
  • <ExtractedTypeTable> renders unresolved. The source preset converts these to <TypeTable> only when extractTypeFromFile succeeds. Make sure typescript is installed in the docs app and typeTableBasePath resolves to the project that contains the type.
  • TOC links don't scroll. Rendered heading IDs don't match. Wire slugifyDocsHeading into your heading components.
  • Sidebar order doesn't match llms.txt. Your app and the CLI are loading different docs.config.ts files. Centralize the config and import it in both.

Reference