SEO (Search Engine Optimization) to proces systematycznego dostosowywania strony internetowej do wymagań algorytmów wyszukiwarek. W kontekście statycznych generatorów stron, takich jak Eleventy (11ty), uzyskujemy unikalną przewagę: pełną kontrolę nad generowanym kodem HTML bez narzutu frameworków JavaScriptowych.

Ten artykuł to kompletny przewodnik techniczny, który przeprowadzi Cię przez proces budowy bloga zoptymalizowanego pod kątem wyszukiwarek — od fundamentów architektonicznych po zaawansowane techniki implementacji.

Dlaczego statyczna architektura ma znaczenie dla SEO?

Przed przystąpieniem do implementacji, zrozummy fundamentalną przewagę architektury statycznej:

Mechanizm działania algorytmów wyszukiwarek

Wyszukiwarki internetowe, przede wszystkim Google, funkcjonują w oparciu o crawling (przeglądanie stron) i indexing (indeksowanie treści). Proces ten realizowany jest przez automatyczne roboty (boty/crawlery), które:

  1. Odwiedzają stronę i pobierają jej kod źródłowy
  2. Analizują strukturę HTML, CSS i JavaScript
  3. Ekstrahują treść, metadane i relacje między stronami
  4. Przechowują dane w indeksie wyszukiwarki
  5. Klasyfikują stronę pod kątem zapytań użytkowników

Problemy z CSR (Client-Side Rendering)

Tradycyjne aplikacje SPA (Single Page Application), takie jak te zbudowane na React, Vue czy Angular, generują treść dynamicznie w przeglądarce użytkownika. To stwarza fundamentalne wyzwanie:

  • Bot może otrzymać pusty lub częściowy HTML
  • Wymagane jest renderowanie JavaScriptu (JavaScript Rendering), które zużywa zasoby Googlebot
  • Opóźnienia w indeksowaniu nowych treści
  • Potencjalne błędy przy skomplikowanym kodzie JS

Przewaga SSG (Static Site Generation)

Eleventy generuje czysty, statyczny HTML w fazie builda:

Aspekt Aplikacja SPA Strona statyczna (11ty)
Czas do pierwszego bajta (TTFB) Średni-wysoki (serwer + render) Minimalny (CDN)
Widoczność dla crawlera Wymaga JS Pełna treść w HTML
Zużycie zasobów Google Wysokie (rendering JS) Minimalne
Szybkość indeksowania Opóźniona Natychmiastowa
Core Web Vitals Wymagają optymalizacji Optymalne domyślnie

Architektura informacji i struktura projektu

Zanim przejdziemy do kodu, zaprojektujmy strukturę projektu zoptymalizowaną pod kątem SEO i utrzymania:

src/
├── _data/
│   └── site.json              # Centralna konfiguracja domeny
├── _includes/
│   ├── layouts/
│   │   ├── base.njk           # Layout główny z kompletnym SEO
│   │   └── post.njk           # Layout dla artykułów
│   └── partials/
│       ├── head-seo.njk       # Izolowane komponenty SEO
│       ├── breadcrumbs.njk    # Nawigacja okruszkowa
│       └── schema-org.njk     # Strukturalne dane
├── assets/
│   ├── css/                   # Krytyczne CSS inline, reszta async
│   ├── js/                    # Minimalny JS, defer/async
│   └── images/                # WebP z fallbackiem
├── posts/                     # Treść: frontmatter + markdown
│   └── [slug]/
│       └── index.md           # Wpis z własnym folderem na obrazy
├── sitemap.xml.njk            # Dynamiczna mapa witryny
├── robots.txt.njk             # Instrukcje dla robotów
├── manifest.json.njk          # PWA i ikony systemowe
├── feed.xml.njk               # Atom/RSS dla subskrypcji
└── opensearch.xml.njk         # Wyszukiwarka w pasku adresu

Dlaczego ten układ jest optymalny?

  • Separacja odpowiedzialności: SEO w osobnych partials, łatwe do modyfikacji
  • Organizacja treści: Każdy wpis w osobnym folderze ułatwia zarządzanie zasobami
  • Automatyzacja: Pliki .njk z permalink generują pliki statyczne automatycznie
  • Skalowalność: Struktura działa dla 10, 100 i 1000 wpisów

