Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Build a Typed MDX Content Pipeline in Next.js with Velite

A practical guide to Velite schemas, generated MDX data, React component rendering, App Router routes, and a bundler-aware Next.js build workflow.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Velite when your Next.js app needs MDX posts as validated, typed content data rather than as route files alone. You define a collection schema, build the content into generated data, and render each compiled MDX body with React and the components it references. This walkthrough uses Velite’s documented configuration-based integration, not its Webpack plugin, because the guide says that plugin does not work correctly with Turbopack.

What Velite does—and when to use it

Velite turns Markdown, MDX, and other files into an app data layer based on a declared schema. Its project documentation describes Zod validation, inferred TypeScript types, multiple output formats, and framework-agnostic use. It is a content build pipeline, not a CMS and not a Next.js router. Velite documentation

As an Amazon Associate I earn from qualifying purchases.

This model is useful when posts need consistent fields—such as titles, dates, slugs, and categories—and the app needs to query them as a collection. If you simply want MDX files imported or mapped directly to routes, Next.js’s native @next/mdx setup may be a better fit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set up a project and content file

The following is a project pattern, not a claim of a tested version combination. The cited documentation does not establish a compatibility matrix; check the current Velite, Next.js, React, and package-manager requirements before installing. From an existing Next.js project, add Velite and its schema package using the package manager you already use:

npm install velite zod

A simple directory layout keeps source content separate from generated output:

content/
  posts/
    first-post.mdx
.velite/

Create content/posts/first-post.mdx with frontmatter and an MDX body:

---
title: "A first post"
slug: "first-post"
description: "A short introduction to the example collection."
---

## A useful heading

This post is compiled as MDX. It can include a React component such as <Callout>Remember to register this component in the renderer.</Callout>.

Define the Velite collection and validation rules

