SEO w 11ty - kompletny przewodnik techniczny z wdrożeniem produkcyjnym
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.
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:
- Odwiedzają stronę i pobierają jej kod źródłowy
- Analizują strukturę HTML, CSS i JavaScript
- Ekstrahują treść, metadane i relacje między stronami
- Przechowują dane w indeksie wyszukiwarki
- 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
.njkzpermalinkgenerują 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:
descriptionwpł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>
Breadcrumbs z mikrodanymi
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
altdla 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.