Docs

// Pure content page - no React interactivity (TOC/copy/search are the layout enhancer + // the Nira island), so ship zero framework JS and avoid hydrating the inline-script DOM. export const hydrate = false

Content & MDX

Nifra ships typed content collections and MDX - the backbone of a docs site, blog, or changelog, without hand-rolling readdir and a frontmatter parser.

Content collections

defineCollection turns a folder of Markdown into a typed, schema-validated source. The frontmatter is validated against a t schema, so a typo'd or missing field fails the build - not production - and the entries are fully typed into your loaders:

TS
import { defineCollection } from "@nifrajs/content/fs"
import { t } from "@nifrajs/schema"

export const blog = defineCollection({
  dir: "content/blog",
  schema: t.object({ title: t.string(), date: t.string(), draft: t.boolean() }),
})

// in a loader - typed + validated entries (a typo'd field fails the build, not production):
const posts = (await blog.all()).filter((p) => !p.frontmatter.draft)

MDX routes

Add the MDX plugin to your build and any routes/**/*.mdx file becomes a page - Markdown that can import and render components inline, and export const meta, exactly like a .tsx route:

TS
import { mdxBunPlugin } from "@nifrajs/content/mdx"

// build.ts - every routes/**/*.mdx file compiles to a component for your framework
await buildClient({
  routesDir: "./routes",
  clientModule: "@nifrajs/web-react/client",
  plugins: [mdxBunPlugin({ jsxImportSource: "react" })],
})

MDX on all five frameworks

MDX is framework-agnostic in Nifra - same as everything else. Each framework gets a build plugin that compiles .mdx to its component model:

TS
// React / Preact / Vue - one plugin, pick the JSX runtime:
import { mdxBunPlugin } from "@nifrajs/content/mdx"
mdxBunPlugin({ jsxImportSource: "react" }) // or "preact" | "vue"

// Solid - compile-time transform + an intrinsics runtime:
import { solidMdxBunPlugin } from "@nifrajs/web-solid/mdx"
solidMdxBunPlugin("ssr") // "dom" for the client build

// Svelte - through mdsvex (Svelte's own Markdown compiler):
import { svelteMdxBunPlugin } from "@nifrajs/web-svelte/mdx"
svelteMdxBunPlugin("ssr")

React, Preact, and Vue share one plugin (their JSX runtimes differ only by jsxImportSource). Solid needs its compile-time transform, so @nifrajs/web-solid/mdx runs babel-preset-solid over the MDX and maps intrinsic tags through <Dynamic>. Svelte has no JSX, so @nifrajs/web-svelte/mdx routes MDX through mdsvex - Svelte's own Markdown compiler. All five server-render and hydrate.