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.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteSet 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:
#1 Best Overall
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.
Recommended Free Tools
Rank #2
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.
Rank #3
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.
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.
Rank #4
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.
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.
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:
{
"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
Quick Recap
| 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.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →




