Technical SEO Checklist for Developers (2026)
Back to Blog
Strategy & Business

Technical SEO Checklist for Developers (2026)

January 21, 2026
14 min read
Jonas Höttler

Technical SEO Checklist for Developers

Technical SEO is the foundation. Without it, the best content is worthless. This checklist covers everything you need to know as a developer – with code examples you can implement directly.

1. Crawling & Indexing

robots.txt

Location: /robots.txt

User-agent: *
Allow: /

# Block admin and API routes
Disallow: /admin/
Disallow: /api/
Disallow: /_next/

# Sitemap location
Sitemap: https://example.com/sitemap.xml

Checklist:

  • robots.txt exists and is accessible
  • Important pages are not blocked
  • Sitemap location specified
  • API/Admin areas blocked

Test: site:yourdomain.com in Google – do you see all important pages?

XML Sitemap

Location: /sitemap.xml

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-01-21</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://example.com/blog/article-1</loc>
    <lastmod>2026-01-15</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
</urlset>

For Next.js (auto-generate):

// next-sitemap.config.js
module.exports = {
  siteUrl: 'https://example.com',
  generateRobotsTxt: true,
  sitemapSize: 7000,
  changefreq: 'weekly',
  priority: 0.7,
  exclude: ['/admin/*', '/api/*'],
}

Checklist:

  • Sitemap contains all important URLs
  • lastmod dates are current
  • Sitemap submitted to Search Console
  • No 4xx/5xx URLs in sitemap

Canonical Tags

Avoid duplicate content:

<link rel="canonical" href="https://example.com/blog/article" />

Typical problems:

  • /blog/article vs /blog/article/
  • http:// vs https://
  • www. vs non-www
  • URL parameters (e.g., ?utm_source=...)

Next.js Example:

import Head from 'next/head';

export default function Page() {
  return (
    <Head>
      <link rel="canonical" href="https://example.com/page" />
    </Head>
  );
}

2. Core Web Vitals

LCP (Largest Contentful Paint)

Target: < 2.5 seconds

Common problems and solutions:

1. Optimize images:

<!-- Before -->
<img src="hero.jpg" />

<!-- After -->
<img
  src="hero.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"
  loading="eager"
  fetchpriority="high"
  alt="Hero Image"
/>

2. Preload critical resources:

<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/hero.webp" as="image">

3. Server Response Time:

  • Use CDN
  • Implement caching
  • Server-Side Rendering for critical content

FID/INP (First Input Delay / Interaction to Next Paint)

Target: < 100ms (FID), < 200ms (INP)

Main problem: JavaScript blocks the main thread

Solutions:

1. Code Splitting:

// Dynamic import
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <Skeleton />,
});

2. Web Workers for heavy calculations:

// worker.js
self.onmessage = function(e) {
  const result = heavyCalculation(e.data);
  self.postMessage(result);
};

// main.js
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = (e) => console.log(e.data);

3. Debounce and Throttle:

const handleScroll = throttle(() => {
  // Expensive operation
}, 100);

CLS (Cumulative Layout Shift)

Target: < 0.1

Main problems and solutions:

1. Images without dimensions:

<!-- Bad -->
<img src="photo.jpg" />

<!-- Good -->
<img src="photo.jpg" width="800" height="600" />

<!-- Or with aspect-ratio -->
<img src="photo.jpg" style="aspect-ratio: 4/3; width: 100%;" />

2. Ads and Embeds:

.ad-container {
  min-height: 250px; /* Reserve space */
}

3. Web Fonts:

@font-face {
  font-family: 'CustomFont';
  src: url('/font.woff2') format('woff2');
  font-display: swap; /* or optional */
  size-adjust: 100%;
  ascent-override: 95%;
  descent-override: 20%;
}

3. Structured Data (Schema Markup)

Article Schema

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Technical SEO Checklist for Developers",
  "description": "Everything developers need to know about technical SEO",
  "author": {
    "@type": "Person",
    "name": "Jonas Höttler",
    "url": "https://hoettler.com"
  },
  "datePublished": "2026-06-30",
  "dateModified": "2026-06-30",
  "publisher": {
    "@type": "Organization",
    "name": "Höttler Tech",
    "logo": {
      "@type": "ImageObject",
      "url": "https://hoettler.com/logo.png"
    }
  },
  "image": "https://hoettler.com/article-image.jpg"
}

