Back to Blog
Next.jsMDXSEO

How to Turn an MDX Blog Into a Product SEO Engine

A breakdown of the current portfolio blog system: MDX files, frontmatter, reading time, static routes, metadata, JSON-LD, RSS, sitemap, and internal linking.

Anas Nadeem
5 min read

Ten new MDX files can become ten indexable product-led pages without touching a CMS, database, or admin panel. That is the biggest advantage of a repo-based content engine: writing and shipping use the same workflow.

This post breaks down the current portfolio blog architecture and how to use it as a lightweight SEO engine for products, tools, and scrapers.

SEO Brief

Primary key phrase: MDX blog SEO

Secondary key phrases: Next.js MDX blog, portfolio blog SEO, gray-matter frontmatter, MDX SEO, static blog Next.js

Internal links to use: Add a Blog to Your Next.js Site in 30 Minutes with MDX, Blog, Projects, Free Tools

Authority links to include: Next.js metadata docs, next-mdx-remote, gray-matter, Schema.org BlogPosting

Visual suggestions: create an architecture diagram from content/blog/*.mdx to getAllPosts() to /blog and /blog/[slug]; add a metadata checklist graphic; add an internal link map between tools, scrapers, projects, and posts.

Buyer Intent Snapshot

Best-fit readers: founders, developers, indie hackers, technical marketers, and agencies building content around products.

Commercial intent: medium. The reader may be building their own system, but the post also demonstrates product SEO execution and engineering capability.

Conversion path: show the implementation, then link to product hubs so the content engine drives users toward tools and scrapers.

The Content Structure

Every blog post lives in content/blog as an .mdx file.

The frontmatter shape is consistent:

---
title: "Post Title"
excerpt: "Short summary for listing pages."
coverImage: ""
coverImageAlt: ""
author: "Anas Nadeem"
categories: ["Next.js", "MDX", "SEO"]
publishedAt: "2026-06-08"
metaTitle: "SEO Title"
metaDescription: "SEO description."
---

This gives the blog loader everything it needs for listing pages, metadata, RSS, and structured data.

The Blog Loader

The blog utility reads files from disk, parses frontmatter with gray-matter, and calculates reading time.

The key functions are:

FunctionJob
getAllSlugs()Finds all .mdx files
getAllPosts()Returns metadata sorted by date
getRecentPosts()Powers homepage recent writing
getPostBySlug()Loads a single article
getPostCount()Feeds homepage stats

That small API is enough for the whole blog surface.

Static Routes

The post page uses generateStaticParams() so each MDX file becomes a route under /blog/[slug].

This matters for performance and SEO:

  • Pages can be statically generated.
  • Routes are known at build time.
  • Missing slugs return notFound().
  • The URL structure stays clean.

For a personal portfolio, this is the right amount of complexity. A CMS would add more moving parts than the site needs.

Metadata and Social Sharing

Each post generates:

  • Page title
  • Meta description
  • Open Graph article data
  • Twitter card data
  • Canonical URL

This is where frontmatter pays off. The writer controls the search snippet and social preview without editing React code.

The current setup also supports cover images when available. If coverImage is empty, the post still renders cleanly without broken image UI.

MDX Components

The renderer customizes a few base elements:

  • img renders through next/image
  • External links open safely
  • Blockquotes get consistent styling
  • Tables are wrapped for horizontal scrolling
  • Table cells use readable dark-mode styles

This gives authors useful formatting without requiring imports in every post.

RSS, Sitemap and JSON-LD

A content engine becomes more useful when it connects to search and feed readers.

The current project includes:

  • /feed.xml route
  • sitemap.ts
  • robots.ts
  • Blog JSON-LD component
  • Canonical URLs

These pieces make the blog easier for crawlers and readers to understand.

Internal Linking Strategy

The site has four strong content hubs:

  1. Projects
  2. Scrapers
  3. Free Tools
  4. Blog

Every new post should link to at least one hub and one related article. For example:

That is how a portfolio becomes a content graph instead of a pile of posts.

The Practical Writing Template

For this site, a strong post template is:

  1. Start with a surprising stat or project result.
  2. State the practical problem.
  3. Add an SEO brief.
  4. Explain the workflow.
  5. Include a comparison table.
  6. Link to related tools or projects.
  7. End with a concrete next action.

This matches the existing tone: practical, direct, and based on shipped work.

Why MDX Fits This Portfolio

The portfolio has 19 projects, 7 Apify scrapers, 5 free tools, and a growing set of technical posts. MDX is enough because the content is written by a developer, versioned in Git, and published with the app.

The important lesson is not "everyone should avoid a CMS." The lesson is: use the simplest content system that matches how you actually write.

For this site, that is MDX in the repo.

The marketing lesson is simple: a blog is not just a place to publish thoughts. It is a routing layer between search intent and the product that solves the problem.