1. System zarządzania metadanymi

Fundamentalne znaczenie meta tagów

Meta tagi to dane o danych — informacje, które nie są widoczne bezpośrednio na stronie, ale są fundamentalne dla:

  • Wyszukiwarek: description wpływa na CTR (Click-Through Rate) w SERP
  • Mediów społecznościowych: Open Graph kontroluje wygląd udostępnień
  • Platform wiadomości: Twitter Cards, LinkedIn rich previews
  • Przeglądarek: viewport, theme-color, canonical

Implementacja systemu zmiennych SEO

W pliku src/_includes/layouts/base.njk implementujemy hierarchiczną logikę metadanych:

<!DOCTYPE html>
<html lang="pl" dir="ltr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  
  
  <title>SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym | koryto.net</title>
  
  
  <meta name="description" content="Profesjonalny przewodnik po optymalizacji SEO dla statycznych stron generowanych przez Eleventy. Od fundamentów po zaawansowane techniki strukturalnych...">
  <meta name="keywords" content="posts, 11ty, seo, tutorial, optymalizacja">
  <meta name="author" content="">
  <meta name="copyright" content="">
  <meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
  
  
  <link rel="canonical" href="https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/">
  
  
  <link rel="alternate" hreflang="pl" href="https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/">
  <link rel="alternate" hreflang="x-default" href="https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/">
  
  
  <meta property="og:site_name" content="koryto.net">
  <meta property="og:title" content="SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym">
  <meta property="og:description" content="Profesjonalny przewodnik po optymalizacji SEO dla statycznych stron generowanych przez Eleventy. Od fundamentów po zaawansowane techniki strukturalnych...">
  <meta property="og:type" content="article">
  <meta property="og:url" content="https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/">
  <meta property="og:image" content="https://koryto.net/assets/images/og-default.png">
  <meta property="og:image:width" content="1200">
  <meta property="og:image:height" content="630">
  <meta property="og:image:alt" content="SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym">
  <meta property="og:locale" content="pl_PL">
  
  
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="">
  <meta name="twitter:creator" content="">
  <meta name="twitter:title" content="SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym">
  <meta name="twitter:description" content="Profesjonalny przewodnik po optymalizacji SEO dla statycznych stron generowanych przez Eleventy. Od fundamentów po zaawansowane techniki strukturalnych...">
  <meta name="twitter:image" content="https://koryto.net/assets/images/og-default.png">
  
  
  <link rel="manifest" href="/manifest.json">
  <meta name="theme-color" content="#6366f1">
  <link rel="apple-touch-icon" href="/assets/icons/apple-touch-icon.png">
</head>
<body>
  
</body>
</html>

Konfiguracja globalna (site.json)

Plik src/_data/site.json stanowi centralne źródło prawdy:

{
  "title": "koryto.net",
  "tagline": "Blog o technologii, programowaniu i architekturze oprogramowania",
  "description": "Praktyczne artykuły o web development, JavaScript, Node.js i optymalizacji wydajności. Od fundamentów po zaawansowane wzorce projektowe.",
  "url": "https://dkoryto.github.io/koryto_net",
  "buildDate": "2026-03-30",
  "defaultKeywords": "blog, technologia, programowanie, web development, javascript",
  "author": {
    "name": "Dariusz Koryto",
    "email": "[email protected]",
    "jobTitle": "Software Engineer",
    "url": "https://github.com/dkoryto"
  },
  "social": {
    "twitter": "@dkoryto",
    "github": "https://github.com/dkoryto",
    "linkedin": "https://linkedin.com/in/dkoryto"
  },
  "organization": {
    "name": "koryto.net",
    "logo": "https://dkoryto.github.io/koryto_net/assets/images/logo.png"
  }
}

Dlaczego te metadane są kluczowe?

Meta Description (155-160 znaków) Nie wpływa bezpośrednio na ranking, ale fundamentalnie na CTR. Dobrze napisany opis może zwiększyć klikalność o 5-15%.