FAQ Schema

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is technical SEO?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Technical SEO encompasses all technical optimizations..."
      }
    }
  ]
}

HowTo Schema

Perfect for tutorials:

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to improve Core Web Vitals",
  "step": [
    {
      "@type": "HowToStep",
      "name": "Optimize images",
      "text": "Convert images to WebP and use responsive images."
    }
  ]
}

Implementation in Next.js:

export default function Article({ data }) {
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: data.title,
    // ...
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* Article content */}
    </>
  );
}

4. Mobile Optimization

Viewport Meta Tag

<meta name="viewport" content="width=device-width, initial-scale=1" />

Mobile-First CSS

/* Base styles (mobile) */
.container {
  padding: 1rem;
}

/* Tablet */
@media (min-width: 768px) {
  .container {
    padding: 2rem;
  }
}

/* Desktop */
@media (min-width: 1024px) {
  .container {
    padding: 3rem;
    max-width: 1200px;
  }
}

Touch Targets

button, a {
  min-height: 48px;
  min-width: 48px;
  padding: 12px;
}

5. HTTPS & Security

HSTS Header

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

In Next.js (next.config.js):

module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=31536000; includeSubDomains'
          }
        ]
      }
    ]
  }
}

Content Security Policy

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline';

6. Internationalization (i18n)

hreflang Tags

<link rel="alternate" hreflang="de" href="https://example.com/de/page" />
<link rel="alternate" hreflang="en" href="https://example.com/en/page" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page" />

In the Sitemap

<url>
  <loc>https://example.com/de/page</loc>
  <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/page"/>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page"/>
</url>

7. Performance Optimization

Resource Hints

<!-- DNS Prefetch for external domains -->
<link rel="dns-prefetch" href="//fonts.googleapis.com">

<!-- Preconnect for critical domains -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- Preload for critical resources -->
<link rel="preload" href="/critical.css" as="style">

<!-- Prefetch for likely needed resources -->
<link rel="prefetch" href="/next-page.js">

Lazy Loading

<!-- Native Lazy Loading -->
<img src="image.jpg" loading="lazy" alt="...">

<!-- Intersection Observer for complex cases -->
<script>
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;
      observer.unobserve(entry.target);
    }
  });
});

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
</script>

The Ultimate Checklist

Crawling & Indexing

  • robots.txt correctly configured
  • XML Sitemap present and current
  • Sitemap submitted to Search Console
  • Canonical tags on all pages
  • No duplicate content issues

Core Web Vitals

  • LCP < 2.5s
  • INP < 200ms
  • CLS < 0.1
  • Images optimized (WebP, responsive)
  • Fonts optimized (preload, font-display)

Structured Data

  • Article Schema on blog posts
  • FAQ Schema where relevant
  • Organization Schema on homepage
  • Schema validated (Rich Results Test)

Mobile

  • Viewport Meta Tag present
  • Mobile-responsive design
  • Touch targets minimum 48x48px
  • No horizontal scrollbars

Security

  • HTTPS everywhere
  • HSTS header set
  • Mixed content avoided

Internationalization

  • hreflang tags correct
  • Language specified in HTML tag
  • Language versions in sitemap

Tools for Verification

ToolChecksLink
Google Search ConsoleIndexing, errorssearch.google.com/search-console
PageSpeed InsightsCore Web Vitalspagespeed.web.dev
Rich Results TestStructured Datasearch.google.com/test/rich-results
Mobile-Friendly TestMobile optimizationsearch.google.com/test/mobile-friendly
LighthouseEverythingIn Chrome DevTools

Conclusion

Technical SEO is not a one-time project – it's continuous work. But once set up correctly, it forms the foundation for all further SEO measures.

The most important priorities:

  1. Be crawlable – robots.txt, sitemap, no blockers
  2. Be fast – optimize Core Web Vitals
  3. Be structured – implement Schema Markup
  4. Mobile-first – responsive, touch-friendly

Use the checklist as a starting point and work through it systematically.


Want to learn more about keyword research without expensive tools? Our guide SEO for Tech Blogs shows you free methods.

#Technical SEO#Core Web Vitals#Schema Markup#Web Performance#Developer SEO

Have a similar project?

Let's talk about how I can help you.

Get in touch