Capítulo 309 de 456

MDX

Core Idea

@next/mdx transforma arquivos .md/.mdx em páginas/imports, permitindo escrever JSX dentro de markdown (componentes React, exports de metadata) para conteúdo local ou remoto.

Key Concepts

  • pageExtensions: precisa incluir md/mdx em next.config.mjs pra esses arquivos virarem páginas/rotas.
  • mdx-components.tsx: arquivo obrigatório na raiz do projeto (exporta useMDXComponents) pra @next/mdx funcionar com App Router; define componentes globais que sobrescrevem elementos HTML nativos (ex.: h1, img).
  • File-based routing vs import: .mdx dentro de /pages vira rota diretamente, ou pode ser importado como componente (import Welcome from '@/markdown/welcome.mdx') e renderizado dentro de uma page normal.
  • Local override de componentes: <Welcome components={overrideComponents} /> sobrescreve, por instância, os componentes globais definidos em mdx-components.tsx.
  • Frontmatter não suportado nativamente: @next/mdx não tem frontmatter YAML por padrão (usar remark-frontmatter/gray-matter), mas suporta export const metadata = {...} direto no .mdx, acessível ao importar o arquivo.
  • remark/rehype plugins: configuráveis via withMDX({ options: { remarkPlugins, rehypePlugins } }); exige next.config.mjs/.ts (ESM-only).
  • Plugins com Turbopack: precisam ser passados como string (nome do pacote) em vez de função importada, já que JS não pode ser passado pro Rust; plugins com opções não-serializáveis ainda não funcionam no Turbopack.
  • mdxRs (experimental): compilador MDX em Rust, não recomendado pra produção ainda.

Code Examples

import createMDX from '@next/mdx'

const nextConfig = {
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
}

const withMDX = createMDX({})
export default withMDX(nextConfig)
  • O que demonstra: setup mínimo pra habilitar .mdx como página.
export const metadata = {
  author: 'John Doe',
}

# Blog post
import BlogPost, { metadata } from '@/content/blog-post.mdx'
// metadata => { author: 'John Doe' }
  • O que demonstra: export de metadata acessível fora do arquivo MDX, útil pra montar índice de posts.

Anti-patterns

  • Esperar frontmatter YAML funcionar sem plugin: @next/mdx não suporta por padrão, usar export const metadata ou lib como gray-matter.
  • Usar plugin com função/opções complexas no Turbopack: falha porque JS não é serializável pro Rust; passar plugin como string simples.
  • Confiar no mdxRs experimental em produção: ainda não é recomendado.

Key Takeaways

  1. mdx-components.tsx é obrigatório pro @next/mdx funcionar corretamente, especialmente no App Router.
  2. Componentes podem ser sobrescritos em três camadas: global (mdx-components.tsx), local (components prop) e layout compartilhado.
  3. Metadata em MDX é feita via export JS, não frontmatter YAML nativo.
  4. Turbopack exige plugins remark/rehype passados como string com opções serializáveis.

Connects To

  • ch291 CSS: @tailwindcss/typography (prose) combinado com layout compartilhado pra estilizar MDX.