DEV Community

Deniz Egemen
Deniz Egemen

Posted on

Technical SEO for Developers: From 0 to 10M Impressions

Technical SEO for Developers: From 0 to 10M Impressions

6 years, 200+ sites, real performance data

TL;DR

  • Core Web Vitals = SEO rankings in 2024
  • Schema markup boosts click-through rates by 30%+
  • Automated sitemaps and meta generation saves hours
  • Performance optimization directly impacts conversion

Core Web Vitals: The Technical Foundation

Largest Contentful Paint (LCP) < 2.5s

// Next.js optimization
import Image from 'next/image';

const HeroSection = () => (
  <Image
    src="/hero.webp"
    alt="Hero image"
    width={1200}
    height={600}
    priority // Critical for LCP
    sizes="(max-width: 768px) 100vw, 1200px"
  />
);

// Preload critical resources
<link rel="preload" href="/critical-font.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/hero.webp" as="image" />
Enter fullscreen mode Exit fullscreen mode

First Input Delay (FID) < 100ms

// Code splitting for better FID
const LazyModal = lazy(() => import('./Modal'));

// Web Workers for heavy tasks
const worker = new Worker('/calculator-worker.js');
worker.postMessage({operation: 'calculate', data: bigDataSet});
Enter fullscreen mode Exit fullscreen mode

Cumulative Layout Shift (CLS) < 0.1

/* Prevent layout shifts */
.image-placeholder {
  aspect-ratio: 16 / 9;
  background: #f0f0f0;
}

@font-face {
  font-family: 'CustomFont';
  src: url('/font.woff2') format('woff2');
  font-display: swap; /* Prevents invisible text */
}
Enter fullscreen mode Exit fullscreen mode

Schema Markup That Actually Works

Product Schema for E-commerce

const ProductSchema = ({ product }) => {
  const schema = {
    "@context": "https://schema.org/",
    "@type": "Product",
    "name": product.name,
    "description": product.description,
    "image": product.images,
    "brand": {"@type": "Brand", "name": product.brand},
    "offers": {
      "@type": "Offer",
      "price": product.price,
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock"
    },
    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": product.rating,
      "reviewCount": product.reviews
    }
  };

  return (
    <script 
      type="application/ld+json"
      dangerouslySetInnerHTML={{__html: JSON.stringify(schema)}}
    />
  );
};
Enter fullscreen mode Exit fullscreen mode

Article Schema for Better SERP

const ArticleSchema = ({ article }) => ({
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": article.title,
  "image": article.featuredImage,
  "datePublished": article.publishDate,
  "dateModified": article.modifiedDate,
  "author": {
    "@type": "Person", 
    "name": article.author
  },
  "publisher": {
    "@type": "Organization",
    "name": "DEOK YAZILIM",
    "logo": "https://deokyazilim.com/logo.png"
  }
});
Enter fullscreen mode Exit fullscreen mode

Automated Sitemap Generation

Dynamic Next.js Sitemap