Canonical URL Eliminuje problem duplikatów treści (duplicate content), który może rozpraszać "moc SEO" między wieloma URL-ami tej samej treści.

Open Graph Image (1200×630px) To standardowy format dla Facebooka, LinkedIn i innych platform. Obrazy z tekstem nakładanym zwiększają zaangażowanie o 30-80%.

2. Strukturalne dane Schema.org (JSON-LD)

Czym są strukturalne dane?

Strukturalne dane to ustandaryzowany format (JSON-LD) opisu zawartości strony, który pozwala wyszukiwarkom nie tylko indeksować treść, ale rozumieć jej znaczenie semantyczne. n Implementacja strukturalnych danych umożliwia:

  • Rich Snippets — rozszerzone wyniki wyszukiwania (gwiazdki, ceny, daty)
  • Knowledge Graph — panel wiedzy z boku wyników wyszukiwania
  • Voice Search Optimization — odpowiedzi asystentów głosowych
  • Breadcrumbs w SERP — ścieżka nawigacyjna pod wynikiem

Implementacja dla artykułów (BlogPosting)

W pliku src/_includes/partials/schema-org.njk:


<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/"
  },
  "headline": "SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym",
  "description": "Profesjonalny przewodnik po optymalizacji SEO dla statycznych stron generowanych przez Eleventy. Od fundamentów po zaawansowane techniki strukturalnych danych, Core Web Vitals i architektury informacji.",
  "image": {
    "@type": "ImageObject",
    "url": "https://koryto.net/assets/images/og-default.png",
    "width": 1200,
    "height": 630
  },
  "author": {
    "@type": "Person",
    "name": "",
    "url": "",
    "jobTitle": ""
  },
  "publisher": {
    "@type": "Organization",
    "name": "",
    "logo": {
      "@type": "ImageObject",
      "url": "",
      "width": 600,
      "height": 60
    }
  },
  "datePublished": "2026-03-30T00:00:00.000Z",
  "dateModified": "2026-03-30T00:00:00.000Z",
  "keywords": "posts, 11ty, seo, tutorial, optymalizacja",
  "articleSection": "posts",
  "inLanguage": "pl-PL",
  "isAccessibleForFree": true
}
</script>

Struktura WebSite z akcją wyszukiwania

Implementacja "Sitelinks Searchbox" — wyszukiwarki bezpośrednio w wynikach Google:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "koryto.net",
  "description": "Blog o technologii, programowaniu i projektach",
  "url": "https://koryto.net",
  "publisher": {
    "@type": "Organization",
    "name": "",
    "logo": ""
  },
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://koryto.net/search/?q={search_term_string}"
    },
    "query-input": "required name=search_term_string"
  },
  "inLanguage": "pl-PL"
}
</script>

Nawigacja okruszkowa (breadcrumbs) poprawia UX i pozwala Google wyświetlić ścieżkę w wynikach wyszukiwania:




  
  



<nav aria-label="Nawigacja okruszkowa">
  <ol itemscope itemtype="https://schema.org/BreadcrumbList">
    
    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      
        <a href="/" itemprop="item">
          <span itemprop="name">Strona główna</span>
        </a>
      
      <meta itemprop="position" content="1">
    </li>
    
    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      
        <a href="/blog/" itemprop="item">
          <span itemprop="name">Blog</span>
        </a>
      
      <meta itemprop="position" content="2">
    </li>
    
    <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
      
        <span itemprop="name" aria-current="page">SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym</span>
      
      <meta itemprop="position" content="3">
    </li>
    
  </ol>
</nav>

3. Mapa witryny i instrukcje dla robotów

Protokół Sitemaps

XML Sitemap to plik informujący wyszukiwarki o strukturze witryny. Jest fundamentalny dla:

  • Dużych witryn (>500 stron)
  • Stron z izolowanymi stronami (osierocone)
  • Nowych witryn z małą liczbą linków zwrotnych
  • Stron z treścią multimedialną

Implementacja src/sitemap.xml.njk:

