Von WordPress zu Next.js migrieren: Der komplette Leitfaden für einen erfolgreichen Wechsel
Die Migration von WordPress zu Next.js mag zunächst wie eine gewaltige Aufgabe erscheinen, doch mit der richtigen Strategie und Planung wird der Wechsel zu einer lohnenden Investition. Dieser Leitfaden führt Sie durch jeden Schritt des Migrationsprozesses und zeigt Ihnen, wie Sie häufige Fallstricke vermeiden.
Warum von WordPress zu Next.js wechseln?
Bevor wir in die technischen Details eintauchen, hier die wichtigsten Gründe für eine Migration:
- Performance-Vorteile: Next.js bietet bis zu 3x schnellere Ladezeiten durch Server-Side Rendering und Static Site Generation
- Bessere Sicherheit: Keine Plugin-Schwachstellen mehr, reduzierte Angriffsfläche
- Niedrigere Kosten: Wegfall von Premium-Plugins, Hosting-Kosten oft niedriger (z.B. Vercel)
- Skalierbarkeit: Next.js skaliert automatisch mit Ihrem Traffic
- Moderne Entwicklung: TypeScript, React-Komponenten, vollständige Code-Kontrolle
- SEO-Vorteile: Bessere Core Web Vitals führen zu besseren Rankings
Phase 1: Vorbereitung und Analyse (Woche 1-2)
1. Bestandsaufnahme Ihrer WordPress-Website:
- Anzahl der Seiten und Beiträge dokumentieren
- Liste aller verwendeten Plugins erstellen
- Custom Post Types identifizieren
- Medien-Bibliothek analysieren (Anzahl, Größe, Formate)
- SEO-Einstellungen exportieren (Meta-Descriptions, Titles, Alt-Tags)
- URL-Struktur dokumentieren (für 301-Redirects)
2. Technische Anforderungen definieren:
- Welche WordPress-Features werden wirklich benötigt?
- Welche Plugins können durch moderne Alternativen ersetzt werden?
- Welche Custom-Funktionalität muss neu entwickelt werden?
- Hosting-Strategie festlegen (Vercel, Netlify, AWS, etc.)
3. Content-Audit durchführen:
- Veraltete Inhalte identifizieren
- Duplicate Content finden und konsolidieren
- Content-Qualität bewerten
- Entscheidung: Was wird migriert, was wird archiviert?
Phase 2: Daten-Export und -Vorbereitung (Woche 2-3)
1. WordPress-Daten exportieren:
```xml
# Standard WordPress Export
WP-Admin → Tools → Export → All Content
# Für größere Websites: WP-CLI verwenden
wp export --dir=./export --skip_comments
```
2. Medien-Dateien sichern:
```bash
# Via FTP/SFTP den wp-content/uploads Ordner herunterladen
# Oder via SSH:
rsync -avz user@server:/pfad/zu/wp-content/uploads/ ./local-uploads/
```
3. Daten konvertieren:
Wichtige Tools für die Konversion:
- **wordpress-export-to-markdown**: Konvertiert WordPress XML zu Markdown
- **node-wpapi**: Nutzt WordPress REST API für strukturierten Export
- Eigene Skripte für spezielle Anforderungen
Beispiel-Skript für Datenkonversion:
```javascript
import fs from 'fs';
import xml2js from 'xml2js';
// WordPress XML parsen
const xmlData = fs.readFileSync('wordpress-export.xml', 'utf8');
const parser = new xml2js.Parser();
parser.parseString(xmlData, (err, result) => {
const posts = result.rss.channel[0].item;
posts.forEach(post => {
const blogPost = {
title: post.title[0],
slug: post['wp:post_name'][0],
content: post['content:encoded'][0],
excerpt: post['excerpt:encoded'][0],
date: post.pubDate[0],
author: post['dc:creator'][0],
categories: post.category?.map(cat => cat._) || [],
featured_image: post['wp:postmeta']?.find(
meta => meta['wp:meta_key'][0] === '_thumbnail_id'
)
};
// Als JSON speichern
fs.writeFileSync(
`./content/blog/${blogPost.slug}.json`,
JSON.stringify(blogPost, null, 2)
);
});
});
```
Phase 3: Next.js Projekt aufsetzen (Woche 3)
1. Next.js initialisieren:
```bash
npx create-next-app@latest meine-neue-website --typescript --tailwind --app
cd meine-neue-website
```
2. Wichtige Dependencies installieren:
```bash
# Für Markdown-Verarbeitung
npm install gray-matter remark remark-html
# Für Bilder-Optimierung
npm install sharp
# Für SEO
npm install next-sitemap
# Für Internationalisierung (falls mehrsprachig)
npm install next-intl
```
3. Projekt-Struktur erstellen:
```
app/
├── (main)/
│ ├── page.tsx # Homepage
│ ├── blog/
│ │ ├── page.tsx # Blog-Übersicht
│ │ └── [slug]/
│ │ └── page.tsx # Einzelne Blog-Posts
│ └── [slug]/
│ └── page.tsx # Dynamische Seiten
data/
├── posts/ # Konvertierte Blog-Posts
└── pages/ # Statische Seiten
public/
├── images/ # Optimierte Bilder
└── uploads/ # Migrierte WordPress-Uploads
```
Phase 4: Content-Migration (Woche 4-5)
1. Blog-Posts migrieren:
```typescript
// lib/posts.ts
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'data/posts');
export function getAllPosts() {
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
const slug = fileName.replace(/\.md$/, '');
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const { data, content } = matter(fileContents);
return {
slug,
content,
...data,
};
});
return allPostsData.sort((a, b) => {
return new Date(b.date) - new Date(a.date);
});
}
```
2. Bilder optimieren und migrieren:
```javascript
// scripts/optimize-images.js
import sharp from 'sharp';
import fs from 'fs';
import path from 'path';
const inputDir = './old-wordpress-uploads';
const outputDir = './public/images';
fs.readdirSync(inputDir).forEach(file => {
if (file.match(/\.(jpg|jpeg|png)$/)) {
sharp(path.join(inputDir, file))
.resize(1200, null, { withoutEnlargement: true })
.webp({ quality: 85 })
.toFile(path.join(outputDir, file.replace(/\.(jpg|jpeg|png)$/, '.webp')))
.then(() => console.log(`Optimiert: ${file}`));
}
});
```
3. Dynamische Seiten erstellen:
```typescript
// app/blog/[slug]/page.tsx
import { notFound } from 'next/navigation';
import { getAllPosts, getPostBySlug } from '@/lib/posts';
export async function generateStaticParams() {
const posts = getAllPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export async function generateMetadata({ params }) {
const post = getPostBySlug(params.slug);
if (!post) return { title: 'Post nicht gefunden' };
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [post.featured_image],
},
};
}
export default async function BlogPost({ params }) {
const post = getPostBySlug(params.slug);
if (!post) notFound();
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}
```
Phase 5: SEO-Migration (Woche 5-6)
1. URL-Redirects implementieren:
```javascript
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/blog/:year/:month/:day/:slug',
destination: '/blog/:slug',
permanent: true, // 301 Redirect
},
{
source: '/category/:slug',
destination: '/blog?category=:slug',
permanent: true,
},
];
},
};
```
2. Sitemap generieren:
```javascript
// next-sitemap.config.js
module.exports = {
siteUrl: 'https://ihre-domain.de',
generateRobotsTxt: true,
changefreq: 'daily',
priority: 0.7,
sitemapSize: 5000,
exclude: ['/admin', '/dashboard'],
robotsTxtOptions: {
policies: [
{ userAgent: '*', allow: '/' },
{ userAgent: 'GPTBot', disallow: '/' },
],
},
};
```
3. Strukturierte Daten hinzufügen:
```typescript
// components/ArticleSchema.tsx
export function ArticleSchema({ post }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
description: post.excerpt,
image: post.featured_image,
datePublished: post.date,
author: {
'@type': 'Person',
name: post.author,
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
```
Phase 6: WordPress-Funktionalität ersetzen (Woche 6-7)
1. Kontaktformulare:
```typescript
// Ersetzen Sie Contact Form 7 mit:
import { useState } from 'react';
export function ContactForm() {
const [formData, setFormData] = useState({});
async function handleSubmit(e) {
e.preventDefault();
const response = await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(formData),
});
// Handle response
}
return <form onSubmit={handleSubmit}>{/* Form fields */}</form>;
}
```
2. Suche implementieren:
```typescript
// Ersetzen Sie WordPress-Suche mit:
import { useState, useEffect } from 'react';
export function SearchBar() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
if (query.length > 2) {
const filtered = allPosts.filter(post =>
post.title.toLowerCase().includes(query.toLowerCase())
);
setResults(filtered);
}
}, [query]);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Suchen..."
/>
{/* Display results */}
</div>
);
}
```
3. Kommentare (Optional):
```typescript
// Verwenden Sie externe Services wie:
// - Disqus
// - Giscus (GitHub Discussions)
// - Oder eigenes System mit Supabase
import Giscus from '@giscus/react';
export function Comments() {
return (
<Giscus
repo="your-username/your-repo"
repoId="your-repo-id"
category="Comments"
categoryId="your-category-id"
mapping="pathname"
theme="light"
/>
);
}
```
Phase 7: Performance-Optimierung (Woche 7)
1. Bilder optimieren:
```typescript
import Image from 'next/image';
<Image
src="/images/blog-post.webp"
alt="Beschreibung"
width={1200}
height={630}
priority={isAboveFold}
quality={85}
sizes="(max-width: 768px) 100vw, 1200px"
/>
```
2. Code-Splitting:
```typescript
// Lazy Loading für große Komponenten
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <p>Lädt...</p>,
ssr: false,
});
```
3. Caching-Strategien:
```typescript
// app/blog/page.tsx
export const revalidate = 3600; // ISR: Alle 60 Min. neu generieren
export default async function BlogPage() {
const posts = await getPosts();
return <PostsList posts={posts} />;
}
```
Phase 8: Testing und Launch (Woche 8)
1. Pre-Launch Checkliste:
- [ ] Alle URLs getestet
- [ ] 301-Redirects funktionieren
- [ ] Sitemap generiert und bei Google eingereicht
- [ ] Strukturierte Daten validiert (Google Rich Results Test)
- [ ] Core Web Vitals geprüft (PageSpeed Insights)
- [ ] Mobile Responsiveness getestet
- [ ] Formulare funktionieren
- [ ] Analytics eingerichtet (Google Analytics 4)
- [ ] Backup der alten WordPress-Site erstellt
2. Soft Launch:
- Neue Site zunächst auf Subdomain deployen (beta.ihre-domain.de)
- Mit kleiner Nutzergruppe testen
- Feedback sammeln und letzte Anpassungen vornehmen
3. Go-Live:
```bash
# DNS auf neue Server umstellen
# A-Record auf neue IP oder CNAME auf Vercel
# Nach DNS-Propagation (24-48h):
# - Alte WordPress-Site im Read-Only-Modus für 30 Tage
# - Google Search Console neu verifizieren
# - Sitemap erneut einreichen
```
Phase 9: Post-Migration (Woche 9-12)
1. Monitoring:
- Google Search Console täglich prüfen (Crawling-Fehler, Coverage)
- Analytics-Daten vergleichen (Traffic, Bounce Rate, Conversions)
- Core Web Vitals überwachen
- Uptime-Monitoring einrichten
2. SEO-Nacharbeit:
- Fehlende 301-Redirects ergänzen
- Internal Linking optimieren
- Broken Links fixen
- Schema-Markup erweitern
3. Performance-Tuning:
- Bottlenecks identifizieren
- Caching optimieren
- CDN konfigurieren
- Database-Queries optimieren (falls CMS verwendet)
Kosten und Zeitaufwand
Typische Kosten für die Migration:
- **Kleine Website (5-20 Seiten)**: 2.000 - 5.000 €, 2-4 Wochen
- **Mittlere Website (20-100 Seiten)**: 5.000 - 15.000 €, 4-8 Wochen
- **Große Website (100+ Seiten)**: 15.000 - 50.000 €, 8-16 Wochen
Kosteneinsparungen nach Migration:
- Premium-Plugins: -500 - 1.500 € / Jahr
- Hosting: -200 - 1.000 € / Jahr
- Wartung & Updates: -1.000 - 3.000 € / Jahr
- Sicherheit: -500 - 2.000 € / Jahr
**ROI**: Meist nach 12-24 Monaten erreicht
Häufige Fallstricke vermeiden
1. **Zu schnell starten**: Gründliche Planung spart später Zeit
2. **SEO vernachlässigen**: 301-Redirects sind kritisch!
3. **Bilder nicht optimieren**: WebP-Format nutzen, Größen anpassen
4. **Keine Backups**: Immer mehrere Backups vor Migration
5. **Testing überspringen**: Gründlich testen vor Go-Live
6. **DNS-Propagation vergessen**: 24-48h einplanen
7. **Analytics nicht vorbereiten**: GA4 parallel laufen lassen
Fazit
Die Migration von WordPress zu Next.js ist eine strategische Entscheidung, die sorgfältige Planung erfordert, aber enorme Vorteile bietet:
✓ **3x schnellere Ladezeiten**
✓ **Bessere SEO-Rankings** durch Core Web Vitals
✓ **Niedrigere Betriebskosten** (bis zu 60% Ersparnis)
✓ **Höhere Sicherheit** ohne Plugin-Schwachstellen
✓ **Moderne Technologie** für zukünftige Anforderungen
Mit diesem Leitfaden haben Sie einen klaren Fahrplan für Ihre Migration. Der Aufwand lohnt sich – Ihre neue Next.js-Website wird schneller, sicherer und zukunftssicher sein.
Nächste Schritte
Bereit für die Migration? Kontaktieren Sie uns für:
- Kostenlose Migrations-Analyse Ihrer WordPress-Site
- Detailliertes Angebot mit Zeitplan
- Technische Beratung zu Ihrer individuellen Situation
Wir begleiten Sie durch den gesamten Migrationsprozess – von der Planung bis zum erfolgreichen Go-Live.