// pages/sitemap.xml.js
export async function getServerSideProps({ res }) {
  const baseUrl = 'https://yoursite.com';
  const posts = await getAllBlogPosts();
  const products = await getAllProducts();

  const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      <url>
        <loc>${baseUrl}</loc>
        <lastmod>${new Date().toISOString()}</lastmod>
        <changefreq>daily</changefreq>
        <priority>1.0</priority>
      </url>

      ${posts.map(post => `
        <url>
          <loc>${baseUrl}/blog/${post.slug}</loc>
          <lastmod>${post.updatedAt}</lastmod>
          <changefreq>weekly</changefreq>
          <priority>0.8</priority>
        </url>
      `).join('')}

      ${products.map(product => `
        <url>
          <loc>${baseUrl}/products/${product.slug}</loc>
          <lastmod>${product.updatedAt}</lastmod>
          <changefreq>weekly</changefreq>
          <priority>0.9</priority>
        </url>
      `).join('')}
    </urlset>`;

  res.setHeader('Content-Type', 'text/xml');
  res.write(sitemap);
  res.end();
  return { props: {} };
}
Enter fullscreen mode Exit fullscreen mode

Google Analytics 4 Implementation

Enhanced E-commerce Tracking

// lib/gtag.js
export const trackPurchase = (transactionId, items, value) => {
  gtag('event', 'purchase', {
    transaction_id: transactionId,
    value: value,
    currency: 'USD',
    items: items.map(item => ({
      item_id: item.id,
      item_name: item.name,
      category: item.category,
      quantity: item.quantity,
      price: item.price
    }))
  });
};

export const trackFormSubmission = (formType) => {
  gtag('event', 'generate_lead', {
    form_type: formType,
    value: 50, // Lead value
    currency: 'USD'
  });
};
Enter fullscreen mode Exit fullscreen mode

React Analytics Hook

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export const useAnalytics = () => {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag('config', GA_TRACKING_ID, {
        page_location: url,
        page_title: document.title
      });
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => router.events.off('routeChangeComplete', handleRouteChange);
  }, [router.events]);

  return {
    trackEvent: (eventName, parameters) => gtag('event', eventName, parameters),
    trackConversion: (conversionName, value) => gtag('event', 'conversion', {
      send_to: `${GA_TRACKING_ID}/${conversionName}`,
      value: value
    })
  };
};
Enter fullscreen mode Exit fullscreen mode

SEO Component Library

Smart Meta Component

// components/SEO.js
import Head from 'next/head';

const SEO = ({ 
  title, 
  description, 
  canonical, 
  ogImage,
  noindex = false 
}) => {
  const fullTitle = title ? `${title} | DEOK YAZILIM` : 'DEOK YAZILIM';
  const truncDesc = description?.slice(0, 160);

  return (
    <Head>
      <title>{fullTitle}</title>
      <meta name="description" content={truncDesc} />
      <link rel="canonical" href={canonical} />

      {noindex && <meta name="robots" content="noindex,nofollow" />}

      {/* Open Graph */}
      <meta property="og:title" content={fullTitle} />
      <meta property="og:description" content={truncDesc} />
      <meta property="og:image" content={ogImage} />
      <meta property="og:url" content={canonical} />

      {/* Twitter Card */}
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={fullTitle} />
      <meta name="twitter:description" content={truncDesc} />
      <meta name="twitter:image" content={ogImage} />
    </Head>
  );
};
Enter fullscreen mode Exit fullscreen mode

Automated Internal Linking

// lib/internalLinking.js
export const addInternalLinks = (content, linkMap) => {
  let linkedContent = content;

  Object.entries(linkMap).forEach(([keyword, url]) => {
    const regex = new RegExp(`\\b${keyword}\\b`, 'i');
    if (regex.test(linkedContent) && !linkedContent.includes(`href="${url}"`)) {
      linkedContent = linkedContent.replace(
        regex, 
        `<a href="${url}" title="${keyword}">${keyword}</a>`
      );
    }
  });

  return linkedContent;
};

// Usage
const linkMap = {
  'React Native': '/hizmetlerimiz/mobil-uygulama',
  'ERP sistemi': '/hizmetlerimiz/erp',
  'SEO': '/hizmetlerimiz/seo-digital-marketing'
};

const linkedContent = addInternalLinks(blogContent, linkMap);
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

Image Optimization Pipeline

// next.config.js
module.exports = {
  images: {
    domains: ['cdn.deokyazilim.com'],
    formats: ['image/webp', 'image/avif'],
    minimumCacheTTL: 31536000, // 1 year
  },

  // Gzip compression
  compress: true,

  // Bundle optimization
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback.fs = false;
    }
    return config;
  },
};
Enter fullscreen mode Exit fullscreen mode

Critical CSS Extraction

// lib/criticalCSS.js
import { PurgeCSS } from 'purgecss';

export const extractCriticalCSS = async (html, cssFiles) => {
  const result = await new PurgeCSS().purge({
    content: [{ raw: html, extension: 'html' }],
    css: cssFiles,
    whitelist: ['html', 'body']
  });

  return result[0].css;
};

// Inline critical CSS
const CriticalCSS = ({ css }) => (
  <style dangerouslySetInnerHTML={{__html: css}} />
);
Enter fullscreen mode Exit fullscreen mode

Local SEO Implementation

Google My Business Schema

const LocalBusinessSchema = ({ business }) => ({
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "DEOK YAZILIM",
  "image": "https://deokyazilim.com/logo.png",
  "telephone": "+90-XXX-XXX-XXXX",
  "address": {
    "@type": "PostalAddress",
    "addressLocality": "İstanbul",
    "addressCountry": "TR"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": "41.0082",
    "longitude": "28.9784"
  },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
    "opens": "09:00",
    "closes": "18:00"
  }]
});
Enter fullscreen mode Exit fullscreen mode

Content Optimization

SEO Content Analyzer

// lib/contentAnalyzer.js
export const analyzeContent = (content) => {
  const words = content.split(/\s+/).length;
  const sentences = content.split(/[.!?]+/).length;
  const readability = calculateReadability(content);
  const keywordDensity = analyzeKeywords(content);

  return {
    wordCount: words,
    readabilityScore: readability,
    keywordDensity,
    recommendations: generateSEORecommendations(words, readability, keywordDensity)
  };
};

const generateSEORecommendations = (words, readability, keywords) => {
  const recommendations = [];

  if (words < 300) recommendations.push('Content too short. Aim for 300+ words.');
  if (readability < 60) recommendations.push('Content hard to read. Simplify.');
  if (keywords.main > 3) recommendations.push('Keyword density too high.');

  return recommendations;
};
Enter fullscreen mode Exit fullscreen mode

Real Performance Data

Before vs After Optimization

Site Performance Metrics:

Before:
- Lighthouse Score: 42/100
- LCP: 4.2 seconds
- FID: 280ms
- CLS: 0.35
- Organic Traffic: 2,000/month

After 3 months:
- Lighthouse Score: 96/100
- LCP: 1.6 seconds  
- FID: 45ms
- CLS: 0.03
- Organic Traffic: 28,000/month

ROI: 1,400% traffic increase
Enter fullscreen mode Exit fullscreen mode

SEO Impact

Ranking Improvements:
- Featured Snippets: 0 → 34
- Top 3 Rankings: 5 → 67
- Page 1 Rankings: 23 → 156
- Organic CTR: 1.8% → 4.2%
- Conversion Rate: 2.1% → 5.7%
Enter fullscreen mode Exit fullscreen mode

Monitoring & Automation

SEO Health Check

// lib/seoMonitor.js
export const runSEOAudit = async (url) => {
  const lighthouse = require('lighthouse');
  const chrome = await chromeLauncher.launch();

  const result = await lighthouse(url, {
    port: chrome.port,
    onlyCategories: ['performance', 'seo']
  });

  await chrome.kill();

  return {
    performance: result.lhr.categories.performance.score * 100,
    seo: result.lhr.categories.seo.score * 100,
    issues: extractSEOIssues(result.lhr.audits)
  };
};

// Weekly monitoring
const scheduleAudits = () => {
  cron.schedule('0 0 * * 1', async () => {
    const criticalPages = await getCriticalPages();
    const results = await Promise.all(
      criticalPages.map(page => runSEOAudit(page.url))
    );
    await sendSEOReport(results);
  });
};
Enter fullscreen mode Exit fullscreen mode

Advanced Tracking

Custom Events & Conversions

// Track micro-conversions
const trackEngagement = (action, element) => {
  gtag('event', 'engagement', {
    action: action,
    element: element,
    page: window.location.pathname,
    timestamp: Date.now()
  });
};

// Track scroll depth
let maxScroll = 0;
window.addEventListener('scroll', () => {
  const scrollPercent = Math.round(
    (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100
  );

  if (scrollPercent > maxScroll && scrollPercent % 25 === 0) {
    maxScroll = scrollPercent;
    gtag('event', 'scroll_depth', {
      scroll_depth: scrollPercent,
      page: window.location.pathname
    });
  }
});
Enter fullscreen mode Exit fullscreen mode

2024 SEO Strategy

Key Focus Areas

  1. Core Web Vitals - Direct ranking factor
  2. E-A-T Signals - Expertise, Authority, Trust
  3. User Experience - Bounce rate, dwell time
  4. Mobile-First - Primary indexing method
  5. Voice Search - Natural language optimization

Technical Implementation Priorities

// 1. Performance First
const performanceConfig = {
  LCP: '< 2.5s',
  FID: '< 100ms', 
  CLS: '< 0.1',
  TTI: '< 3.8s'
};

// 2. Structured Data
const requiredSchemas = [
  'Organization',
  'LocalBusiness', 
  'Product',
  'Article',
  'FAQ'
];

// 3. Technical SEO
const technicalChecklist = [
  'XML Sitemap',
  'Robots.txt',
  'SSL Certificate',
  'Mobile Responsive',
  'Page Speed',
  'Internal Linking',
  'Meta Tags',
  'Schema Markup'
];
Enter fullscreen mode Exit fullscreen mode

Conclusion

Technical SEO in 2024 is about:

Performance optimization as a ranking factor

Automation for scale and consistency

User experience metrics matter most

Data-driven decision making

Mobile-first everything

Start with Core Web Vitals, implement proper tracking, and automate what you can measure.


This guide represents 6 years of SEO experience managing 200+ websites with 10M+ organic impressions. What's working for your SEO strategy?

More resources:

Tags: #SEO #TechnicalSEO #WebPerformance #DigitalMarketing #NextJS #GoogleAnalytics

Top comments (0)