---
permalink: /sitemap.xml
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
  <url>
    <loc>https://koryto.net/posts/jak-stworzylem-bloga/</loc>
    <lastmod>2026-03-28T00:00:00.000Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://koryto.net/posts/jak-dodawac-obrazki/</loc>
    <lastmod>2026-03-29T00:00:00.000Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://koryto.net/posts/pierwszy-wpis/</loc>
    <lastmod>2026-03-29T00:00:00.000Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/</loc>
    <lastmod>2026-03-30T00:00:00.000Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://koryto.net/archiwum/</loc>
    <lastmod>2026-04-06T16:01:41.313Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/blog/</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/edytor/</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/feed.xml</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>daily</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://koryto.net/llms.txt</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/manifest.json</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/o-mnie/</loc>
    <lastmod>2026-04-06T16:01:41.314Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/robots.txt</loc>
    <lastmod>2026-04-06T16:01:41.316Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/search/</loc>
    <lastmod>2026-04-06T16:01:41.316Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://koryto.net/sitemap.xml</loc>
    <lastmod>2026-04-06T16:01:41.316Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

Robots.txt — protokół wykluczania robotów

Plik src/robots.txt.njk kontroluje dostęp crawlerów:

---
permalink: /robots.txt
layout: null
---
# Protocol: robots.txt
# Documentation: https://www.robotstxt.org/robotstxt.html

User-agent: *
Allow: /

# Optymalizacja crawl budget
Disallow: /tag/
Disallow: /404.html

# Sitemap location
Sitemap: https://koryto.net/sitemap.xml

# Host directive (opcjonalnie, dla Yandex)
Host: koryto.net

Dlaczego wykluczamy /tag/?

Strony tagów często generują thin content (treść niskiej jakości) lub duplikaty. Wykluczenie ich z indeksu:

  • Koncentruje "moc SEO" na wartościowych stronach artykułów
  • Zapobiega kanibalizacji słów kluczowych
  • Optymalizuje crawl budget

4. Wydajność jako czynnik rankingowy (Core Web Vitals)

Od czerwca 2021 Google oficjalnie uwzględnia Core Web Vitals jako czynnik rankingowy. To trzy metryki:

Metryka Cel Mierzy
LCP (Largest Contentful Paint) < 2.5s Czas wyrenderowania największego elementu
FID (First Input Delay) < 100ms Responsywność na pierwszą interakcję
CLS (Cumulative Layout Shift) < 0.1 Stabilność wizualną (przesunięcia layoutu)

Optymalizacja zasobów krytycznych

W sekcji <head> implementujemy hierarchię ładowania:


<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://unpkg.com">


<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://koryto.net" crossorigin>


<link rel="preload" href="/assets/css/critical.css" as="style">
<link rel="preload" href="/assets/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>


