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.
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:
| Function | Job |
|---|---|
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:
imgrenders throughnext/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.xmlroutesitemap.tsrobots.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:
Every new post should link to at least one hub and one related article. For example:
- A Meta ads article links to Scrapers and Best Ad Intelligence Tools.
- A social preview article links to Free Tools, Link Preview, and Twitter Link Preview.
- A Chrome extension article links to Projects and Build a Chrome Extension That People Actually Use.
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:
- Start with a surprising stat or project result.
- State the practical problem.
- Add an SEO brief.
- Explain the workflow.
- Include a comparison table.
- Link to related tools or projects.
- 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.