Zum Inhalt springen
Kontakt

Sebastian Nawrot
Dorneystr. 45
44149 Dortmund

Webentwicklung & Technik

Modernes Blog-System mit Next.js 14 und MDX

Wie ich ein performantes, SEO-optimiertes Blog-System mit Next.js App Router, MDX und Tailwind CSS aufgebaut habe. Ein technischer Deep-Dive.

Sebastian Nawrot
5 Min. Lesezeit
#Next.js#MDX#React#SEO#Webentwicklung

Als Webentwickler wollte ich schon lange einen eigenen Blog haben - nicht nur um mein technisches Wissen zu teilen, sondern auch um ehrlich über meine Erfahrungen als neurodivergenter Entwickler zu sprechen. Aber ich wollte kein WordPress oder Ghost nutzen. Ich wollte volle Kontrolle, moderne Technologie und maximale Performance.

Die Anforderungen

Bevor ich mit der Entwicklung startete, definierte ich klare Anforderungen:

  • Moderne Tech-Stack: Next.js 14 mit App Router
  • MDX-Support: Markdown mit React-Komponenten
  • SEO-optimiert: Structured Data, Meta-Tags, Sitemaps
  • Performant: Static Site Generation, optimierte Bilder
  • Dark Mode: Natürlich!
  • Kategorien & Tags: Flexible Content-Organisation
  • Syntax Highlighting: Für Code-Beispiele
  • Related Posts: Automatische Empfehlungen

Tech-Stack im Detail

Next.js 14 App Router

Der neue App Router von Next.js ist ein Game-Changer. Statt pages/ nutze ich jetzt app/ mit Server Components als Default:

// app/(marketing)/blog/[slug]/page.jsx
export async function generateStaticParams() {
  const slugs = getAllPostSlugs();
  return slugs.map((slug) => ({ slug }));
}

export default function BlogPostPage({ params }) {
  const post = getPostBySlug(params.slug);
  return <MDXRemote source={post.content} />;
}

Vorteile:

  • Automatisches Code-Splitting
  • Bessere Performance durch Server Components
  • Einfachere Metadaten-Generierung mit generateMetadata()

MDX mit next-mdx-remote

MDX erlaubt mir, React-Komponenten direkt in Markdown zu nutzen. Perfekt für interaktive Blog-Posts!

pnpm add next-mdx-remote gray-matter remark-gfm rehype-highlight

Die Konfiguration ist einfach:

import { MDXRemote } from 'next-mdx-remote/rsc';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';

const mdxOptions = {
  mdxOptions: {
    remarkPlugins: [remarkGfm],
    rehypePlugins: [rehypeHighlight],
  },
};

<MDXRemote source={content} options={mdxOptions} />

File-Based Content Management

Alle Blog-Posts liegen als .mdx-Dateien in content/blog/:

content/blog/
├── nextjs-blog-mit-mdx.mdx
├── adhs-und-coding.mdx
└── hochsensibel-als-developer.mdx

Jeder Post hat Frontmatter-Metadaten:

---
title: "Mein Titel"
description: "Eine kurze Beschreibung"
date: "2024-12-14"
category: "Webentwicklung & Technik"
tags: ["Next.js", "React"]
published: true
---

Mit gray-matter parse ich das Frontmatter:

import matter from 'gray-matter';
import fs from 'fs';

export function getPostBySlug(slug) {
  const fileContents = fs.readFileSync(`content/blog/${slug}.mdx`, 'utf8');
  const { data, content } = matter(fileContents);

  return {
    slug,
    content,
    frontmatter: data
  };
}

SEO-Optimierung

Structured Data

Jeder Blog-Post hat Schema.org BlogPosting Markup:

const structuredData = {
  '@context': 'https://schema.org',
  '@type': 'BlogPosting',
  headline: frontmatter.title,
  description: frontmatter.description,
  datePublished: frontmatter.date,
  author: {
    '@type': 'Person',
    name: frontmatter.author,
  },
};