<style>
  /* Krytyczne style: layout, typografia, kolory */
  :root{--bg:#0f0f11;--text:#e8e8ec;--font:sans-serif}
  *,*::before,*::after{box-sizing:border-box;margin:0}
  body{font-family:var(--font);background:var(--bg);color:var(--text)}
  /* ... więcej krytycznych stylów ... */
</style>


<link rel="stylesheet" href="/assets/css/main.css" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="/assets/css/main.css"></noscript>

Transformacje HTML dla optymalizacji

W eleventy.config.js dodajemy transformacje:

// Lazy loading dla wszystkich obrazków bez atrybutu loading
eleventyConfig.addTransform("lazyImages", function(content, outputPath) {
  if (!outputPath || !outputPath.endsWith(".html")) return content;
  
  // Dodaj loading="lazy" i decoding="async"
  content = content.replace(
    /<img(?![^>]*loading=)([^>]*)>/gi,
    '<img$1 loading="lazy" decoding="async">'
  );
  
  // Priorytet dla pierwszego obrazka (LCP optimization)
  content = content.replace(
    /<img([^>]*)class="([^"]*hero[^"]*)"([^>]*)>/i,
    '<img$1class="$2"$3 fetchpriority="high" loading="eager">'
  );
  
  return content;
});

// Minifikacja HTML w produkcji
if (process.env.NODE_ENV === 'production') {
  const htmlmin = require("html-minifier");
  eleventyConfig.addTransform("htmlmin", function(content, outputPath) {
    if (!outputPath || !outputPath.endsWith(".html")) return content;
    
    return htmlmin.minify(content, {
      useShortDoctype: true,
      removeComments: true,
      collapseWhitespace: true,
      conservativeCollapse: true,
      minifyCSS: true,
      minifyJS: true,
      removeEmptyAttributes: true,
      removeRedundantAttributes: true
    });
  });
}

Optymalizacja obrazków

Praktyki dla obrazków w treści:

<!-- Format WebP z fallbackiem -->
<picture>
  <source srcset="/assets/images/photo.webp" type="image/webp">
  <img src="/assets/images/photo.jpg" 
       alt="Opisz co widoczne na zdjęciu, nie że to zdjęcie"
       width="800" height="600"
       loading="lazy" 
       decoding="async">
</picture>

<!-- Responsive images dla różnych urządzeń -->
<img srcset="
    /assets/images/photo-400.webp 400w,
    /assets/images/photo-800.webp 800w,
    /assets/images/photo-1200.webp 1200w
  "
  sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
  src="/assets/images/photo-800.webp"
  alt="Deskryptywny opis obrazka">

5. Feeds syndykacji treści (RSS/Atom)

Feed Atom (nowocześniejszy niż RSS 2.0) umożliwia subskrypcję i szybsze indeksowanie nowych wpisów.

---
permalink: /feed.xml
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
  <title>koryto.net</title>
  <subtitle></subtitle>
  <link href="https://koryto.net/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="https://koryto.net/" rel="alternate" type="text/html"/>
  <updated></updated>
  <id>https://koryto.net/</id>
  <author>
    <name></name>
    <uri></uri>
  </author>
  <entry>
    <title>Architektura i implementacja bloga na Eleventy — od koncepcji do deploymentu</title>
    <link href="https://koryto.net/posts/jak-stworzylem-bloga/" rel="alternate" type="text/html"/>
    <published>2026-03-28T00:00:00.000Z</published>
    <updated>2026-03-28T00:00:00.000Z</updated>
    <id>https://koryto.net/posts/jak-stworzylem-bloga/</id>
    <summary type="html">Kompletny przewodnik techniczny budowy nowoczesnego bloga z użyciem Eleventy. Architektura projektu, konfiguracja środowiska, lokalny development i zdalny deployment na GitHub Pages.</summary>
    <category term="posts" />
  </entry>
  <entry>
    <title>Witaj na moim blogu!</title>
    <link href="https://koryto.net/posts/pierwszy-wpis/" rel="alternate" type="text/html"/>
    <published>2026-03-29T00:00:00.000Z</published>
    <updated>2026-03-29T00:00:00.000Z</updated>
    <id>https://koryto.net/posts/pierwszy-wpis/</id>
    <summary type="html">Pierwszy wpis na nowym blogu o technologii i programowaniu</summary>
    <category term="posts" />
  </entry>
  <entry>
    <title>Jak dodawać obrazki do artykułów - przykład</title>
    <link href="https://koryto.net/posts/jak-dodawac-obrazki/" rel="alternate" type="text/html"/>
    <published>2026-03-29T00:00:00.000Z</published>
    <updated>2026-03-29T00:00:00.000Z</updated>
    <id>https://koryto.net/posts/jak-dodawac-obrazki/</id>
    <summary type="html">Praktyczny przykład użycia obrazków w artykułach na blogu. Zobacz jak to działa!</summary>
    <category term="posts" />
  </entry>
  <entry>
    <title>SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym</title>
    <link href="https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/" rel="alternate" type="text/html"/>
    <published>2026-03-30T00:00:00.000Z</published>
    <updated>2026-03-30T00:00:00.000Z</updated>
    <id>https://koryto.net/posts/seo-w-11ty-kompletny-przewodnik/</id>
    <summary type="html">Profesjonalny przewodnik po optymalizacji SEO dla statycznych stron generowanych przez Eleventy. Od fundamentów po zaawansowane techniki strukturalnych danych, Core Web Vitals i architektury informacji.</summary>
    <category term="posts" />
  </entry>
</feed>

6. Architektura URL i linkowanie wewnętrzne

Przyjazne URL-e (slugi)

Implementacja w eleventy.config.js:

eleventyConfig.addFilter("slugify", (input) => {
  const slug = String(input)
    .normalize('NFD')                    // Rozkład polskich znaków
    .replace(/[\u0300-\u036f]/g, '')     // Usuń diakrytyki
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, '')           // Usuń znaki specjalne
    .replace(/[\s_-]+/g, '-')            // Zamień spacje na myślniki
    .replace(/^-+|-+$/g, '');            // Trim myślniki
  
  return slug;
});