Create velite.config.ts at the project root. Velite’s MDX guide demonstrates a collection pattern such as posts/*.mdx, with fields including title: s.string() and code: s.mdx(). The example below adds a required slug and description so routes and metadata have explicit values.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { defineConfig, s } from 'velite'

export default defineConfig({
  root: 'content',
  output: {
    data: '.velite',
  },
  collections: {
    posts: {
      name: 'Post',
      pattern: 'posts/*.mdx',
      schema: s.object({
        title: s.string(),
        slug: s.slug('posts'),
        description: s.string(),
        content: s.mdx(),
      }),
    },
  },
})

Use the current Velite configuration reference to confirm option names for the installed release; the documentation supports JavaScript and TypeScript configurations and recommends defineConfig for type inference. The important design choice is that required fields are enforced by the schema: an omitted description or title is a content error, not something TypeScript can infer from a missing value.

Validation strictness affects the build outcome. The documented strict setting defaults to false; by default, schema failures produce warnings. With strict: true, a validation failure throws and terminates the process. For a production content pipeline, add the setting at the top level of the config to make invalid entries fail the build:

export default defineConfig({
  strict: true,
  // keep the root, output, and collections settings shown above
})

Treat that as a change to the full config, not a second export. To see the effect, temporarily remove description from the sample frontmatter: with strict validation enabled, the Velite process should stop on the missing required schema field; with the documented default, it warns instead. Exact diagnostic text can vary by release.

Build the collection and inspect its generated data

Run Velite directly once to verify that the content pattern and schema match your files:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npx velite build

The MDX guide says the build produces collection data and compiles each s.mdx() field into a function-body string by default. That string is executable MDX output, not finished HTML and not a rendered React tree. Generated output location and import shape depend on the config and release; use the configured output directory and inspect the generated files rather than assuming a particular filename.

The configuration also enables inferred types, so application code can consume the generated collection with its schema-derived shape. Make sure the generated data exists before importing it in a route, and avoid hand-maintaining a second TypeScript interface that can drift from the schema.

Render MDX with React components

Velite documents evaluating the compiled MDX with the React JSX runtime and providing shared or per-document components. Since the compile step does not bundle your component implementations, names referenced in MDX need to be passed to the renderer.

import * as runtime from 'react/jsx-runtime'
import { posts } from '../.velite'

const mdxComponents = {
  Callout,
  Chart,
  Image,
}

export function PostBody({ code }: { code: string }) {
  const Content = run(code, runtime).default
  return <Content components={mdxComponents} />
}

run above represents the MDX evaluation helper shown in Velite’s renderer documentation; import it from the renderer module specified by the current Velite guide and release. Define or import Callout, Chart, and Image as actual React components in your application. Remove entries you do not use. If a post uses an unregistered component, rendering cannot resolve that name correctly. Do not render untrusted MDX as if the compilation step were a security boundary; establish an authoring and review policy appropriate to your app.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Look up a post from a Next.js App Router route

A dynamic route can resolve the URL slug against the generated collection, then pass the compiled body to the renderer. For example, create app/posts/[slug]/page.tsx:

import { notFound } from 'next/navigation'
import { posts } from '../../../.velite'
import { PostBody } from '@/components/post-body'

export default async function PostPage({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  const post = posts.find((entry) => entry.slug === slug)

  if (!post) notFound()

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.description}</p>
      <PostBody code={post.content} />
    </article>
  )
}

Adjust the relative import and route parameter typing to the Next.js version used by your project; the documentation cited here does not establish a version-specific API contract for this sample. The core flow is stable: find the record by slug, call notFound() when there is no match, and render the record’s compiled MDX field.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Wire Velite into development and production

Velite’s Next.js guide documents several integration styles: start the build from Next.js configuration, use its Webpack plugin, or coordinate Velite and Next.js through package scripts. The plugin is a Webpack integration; the guide warns it does not function correctly when Turbopack is enabled and presents a separate configuration-based start approach for projects adopting Turbopack. This example uses scripts to make build ordering explicit and avoid assuming the Webpack plugin is available.

Add scripts that watch content during development and build content before Next.js creates the production app:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
{
  "scripts": {
    "dev": "velite --watch & next dev",
    "build": "velite build && next build",
    "start": "next start"
  }
}

Velite’s guide documents a watch workflow and a clean content build before the Next.js production build. Shell backgrounding syntax differs across operating systems and shells, so use the exact orchestration approach documented for your environment if the concurrent dev command does not run both processes reliably. The production script’s && ensures Next.js build runs only after Velite exits successfully.

If you choose the documented Webpack plugin instead, follow its dedicated setup and keep the bundler distinction explicit; do not assume it works with Turbopack. The guide also shows a typed-route pattern using Next.js’s experimental typedRoutes feature. Because that feature’s status can change by Next.js release, confirm the current release documentation before enabling it.

Velite or native Next.js MDX?

Next.js’s current App Router MDX guide describes @next/mdx, where MDX can be handled through route files or imports and shared components are configured through mdx-components.tsx. The guide states that this file is required to use @next/mdx with the App Router. Next.js MDX guide

Need Velite Native @next/mdx
Schema-validated, typed content collection Designed to build content into schema-based app data with inferred types. Velite project The cited guide focuses on MDX routes and imports, not a Velite-style content collection schema.
Content model Files are collected as data records, such as a posts/*.mdx collection. MDX files are used through route files or imports.
Component registration Pass the React runtime and map component names referenced by MDX when rendering compiled content. Use the required App Router mdx-components.tsx convention.
Build integration Choose a supported integration for the bundler; the Velite Webpack plugin is not compatible with Turbopack according to its guide. Velite Next.js guide Follow the Next.js MDX configuration for the project’s chosen setup. Next.js MDX guide
Best fit Choose it when editorial records need a declared schema and generated collection data. Choose it when direct MDX routes or imports fit the content and routing model.

Troubleshoot common pipeline failures

  • Velite does not find posts: check that the config root points at the content directory and that the collection pattern matches the file location and extension, such as posts/*.mdx.
  • A post fails schema validation: compare its frontmatter keys and value types with required schema fields. With strict: true, correct the content or schema before expecting the process to complete.
  • A component in MDX is unresolved: register the matching React component name in the map passed to the renderer; compilation does not bundle that implementation.
  • The generated collection import is missing: run Velite first, confirm the configured output path, and check that your import points to the generated data rather than the original MDX source.
  • Next.js starts before content generation finishes: use the documented watch integration for development and ensure production scripts run the content build successfully before next build.
  • The integration breaks under Turbopack: do not use the Velite Webpack plugin in that setup; use the guide’s alternate configuration-based start method or coordinated scripts.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.