Next.js’s official MDX integration lets you import .mdx as components and export metadata alongside content. I used @next/mdx with the App Router and kept indexing simple by importing metadata directly from each MDX file. No extra build steps, no content database, and the sitemap pulls dates straight from the MDX front‑matter.Next.js’s official MDX integration lets you import .mdx as components and export metadata alongside content. I used @next/mdx with the App Router and kept indexing simple by importing metadata directly from each MDX file. No extra build steps, no content database, and the sitemap pulls dates straight from the MDX front‑matter.

How I Built a Simple MDX Blog in Next.js and why I chose native mdx over Contentlayer

There are many ways to host blogs with Next.js but I needed something fast & simple: plain MDX files, first‑party support, and zero extra content pipelines. No Contentlayer (which is unmaintained). No next-mdx-remote. No heavy weighted CMS systems.

\

TL;DR

  • Next.js’s official MDX integration lets you import .mdx as components and export metadata alongside content.
  • See doc here: https://nextjs.org/docs/pages/guides/mdx
  • I used @next/mdx with the App Router and kept indexing simple by importing metadata directly from each MDX file.
  • No extra build steps, no content database, and the sitemap pulls dates straight from the MDX front‑matter.

\

Why MDX + App Router?

  • Content is code: The App Router treats a folder as a route and page.mdx as a component. You get layouts, streaming, and RSC benefits for free.

  • First‑party MDX: The official plugin is maintained with Next.js and plays nicely with routing, metadata, and bundling.

  • Lower cognitive load: For a small product site, I don’t want a content compiler, watcher, or a GraphQL layer. A few MDX files and some imports are enough.

    \

    The Core Setup

  1. Add the official MDX plugin and let Next treat MD/MDX as pages.

next.config.js