Strategia linkowania wewnętrznego

Linkowanie wewnętrzne przekazuje "link juice" i pomaga Google zrozumieć hierarchię treści:

<!-- Link kontekstowy z anchor text opisującym docelową stronę -->
<p>W artykule o <a href="/blog/seo-w-11ty/">optymalizacji SEO dla Eleventy</a> 
dokładnie opisałem proces implementacji strukturalnych danych.</p>

<!-- Unikaj "click here" lub "czytaj więcej" -->
<!-- ❌ Źle: -->
<a href="/blog/seo/">Czytaj więcej →</a>

<!-- ✅ Dobrze: -->
<a href="/blog/seo/">Kompletny przewodnik SEO dla 11ty z przykładami</a>

7. Walidacja i monitoring

Narzędzia do weryfikacji wdrożenia

Po wdrożeniu przetestuj stronę w następujących narzędziach:

Narzędzie URL Co sprawdza
Rich Results Test search.google.com/test/rich-results Poprawność Schema.org
PageSpeed Insights pagespeed.web.dev Core Web Vitals
Mobile-Friendly Test search.google.com/test/mobile-friendly Responsywność
RSS Validator validator.w3.org/feed Poprawność feedu
Schema Markup Validator validator.schema.org Strukturalne dane

Google Search Console — podstawowy monitoring

Dodaj stronę do GSC i monitoruj:

  • Coverage — indeksowanie i błędy
  • Core Web Vitals — raport wydajności
  • Performance — zapytania, CTR, pozycje
  • Enhancements — rich results i breadcrumbs

Checklist produkcyjnego wdrożenia SEO

Przed publikacją zweryfikuj:

Meta i struktura

  • [ ] Unikalny <title> na każdej stronie (50-60 znaków)
  • [ ] Unikalny meta description (150-160 znaków)
  • [ ] Canonical URL poprawnie ustawiony
  • [ ] Open Graph tags dla wszystkich stron
  • [ ] Twitter Cards skonfigurowane

Techniczne SEO

  • [ ] Schema.org JSON-LD dla artykułów
  • [ ] Breadcrumbs z mikrodanymi
  • [ ] XML Sitemap generowany automatycznie
  • [ ] Robots.txt zezwalający na indeksowanie
  • [ ] HTTPS wymuszony
  • [ ] Hreflang dla wersji językowych

Wydajność

  • [ ] LCP < 2.5s (PageSpeed Insights)
  • [ ] CLS < 0.1
  • [ ] Lazy loading obrazków
  • [ ] Minifikacja HTML/CSS/JS
  • [ ] Preload krytycznych zasobów
  • [ ] WebP dla obrazków z fallbackiem

Treść i nawigacja

  • [ ] Jednoznaczna hierarchia H1-H6 (tylko jeden H1)
  • [ ] Atrybuty alt dla wszystkich obrazków
  • [ ] Linkowanie wewnętrzne między powiązanymi artykułami
  • [ ] Przyjazne URL-e ze słowami kluczowymi
  • [ ] Atom/RSS feed działający

Monitoring

  • [ ] Strona dodana do Google Search Console
  • [ ] Sitemap zgłoszony w GSC
  • [ ] Test Rich Results przechodzi bez błędów
  • [ ] Test Mobile-Friendly pozytywny

Implementacja powyższych praktyk zapewnia solidne fundamenty SEO dla bloga opartego na Eleventy. Pamiętaj, że SEO to proces ciągły — regularnie monitoruj wyniki w Google Search Console i iteracyjnie poprawiaj stronę na podstawie zebranych danych.