Dynamische Metadaten

Mit generateMetadata() im App Router:

export async function generateMetadata({ params }) {
  const post = getPostBySlug(params.slug);

  return {
    title: `${post.frontmatter.title} | Blog`,
    description: post.frontmatter.description,
    openGraph: {
      title: post.frontmatter.title,
      description: post.frontmatter.description,
      type: 'article',
      publishedTime: post.frontmatter.date,
    },
  };
}

Performance-Features

Static Site Generation

Alle Blog-Posts werden zur Build-Time generiert:

export async function generateStaticParams() {
  const slugs = getAllPostSlugs();
  return slugs.map((slug) => ({ slug }));
}

Ergebnis: Instant Page Loads mit 0ms Server Response Time!

Code-Splitting

Jede Route wird automatisch gesplittet. Der Blog-Code wird nur geladen, wenn du /blog besuchst.

Optimierte Bilder

Mit Next.js <Image> Component (später implementiert):

import Image from 'next/image';

<Image
  src={frontmatter.image}
  alt={frontmatter.title}
  width={1200}
  height={630}
  priority={featured}
/>

Ich habe einen simplen Score-basierten Algorithmus:

export function getRelatedPosts(slug, limit = 3) {
  const currentPost = getPostBySlug(slug);
  let relatedPosts = getAllPosts().filter(post => post.slug !== slug);

  relatedPosts = relatedPosts.map(post => {
    let score = 0;

    // Gleiche Kategorie = +10 Punkte
    if (post.frontmatter.category === currentPost.frontmatter.category) {
      score += 10;
    }

    // Gemeinsame Tags = +5 Punkte pro Tag
    const sharedTags = post.frontmatter.tags.filter(tag =>
      currentPost.frontmatter.tags.includes(tag)
    );
    score += sharedTags.length * 5;

    return { ...post, score };
  });

  return relatedPosts
    .sort((a, b) => b.score - a.score)
    .slice(0, limit);
}

Was ich gelernt habe

1. App Router > Pages Router

Der neue App Router macht so vieles einfacher:

  • Layouts sind endlich vernünftig
  • Server Components als Default = Performance-Boost
  • Metadata-Handling ist cleaner

2. MDX ist perfekt für Blogs

Die Kombination aus Markdown-Einfachheit und React-Power ist genial:

  • Schreiben ist schnell (Markdown)
  • Interaktivität wo nötig (React-Komponenten)
  • Type-Safety mit TypeScript möglich

3. File-Based CMS reicht oft

Ich brauche kein Headless CMS für meinen Blog:

  • Git als Version Control
  • VS Code als Editor
  • Kein Backend nötig
  • Volle Kontrolle

Nächste Schritte

Das Blog-System ist jetzt live, aber ich plane noch:

  1. Newsletter-Integration (Mailchimp oder ConvertKit)
  2. Kommentare (Giscus mit GitHub Discussions)
  3. View Counter (Edge Function + KV Store)
  4. RSS Feed (automatisch generiert)
  5. Search (Algolia oder Fuse.js)

Fazit

Ein modernes Blog mit Next.js und MDX aufzubauen war einfacher als gedacht. Die Developer Experience ist fantastisch, die Performance ist top, und ich habe volle Kontrolle über meine Inhalte.

Wenn du auch überlegst, einen technischen Blog zu starten: Tu es! Nicht nur für andere, sondern auch für dich selbst. Ich habe beim Schreiben dieses Posts mehr gelernt als beim reinen Coden.


Du möchtest auch so ein Blog-System? Ich entwickle moderne, performante Websites mit Next.js, React und Tailwind CSS. Lass uns sprechen!

Möchtest du auch so einen Blog?

Ich entwickle moderne, SEO-optimierte Websites und Blogs mit Next.js, React und Tailwind CSS.