# Technical SEO Checklist **Meta-Description:** Komplette Technical SEO Checklist für 2026. Crawling, Indexierung, Site Structure und Performance-Optimierung für bessere Rankings. **Keywords:** Technical SEO, SEO Checklist, Crawling, Indexierung, Site Structure, Page Speed, Mobile SEO, SEO Audit --- ## Einführung **Technical SEO** bildet das Fundament für erfolgreiche Suchmaschinenoptimierung. Ohne saubere technische Basis nützt der beste Content wenig. Diese Checklist deckt alle wichtigen Aspekte ab – von **Crawling** bis **Performance**. --- ## Technical SEO Overview ``` ┌─────────────────────────────────────────────────────────────┐ │ TECHNICAL SEO PYRAMID │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────┐ │ │ │ Content │ │ │ │ & UX │ │ │ └────┬────┘ │ │ ┌─────────┴─────────┐ │ │ │ On-Page SEO │ │ │ │ (Title, Meta,H1) │ │ │ └─────────┬─────────┘ │ │ ┌──────────────┴──────────────┐ │ │ │ Site Architecture │ │ │ │ (URLs, Internal Links) │ │ │ └──────────────┬──────────────┘ │ │ ┌───────────────────┴───────────────────┐ │ │ │ Crawling & Indexing │ │ │ │ (robots.txt, sitemap, canonicals) │ │ │ └───────────────────┬───────────────────┘ │ │ ┌──────────────────────┴──────────────────────┐ │ │ │ Server & Performance │ │ │ │ (HTTPS, Speed, Core Web Vitals, Mobile) │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ Priority Levels: │ │ 🔴 Critical - Must fix immediately │ │ 🟡 Important - Fix soon │ │ 🟢 Nice to have - Optimize when possible │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Server & Security ```typescript // lib/seo/audit/server.ts interface ServerAuditResult { https: boolean; httpToHttpsRedirect: boolean; wwwRedirect: 'www' | 'non-www' | 'inconsistent'; responseTime: number; serverHeaders: Record; issues: string[]; } async function auditServer(url: string): Promise { const issues: string[] = []; // HTTPS Check const https = url.startsWith('https://'); if (!https) { issues.push('🔴 Site is not using HTTPS'); } // HTTP to HTTPS Redirect const httpUrl = url.replace('https://', 'http://'); const httpResponse = await fetch(httpUrl, { redirect: 'manual' }); const httpToHttpsRedirect = httpResponse.status === 301 && httpResponse.headers.get('location')?.startsWith('https://'); if (!httpToHttpsRedirect) { issues.push('🔴 HTTP does not redirect to HTTPS'); } // WWW Consistency const withWww = url.includes('www.'); const testUrl = withWww ? url.replace('www.', '') : url.replace('://', '://www.'); const wwwResponse = await fetch(testUrl, { redirect: 'manual' }); const wwwRedirect = wwwResponse.status === 301 ? (withWww ? 'www' : 'non-www') : 'inconsistent'; if (wwwRedirect === 'inconsistent') { issues.push('🟡 WWW and non-WWW versions not properly redirected'); } // Response Time const start = Date.now(); await fetch(url); const responseTime = Date.now() - start; if (responseTime > 500) { issues.push(`🟡 Server response time is slow: ${responseTime}ms`); } // Security Headers const response = await fetch(url); const serverHeaders: Record = {}; response.headers.forEach((value, key) => { serverHeaders[key] = value; }); const requiredHeaders = [ 'strict-transport-security', 'x-content-type-options', 'x-frame-options' ]; requiredHeaders.forEach(header => { if (!serverHeaders[header]) { issues.push(`🟢 Missing security header: ${header}`); } }); return { https, httpToHttpsRedirect, wwwRedirect, responseTime, serverHeaders, issues }; } ``` ```typescript // middleware.ts - Security Headers import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const response = NextResponse.next(); // Security Headers response.headers.set('X-DNS-Prefetch-Control', 'on'); response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload'); response.headers.set('X-Content-Type-Options', 'nosniff'); response.headers.set('X-Frame-Options', 'SAMEORIGIN'); response.headers.set('X-XSS-Protection', '1; mode=block'); response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin'); // Permissions Policy response.headers.set( 'Permissions-Policy', 'camera=(), microphone=(), geolocation=(self), interest-cohort=()' ); return response; } ``` --- ## Crawling & Indexing ```typescript // app/robots.ts - Optimized robots.txt import { MetadataRoute } from 'next'; export default function robots(): MetadataRoute.Robots { const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com'; return { rules: [ { userAgent: '*', allow: '/', disallow: [ '/api/', '/admin/', '/_next/', '/private/', '/*.json$', '/*?*', // Query Parameter '/search?*' ] }, { userAgent: 'Googlebot', allow: '/', disallow: ['/admin/', '/api/'] }, { // Block bad bots userAgent: ['AhrefsBot', 'SemrushBot', 'DotBot'], disallow: '/' } ], sitemap: `${baseUrl}/sitemap.xml`, host: baseUrl }; } // app/sitemap.ts - Dynamic Sitemap import { MetadataRoute } from 'next'; import { getAllPages, getAllPosts, getAllProducts } from '@/lib/content'; export default async function sitemap(): Promise { const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com'; // Static Pages const staticPages: MetadataRoute.Sitemap = [ { url: baseUrl, lastModified: new Date(), changeFrequency: 'daily', priority: 1.0 }, { url: `${baseUrl}/about`, lastModified: new Date(), changeFrequency: 'monthly', priority: 0.8 }, { url: `${baseUrl}/contact`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.5 }, { url: `${baseUrl}/blog`, lastModified: new Date(), changeFrequency: 'daily', priority: 0.9 } ]; // Dynamic Pages const pages = await getAllPages(); const dynamicPages: MetadataRoute.Sitemap = pages.map(page => ({ url: `${baseUrl}/${page.slug}`, lastModified: new Date(page.updatedAt), changeFrequency: 'monthly', priority: 0.7 })); // Blog Posts const posts = await getAllPosts(); const blogPosts: MetadataRoute.Sitemap = posts.map(post => ({ url: `${baseUrl}/blog/${post.slug}`, lastModified: new Date(post.updatedAt), changeFrequency: 'weekly', priority: 0.8 })); // Products const products = await getAllProducts(); const productPages: MetadataRoute.Sitemap = products.map(product => ({ url: `${baseUrl}/products/${product.slug}`, lastModified: new Date(product.updatedAt), changeFrequency: 'daily', priority: 0.9 })); return [...staticPages, ...dynamicPages, ...blogPosts, ...productPages]; } ``` ```typescript // lib/seo/canonical.ts - Canonical URL Helper export function getCanonicalUrl(path: string, locale?: string): string { const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com'; // Remove trailing slash const cleanPath = path.replace(/\/$/, ''); // Remove query parameters for canonical const pathWithoutQuery = cleanPath.split('?')[0]; // Add locale if needed if (locale && locale !== 'de') { return `${baseUrl}/${locale}${pathWithoutQuery}`; } return `${baseUrl}${pathWithoutQuery}`; } // Usage in page export async function generateMetadata({ params }: PageProps): Promise { return { alternates: { canonical: getCanonicalUrl(`/blog/${params.slug}`) } }; } ``` --- ## URL Structure ```typescript // lib/seo/url-utils.ts export function createSEOFriendlyUrl(title: string): string { return title .toLowerCase() .trim() // Umlaute ersetzen .replace(/ä/g, 'ae') .replace(/ö/g, 'oe') .replace(/ü/g, 'ue') .replace(/ß/g, 'ss') // Sonderzeichen entfernen .replace(/[^a-z0-9\s-]/g, '') // Mehrere Leerzeichen zu einem .replace(/\s+/g, ' ') // Leerzeichen zu Bindestrich .replace(/\s/g, '-') // Mehrere Bindestriche zu einem .replace(/-+/g, '-') // Max Länge .substring(0, 60); } // URL Audit interface URLAuditResult { url: string; issues: string[]; suggestions: string[]; } export function auditURL(url: string): URLAuditResult { const issues: string[] = []; const suggestions: string[] = []; // Length check if (url.length > 75) { issues.push('🟡 URL is too long (> 75 characters)'); } // Uppercase check if (url !== url.toLowerCase()) { issues.push('🟡 URL contains uppercase characters'); } // Underscore check if (url.includes('_')) { issues.push('🟡 URL contains underscores (use hyphens instead)'); } // Double slashes if (url.includes('//') && !url.startsWith('http')) { issues.push('🔴 URL contains double slashes'); } // Query parameters if (url.includes('?')) { suggestions.push('Consider using clean URLs without query parameters'); } // Trailing slash consistency if (!url.endsWith('/') && !url.includes('.')) { suggestions.push('Consider adding trailing slash for consistency'); } return { url, issues, suggestions }; } ``` --- ## On-Page SEO ```typescript // lib/seo/audit/onpage.ts interface OnPageAuditResult { title: { value: string; length: number; issues: string[] }; metaDescription: { value: string; length: number; issues: string[] }; h1: { count: number; value: string; issues: string[] }; headings: { h2: number; h3: number; h4: number; issues: string[] }; images: { total: number; withoutAlt: number; issues: string[] }; links: { internal: number; external: number; broken: number; issues: string[] }; } async function auditOnPage(html: string, url: string): Promise { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); // Title const title = doc.querySelector('title')?.textContent || ''; const titleIssues: string[] = []; if (!title) titleIssues.push('🔴 Missing title tag'); else if (title.length < 30) titleIssues.push('🟡 Title too short (< 30 chars)'); else if (title.length > 60) titleIssues.push('🟡 Title too long (> 60 chars)'); // Meta Description const metaDesc = doc.querySelector('meta[name="description"]')?.getAttribute('content') || ''; const metaDescIssues: string[] = []; if (!metaDesc) metaDescIssues.push('🔴 Missing meta description'); else if (metaDesc.length < 120) metaDescIssues.push('🟡 Meta description too short'); else if (metaDesc.length > 160) metaDescIssues.push('🟡 Meta description too long'); // H1 const h1Elements = doc.querySelectorAll('h1'); const h1Issues: string[] = []; if (h1Elements.length === 0) h1Issues.push('🔴 Missing H1 tag'); else if (h1Elements.length > 1) h1Issues.push('🟡 Multiple H1 tags found'); // Heading Structure const h2Count = doc.querySelectorAll('h2').length; const h3Count = doc.querySelectorAll('h3').length; const h4Count = doc.querySelectorAll('h4').length; const headingIssues: string[] = []; if (h2Count === 0) headingIssues.push('🟡 No H2 headings found'); // Images const images = doc.querySelectorAll('img'); const imagesWithoutAlt = Array.from(images).filter( img => !img.getAttribute('alt') ).length; const imageIssues: string[] = []; if (imagesWithoutAlt > 0) { imageIssues.push(`🟡 ${imagesWithoutAlt} images missing alt text`); } // Links const links = doc.querySelectorAll('a[href]'); const baseUrl = new URL(url); let internalLinks = 0; let externalLinks = 0; const linkIssues: string[] = []; links.forEach(link => { const href = link.getAttribute('href') || ''; if (href.startsWith('/') || href.includes(baseUrl.hostname)) { internalLinks++; } else if (href.startsWith('http')) { externalLinks++; // Check for nofollow on external links const rel = link.getAttribute('rel') || ''; if (!rel.includes('nofollow') && !rel.includes('sponsored')) { // Suggestion, not issue } } }); return { title: { value: title, length: title.length, issues: titleIssues }, metaDescription: { value: metaDesc, length: metaDesc.length, issues: metaDescIssues }, h1: { count: h1Elements.length, value: h1Elements[0]?.textContent || '', issues: h1Issues }, headings: { h2: h2Count, h3: h3Count, h4: h4Count, issues: headingIssues }, images: { total: images.length, withoutAlt: imagesWithoutAlt, issues: imageIssues }, links: { internal: internalLinks, external: externalLinks, broken: 0, issues: linkIssues } }; } ``` --- ## Complete SEO Checklist ```typescript // lib/seo/checklist.ts export const technicalSEOChecklist = { server: [ { id: 'https', priority: 'critical', item: 'HTTPS enabled', automated: true }, { id: 'http-redirect', priority: 'critical', item: 'HTTP redirects to HTTPS (301)', automated: true }, { id: 'www-redirect', priority: 'important', item: 'WWW/non-WWW consistency', automated: true }, { id: 'response-time', priority: 'important', item: 'Server response < 500ms', automated: true }, { id: 'security-headers', priority: 'nice', item: 'Security headers configured', automated: true } ], crawling: [ { id: 'robots-txt', priority: 'critical', item: 'robots.txt exists and valid', automated: true }, { id: 'sitemap', priority: 'critical', item: 'XML Sitemap exists', automated: true }, { id: 'sitemap-submitted', priority: 'important', item: 'Sitemap submitted to Search Console', automated: false }, { id: 'no-crawl-errors', priority: 'critical', item: 'No crawl errors in Search Console', automated: false }, { id: 'canonical-tags', priority: 'critical', item: 'Canonical tags on all pages', automated: true } ], indexing: [ { id: 'indexable', priority: 'critical', item: 'Important pages are indexable', automated: true }, { id: 'noindex-correct', priority: 'important', item: 'noindex only on non-important pages', automated: true }, { id: 'no-duplicate-content', priority: 'critical', item: 'No duplicate content issues', automated: true }, { id: 'hreflang', priority: 'important', item: 'hreflang tags for multilingual sites', automated: true } ], urlStructure: [ { id: 'url-readable', priority: 'important', item: 'URLs are human-readable', automated: true }, { id: 'url-lowercase', priority: 'important', item: 'URLs are lowercase', automated: true }, { id: 'url-hyphens', priority: 'nice', item: 'URLs use hyphens (not underscores)', automated: true }, { id: 'url-length', priority: 'nice', item: 'URLs under 75 characters', automated: true }, { id: 'no-parameters', priority: 'nice', item: 'Clean URLs without parameters', automated: true } ], onPage: [ { id: 'title-tag', priority: 'critical', item: 'Unique title tag (50-60 chars)', automated: true }, { id: 'meta-description', priority: 'critical', item: 'Meta description (150-160 chars)', automated: true }, { id: 'h1-tag', priority: 'critical', item: 'Single H1 per page', automated: true }, { id: 'heading-hierarchy', priority: 'important', item: 'Proper heading hierarchy', automated: true }, { id: 'image-alt', priority: 'important', item: 'All images have alt text', automated: true }, { id: 'internal-links', priority: 'important', item: 'Internal linking structure', automated: false } ], performance: [ { id: 'lcp', priority: 'critical', item: 'LCP < 2.5s', automated: true }, { id: 'inp', priority: 'critical', item: 'INP < 200ms', automated: true }, { id: 'cls', priority: 'critical', item: 'CLS < 0.1', automated: true }, { id: 'mobile-friendly', priority: 'critical', item: 'Mobile-friendly design', automated: true }, { id: 'page-size', priority: 'important', item: 'Page size < 3MB', automated: true } ], structuredData: [ { id: 'jsonld', priority: 'important', item: 'JSON-LD structured data', automated: true }, { id: 'valid-schema', priority: 'important', item: 'Schema validates in Rich Results Test', automated: false }, { id: 'breadcrumbs', priority: 'nice', item: 'Breadcrumb schema', automated: true } ] }; // Generate Audit Report export function generateSEOReport(results: Record): string { let report = '# Technical SEO Audit Report\n\n'; Object.entries(technicalSEOChecklist).forEach(([category, items]) => { report += `## ${category.charAt(0).toUpperCase() + category.slice(1)}\n\n`; items.forEach(item => { const status = results[item.id]; const emoji = status ? '✅' : (item.priority === 'critical' ? '❌' : '⚠️'); report += `${emoji} ${item.item}\n`; }); report += '\n'; }); return report; } ``` --- ## Checklist Summary | Category | Critical | Important | Nice to Have | |----------|----------|-----------|--------------| | **Server** | HTTPS, Redirects | Response time | Security headers | | **Crawling** | robots.txt, Sitemap | Search Console | Crawl budget | | **Indexing** | Canonical, No duplicates | hreflang | Coverage report | | **URLs** | - | Readable, lowercase | Short URLs | | **On-Page** | Title, Meta, H1 | Alt text, Headings | Schema | | **Performance** | Core Web Vitals | Page size | Resource hints | --- ## Fazit Technical SEO Checklist erfordert: 1. **Server-Basics**: HTTPS, Redirects, Security 2. **Crawling**: robots.txt, Sitemap, Canonical 3. **On-Page**: Title, Meta, Headings, Images 4. **Performance**: Core Web Vitals optimieren Regelmäßige Audits sichern die technische Basis. --- ## Bildprompts 1. "SEO audit dashboard showing checklist items, green checkmarks" 2. "Technical SEO pyramid diagram, layered structure" 3. "Search Console crawl stats visualization, data charts" --- ## Quellen - [Google Search Central](https://developers.google.com/search/docs) - [Ahrefs Technical SEO Guide](https://ahrefs.com/blog/technical-seo/) - [Moz Technical SEO](https://moz.com/learn/seo/technical-seo) - [Web.dev SEO](https://web.dev/learn/seo/)