seo & crawlers

6/20/20253 min read

seo & crawlers

seo = getting found on google. matters for organic traffic, credibility, and long-term roi.

how google works

three stages:

1. crawling (discovery)

googlebot finds pages by:

  • following links from known pages
  • reading sitemaps
  • previous crawl data

crawl rate depends on:

  • site speed
  • authority
  • internal linking
  • content freshness

2. indexing

google analyzes and stores content:

  • reads text, images, videos
  • determines topics
  • checks quality & uniqueness
  • processes structured data

3. ranking

algorithm sorts indexed pages by:

  • relevance
  • page speed
  • mobile-friendliness
  • user experience
  • backlinks
  • E-A-T signals

E-A-T (expertise, authoritativeness, trustworthiness)

critical for ranking, especially YMYL content (health, finance, safety).

expertise: show you know your stuff

  • deep, researched content
  • author bios with credentials
  • cite sources
  • use proper terminology

authoritativeness: be the go-to source

  • earn quality backlinks
  • get mentioned by industry sites
  • strong social presence
  • contribute to publications

trustworthiness: be reliable

  • use HTTPS
  • clear privacy policy
  • show contact info
  • include reviews/testimonials
  • keep info accurate

technical SEO basics

  • logical URL structure
  • clean internal linking
  • XML sitemaps
  • fast page speed
  • mobile-first design
  • core web vitals (LCP, FID, CLS)

SEO in next.js

meta tags

import Head from 'next/head';

function SEOHead({ title, description, canonicalUrl, ogImage }) {
  return (
    <Head>
      <title>{title}</title>
      <meta name="description" content={description} />

      {/* open graph */}
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={ogImage} />

      {/* twitter */}
      <meta name="twitter:card" content="summary_large_image" />

      {/* canonical */}
      <link rel="canonical" href={canonicalUrl} />
    </Head>
  );
}

structured data

export default function BlogPost({ post }) {
  const structuredData = {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "headline": post.title,
    "author": {
      "@type": "Person",
      "name": post.author
    },
    "datePublished": post.date,
  };

  return (
    <>
      <Head>
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
        />
      </Head>
      <article>{post.content}</article>
    </>
  );
}

sitemap

// pages/api/sitemap.xml.js
export default async function handler(req, res) {
  const posts = await getPosts();

  const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      <url>
        <loc>https://yoursite.com</loc>
        <lastmod>${new Date().toISOString()}</lastmod>
        <priority>1.0</priority>
      </url>
      ${posts.map(post => `
        <url>
          <loc>https://yoursite.com/blog/${post.slug}</loc>
          <lastmod>${post.date}</lastmod>
          <priority>0.8</priority>
        </url>
      `).join('')}
    </urlset>`;

  res.setHeader('Content-Type', 'text/xml');
  res.write(sitemap);
  res.end();
}

robots.txt

// pages/api/robots.txt.js
export default function handler(req, res) {
  res.setHeader('Content-Type', 'text/plain');
  res.write(`User-agent: *
Allow: /
Sitemap: https://yoursite.com/api/sitemap.xml`);
  res.end();
}

image optimization

import Image from 'next/image';

// automatic optimization
<Image
  src="/hero.jpg"
  alt="descriptive alt text"
  width={1200}
  height={630}
  priority // for above-fold images
/>

SEO in node.js/express

meta tags middleware

app.get('/blog/:slug', async (req, res) => {
  const post = await getPost(req.params.slug);

  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>${post.title}</title>
        <meta name="description" content="${post.excerpt}" />
        <meta property="og:title" content="${post.title}" />
        <meta property="og:image" content="${post.image}" />
      </head>
      <body>${post.content}</body>
    </html>
  `);
});

compression

const compression = require('compression');
app.use(compression());

caching

app.get('/api/data', (req, res) => {
  res.set('Cache-Control', 'public, max-age=3600');
  res.json(data);
});

core web vitals optimization

LCP (largest contentful paint) - < 2.5s

  • optimize images
  • preload key resources
  • minimize CSS/JS
  • use CDN
// preload critical resources
<Head>
  <link rel="preload" href="/hero.jpg" as="image" />
  <link rel="preload" href="/fonts/main.woff2" as="font" crossOrigin />
</Head>

FID (first input delay) - < 100ms

  • minimize JS
  • code splitting
  • defer non-critical JS
// dynamic imports
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>loading...</p>,
});

CLS (cumulative layout shift) - < 0.1

  • set image dimensions
  • reserve space for ads
  • avoid inserting content above existing content

monitoring

# lighthouse
npm install -g lighthouse
lighthouse https://yoursite.com --view

# core web vitals
npm install web-vitals
import { getCLS, getFID, getLCP } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getLCP(console.log);

quick wins

  • add meta descriptions to all pages
  • create XML sitemap
  • implement structured data
  • optimize images
  • enable compression
  • set up HTTPS
  • fix broken links
  • improve mobile experience
  • reduce page load time
  • create quality content regularly

common mistakes

  • duplicate content
  • slow loading times
  • poor mobile experience
  • missing meta descriptions
  • broken internal links
  • no sitemap
  • ignoring analytics
  • keyword stuffing
  • thin content
  • no HTTPS