import createMDX from '@next/mdx';  const withMDX = createMDX({   // Add remark/rehype plugins if/when needed   options: {     remarkPlugins: [],     rehypePlugins: [],   }, });  /** @type {import('next').NextConfig} */ const nextConfig = {   ...   pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'], };  export default withMDX(nextConfig); 

\

  1. Optionally customize how MDX renders components (I kept it minimal for now):

mdx-components.tsx

import type { MDXComponents } from 'mdx/types';  export function useMDXComponents(components: MDXComponents = {}): MDXComponents {   return {     ...components,   }; } 

\

  1. Type the metadata you export from MDX so TS understands it when imported elsewhere.

src/types/mdx.d.ts

declare module '*.mdx' {   import type { ComponentType } from 'react';   const MDXComponent: ComponentType<any>;   export default MDXComponent;   export const metadata: {     title?: string;     description?: string;     date?: string;     author?: string;     tags?: string[];   }; } 

\

  1. Create a post as a route. In the App Router, a folder is your slug and page.mdx is the page.

src/app/blog/how-to-export-ig-followers-tutorial/page.mdx

export const metadata = {   title: 'How to Export Instagram Followers (CSV, Excel, JSON)',   description: 'Step-by-step guide…',   date: '2025-08-28', };  import Image from 'next/image'; 

\

  1. Build a simple index page by importing metadata straight from MDX modules.

src/app/blog/page.tsx

import Link from 'next/link'; import { metadata as igExport } from './how-to-export-ig-followers-tutorial/page.mdx';  const posts = [   {     slug: 'how-to-export-ig-followers-tutorial',     title: igExport?.title ?? 'How to Export Instagram Followers',     description: igExport?.description,     date: igExport?.date,   }, ];  export default function BlogIndexPage() {   // Render cards linking to /blog/[slug] } 

\

  1. Keep your sitemap honest by importing the same metadata for lastModified.

src/app/sitemap.ts

import type { MetadataRoute } from 'next'; import { metadata as igExportPost } from './blog/how-to-export-ig-followers-tutorial/page.mdx'; import { getURL } from '@/utils/get-url';  export default function sitemap(): MetadataRoute.Sitemap {   return [     // …other routes     {       url: getURL('blog/how-to-export-ig-followers-tutorial'),       lastModified: igExportPost?.date ? new Date(igExportPost.date) : new Date(),       changeFrequency: 'weekly',       priority: 0.7,     },   ]; } 

\

The Aha Moments (and a few gotchas)

  • MDX as modules: You can import both the rendered component and named exports (metadata) from any .mdx file. That made the blog index and sitemap trivial.
  • Keep it typed: The *.mdx module declaration means TS won’t complain when you do import { metadata } from 'some-post/page.mdx'.
  • Less is more: I didn’t reach for Contentlayer because I don’t need filesystem crawling or transformations. With a handful of posts, a tiny array is fine.

\

Contentlayer vs. Native MDX

What Contentlayer gives you:

  • Schemas and types: Define required fields and get generated TypeScript. Build fails if a post is missing a title or date.
  • Content graph: Read files from a content/ directory, compute slugs/paths, and query everything in one place.
  • Computed fields: Derive readingTime, slug, canonical URLs, etc., at build time.
  • Good for docs sites: Multiple document types (Guides, API refs, Changelogs) with strict structure.

Native MDX strengths (why I chose it here):

  • Zero ceremony: No schema layer, no background watcher — just .mdx files and imports.
  • Co‑location: The post lives at app/blog/[slug]/page.mdx, same place users will visit.
  • Good enough typing: A tiny *.mdx module declaration plus optional Zod to validate metadata if you want stricter checks.

\

Market Opportunity
RWAX Logo
RWAX Price(APP)
$0.0002123
$0.0002123$0.0002123
-7.53%
USD
RWAX (APP) Live Price Chart
Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact service@support.mexc.com for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

The Channel Factories We’ve Been Waiting For

The Channel Factories We’ve Been Waiting For

The post The Channel Factories We’ve Been Waiting For appeared on BitcoinEthereumNews.com. Visions of future technology are often prescient about the broad strokes while flubbing the details. The tablets in “2001: A Space Odyssey” do indeed look like iPads, but you never see the astronauts paying for subscriptions or wasting hours on Candy Crush.  Channel factories are one vision that arose early in the history of the Lightning Network to address some challenges that Lightning has faced from the beginning. Despite having grown to become Bitcoin’s most successful layer-2 scaling solution, with instant and low-fee payments, Lightning’s scale is limited by its reliance on payment channels. Although Lightning shifts most transactions off-chain, each payment channel still requires an on-chain transaction to open and (usually) another to close. As adoption grows, pressure on the blockchain grows with it. The need for a more scalable approach to managing channels is clear. Channel factories were supposed to meet this need, but where are they? In 2025, subnetworks are emerging that revive the impetus of channel factories with some new details that vastly increase their potential. They are natively interoperable with Lightning and achieve greater scale by allowing a group of participants to open a shared multisig UTXO and create multiple bilateral channels, which reduces the number of on-chain transactions and improves capital efficiency. Achieving greater scale by reducing complexity, Ark and Spark perform the same function as traditional channel factories with new designs and additional capabilities based on shared UTXOs.  Channel Factories 101 Channel factories have been around since the inception of Lightning. A factory is a multiparty contract where multiple users (not just two, as in a Dryja-Poon channel) cooperatively lock funds in a single multisig UTXO. They can open, close and update channels off-chain without updating the blockchain for each operation. Only when participants leave or the factory dissolves is an on-chain transaction…
Share
BitcoinEthereumNews2025/09/18 00:09
‘KPop Demon Hunters’ Gets ‘Golden’ Ticket With 2 Nominations

‘KPop Demon Hunters’ Gets ‘Golden’ Ticket With 2 Nominations

The post ‘KPop Demon Hunters’ Gets ‘Golden’ Ticket With 2 Nominations appeared on BitcoinEthereumNews.com. Mira (voice of May Hong), Rumi (Arden Cho) and Zoey (
Share
BitcoinEthereumNews2026/01/22 23:28
Tron Founder Justin Sun Invests $8M in River’s Stablecoin Abstraction Technology

Tron Founder Justin Sun Invests $8M in River’s Stablecoin Abstraction Technology

Justin Sun commits $8 million to River for stablecoin abstraction deployment across Tron ecosystem, including SUN pools and JustLend integration, as RIVER token
Share
Coinstats2026/01/22 22:59