O Next-MDX fornece um conjunto de funções auxiliares para buscar e renderizar arquivos MDX locais. Ele lida com dados relacionais , suporta componentes personalizados , TypeScript Ready e é muito rápido .
O Next-MDX é ótimo para a construção de páginas movidas a MDX, blogs multi-usuários, páginas de categoria.

https://next-mdx-example.vercel.app
Saiba como o Next-MDX funciona analisando exemplos.
next-mdx.json para ver a configuração de amostra.pages/[[...slug]].tsx para ver como os arquivos MDX são buscados e renderizados.types/index.d.ts para TypeScript. Clique para expandir exemplos.
{
"post" : {
"contentPath" : " content/posts " ,
"basePath" : " /blog " ,
"sortBy" : " date " ,
"sortOrder" : " desc "
},
} import { useHydrate } from "next-mdx/client"
import { getMdxNode , getMdxPaths } from "next-mdx/server"
export default function PostPage ( { post } ) {
const content = useHydrate ( post )
return (
< article >
< h1 variant = "heading.title" > { post . frontMatter . title } </ h1 >
{ post . frontMatter . excerpt ? (
< p variant = "text.lead" mt = "4" >
{ post . frontMatter . excerpt }
</ p >
) : null }
< hr />
{ content }
</ article >
)
}
export async function getStaticPaths ( ) {
return {
paths : await getMdxPaths ( "post" ) ,
fallback : false ,
}
}
export async function getStaticProps ( context ) {
const post = await getMdxNode ( "post" , context )
if ( ! post ) {
return {
notFound : true ,
}
}
return {
props : {
post ,
} ,
}
}
npm i --save next-mdx
Crie um arquivo next-mdx.json na raiz do seu projeto com o seguinte:
{
"post" : {
"contentPath" : " content/posts " ,
"basePath" : " /blog " ,
"sortBy" : " date " ,
"sortOrder" : " desc "
},
"category" : {
"contentPath" : " content/categories "
}
}post , category e author são IDs exclusivos usados como referências para seus tipos de MDX.contentPath (requerido) é onde seus arquivos MDX estão localizados.basePath (opcional) é o caminho usado para gerar URLs.sortBy (opcional, padrões para title ) é o nome do campo FrontMatter usado para classificar.sortOrder (opcional, padrões para asc ) é a ordem de classificação. next-mdx expõe 6 funções principais ajudantes:
getMdxPaths(sourceName: string)getNode(sourceName, context)getAllNodes(sourceName)getMdxNode(sourceName, context, params)getAllMdxNodes(sourceName, params)useHydrate(node, params) getMdxPaths(sourceName: string) retorna uma matriz de parâmetros de caminho que pode ser passada diretamente para paths in getStaticPaths`.
sourceName é o ID exclusivo definido em next-mdx.json // pages/blog/[...slug].js
import { getMdxPaths } from "next-mdx/server"
export async function getStaticPaths ( ) {
return {
paths : await getMdxPaths ( "post" ) ,
fallback : false ,
}
} getNode(sourceName, context) retorna um MDXNode com dados de FrontMatter e Relacional, mas sem dados MDX. Isso é muito rápido e armazenado em cache.
Use isso em vez de getMdxNode se você não estiver renderizando o conteúdo MDX em uma página.
sourceName é o ID exclusivo definido em next-mdx.jsoncontext é o contexto passado para getStaticProps ou a Slug como uma string. // pages/blog/[...slug].js
import { getNode } from "next-mdx/server"
export async function getStaticProps ( context ) {
const post = await getNode ( "post" , context )
if ( ! post ) {
return {
notFound : true ,
}
}
return {
props : {
post ,
} ,
}
} getAllNodes(sourceName) Retorna todo o MdxNode do tipo/fonte fornecido com dados de FrontMatter e Relacional, mas sem dados MDX. Isso também é muito rápido e armazenado em cache.
sourceName é o ID exclusivo definido em next-mdx.json import { getAllNodes } from "next-mdx/server"
export async function getStaticProps ( ) {
return {
props : {
posts : await getAllNodes ( "post" ) ,
} ,
}
} getMdxNode(sourceName, context, params) retorna um MDXNode .
sourceName é o ID exclusivo definido em next-mdx.jsoncontext é o contexto passado para getStaticProps ou a Slug como uma string.params : {
components ?: MdxRemote . Components
scope ?: Record < string , unknown >
provider ?: MdxRemote . Provider
mdxOptions ?: {
remarkPlugins ?: Pluggable [ ]
rehypePlugins ?: Pluggable [ ]
hastPlugins ?: Pluggable [ ]
compilers ?: Compiler [ ]
filepath ?: string
}
} // pages/blog/[...slug].js
import { getMdxNode } from "next-mdx/server"
export async function getStaticProps ( context ) {
const post = await getMdxNode ( "post" , context )
if ( ! post ) {
return {
notFound : true ,
}
}
return {
props : {
post ,
} ,
}
} getAllMdxNodes(sourceName, params) retorna todo o MdxNode do tipo/fonte fornecido.
sourceName é o ID exclusivo definido em next-mdx.jsonparams : {
components ?: { name : React . Component } ,
scope ?: { } ,
provider ?: { component : React . Component , props : Record < string , unknown > } ,
mdxOptions : {
remarkPlugins : [ ] ,
rehypePlugins : [ ] ,
hastPlugins : [ ] ,
compilers : [ ] ,
}
} import { getAllMdxNodes } from "next-mdx/server"
export async function getStaticProps ( ) {
const posts = await getAllMdxNodes ( "post" )
return {
props : {
posts : posts . filter ( ( post ) => post . frontMatter . featured ) ,
} ,
}
} useHydrate(node, params) é usado no lado do cliente para hidratar conteúdo estático.
node é o objeto MdxNodeparams : {
components ?: { name : React . Component } ,
provider ?: { component : React . Component , props : Record < string , unknown > }
} import { useHydrate } from "next-mdx/client"
export default function PostPage ( { post } ) {
const content = useHydrate ( post )
return (
< div >
< h1 > { post . frontMatter . title } </ h1 >
{ content }
</ div >
)
} Use getAllNodes quando precisar de nós sem o conteúdo MDX. É apoiado por um cache e é muito rápido. Isso é útil quando você precisa de uma lista de nós (exemplo de postagem) e não está usando o conteúdo MDX.
Para usar componentes dentro dos arquivos MDX, você precisa passar os componentes para getMdxNode/getAllMdxNodes e useHydrate .
import { getMdxNode } from "next-mdx/server"
import { useHydrate } from "next-mdx/client"
export function Alert ( { text } ) {
return < p > { text } </ p >
}
export default function PostPage ( { post } ) {
const content = useHydrate ( post , {
components : {
Alert ,
} ,
} )
return (
< div >
< h1 > { post . frontMatter . title } </ h1 >
{ content }
</ div >
)
}
export async function getStaticProps ( context ) {
const post = await getMdxNode ( "post" , context , {
components : {
Alert ,
} ,
} )
return {
props : {
post ,
} ,
}
} As opções MDX podem ser passadas como params para getMdxNode(sourceName, context, params) e getAllMdxNodes(sourceName, params) onde params assumem a forma de:
export interface MdxParams {
components ?: MdxRemote . Components
scope ?: Record < string , unknown >
provider ?: MdxRemote . Provider
mdxOptions ?: {
remarkPlugins ?: Pluggable [ ]
rehypePlugins ?: Pluggable [ ]
hastPlugins ?: Pluggable [ ]
compilers ?: Compiler [ ]
filepath ?: string
}
} Ao recuperar nós com getMdxNode ou getAllMdxNodes , next-mdx inferirá automaticamente dados relacionais das teclas FrontMatter.
next-mdx.jsonDados os seguintes arquivos MDX.
.
└── content
├── categories
│ └── category-a.mdx
│ └── category-b.mdx
└── posts:
└── example-post.mdx
No example-post você pode fazer referência a categorias relacionadas usando o seguinte:
---
title : Example Post
category :
- category-a
---Você pode acessar as categorias da seguinte forma:
const post = getMdxNode ( "post" , context )
// post.relationships.category Defina seus tipos de nós da seguinte maneira:
interface Post extends MdxNode < FrontMatterFields > { } import { MdxNode } from "next-mdx/server"
interface Category
extends MdxNode < {
name : string
} > { }
interface Post
extends MdxNode < {
title : string
excerpt ?: string
category ?: string [ ]
} > {
relationships ?: {
category : Category [ ]
}
} Você pode usar Post como tipo de retorno para getNode , getAllNodes , getMdxNode e getAllMdxNode :
const post = await getMdxNode < Post > ( "post" , context )
const posts = await getAllNodes < Post > ( "post" ) Licenciado sob a licença do MIT.