Panduan Jekyll SEO

cara mengoptimalkan Jekyll situs untuk search — why -nya static HTML adalah crawler-friendly oleh default, plus jekyll-seo-tag dan jekyll-sitemap plugins, permalinks, collections, robots.txt, dan GitHub halaman plugin whitelist.

Pertama kali diterbitkan: 26 Jun 2026 · Terakhir diperbarui: 3 Agu 2026 · Advanced
Bahasa
1 sinyal bukti di halaman ini

Jekyll outputs flat, static HTML — crawler get complete konten pada pertama fetch, dengan no JavaScript rendering delay. So SEO berfungsi isn't fighting framework; ini adalah configuration. Install jekyll-seo-tag (judul, deskripsi, canonical, Open Graph, Twitter Card, JSON-LD) dan jekyll-sitemap (sitemap.xml), dan set url: di _config.yml atau both produce broken output. Pick clean permalinks (/:judul/, not date-based) untuk evergreen konten. buat robots.txt yourself — Jekyll won't. Watch two GitHub halaman traps: plugin whitelist (hanya sebuah fixed set runs without sebuah GitHub tindakan bangun) dan baseurl misconfiguration pada project situs, which breaks setiap canonical URL.

TL;DR — Jekyll emits flat static HTML di bangun time, so konten adalah di raw respons pada pertama crawl — no Web rendering Service, no Wave 2 delay. SEO berfungsi adalah configuration, not architecture. Install jekyll-seo-tag (judul, deskripsi, canonical, OG, Twitter Card, JSON-LD) dan jekyll-sitemap (sitemap.xml); both memerlukan url: di _config.yml atau mereka produce broken output. gunakan clean permalinks (/:title/) di atas date-based ones untuk evergreen konten. Two GitHub halaman traps dominate: plugin whitelist (GitHub membangun dengan --safe; non-whitelisted plugins perlu sebuah GitHub tindakan bangun) dan sebuah missing baseurl pada project situs, which breaks setiap generated canonical URL. GitHub halaman juga pins spesifik plugin versi (3.10.0 core, older jekyll-seo-tag/jekyll-sitemap releases), not hanya which plugins run. Collections perlu output: true atau mereka’re tidak pernah rendered. Drafts, future-dated posts, dan published: false documents adalah excluded dari sebuah normal bangun, dan --incremental adalah experimental — don’t gunakan ini untuk production deploys. dan robots.txt adalah not auto-generated — membuat ini yourself.

Why Jekyll’s static output adalah baik untuk SEO

Jekyll adalah sebuah static situs generator: ini runs Anda Markdown dan Liquid templates melalui sebuah bangun langkah dan emits finished HTML, once, sebelum apa pun permintaan. itu timing adalah whole SEO advantage. Evidence for this claim Jekyll processes text and templates into static files during a build. Scope: Jekyll build architecture. Confidence: high · Verified: Jekyll documentation

Google’s pipeline adalah crawl → render → indeks, dan rendering JavaScript adalah “a separate step” (terjemahan) “sebuah separate langkah” itu sits di sebuah queue — what people loosely panggil “two-wave” (terjemahan) “two-wave” process. Wave 1 fetches raw HTML dan indeks text dan tautan immediately; Wave 2 queues halaman untuk Web rendering Service untuk run JavaScript, “a few seconds to weeks” (terjemahan) “sebuah few seconds untuk weeks” later depending pada anggaran crawling. dengan Jekyll, Wave 1 sudah berisi semua Anda konten — there’s no JavaScript diperlukan untuk render body. Wave 1 = Wave 2. No rendering delay, no rendering budget spent. ini adalah yang sama argument itu membuat apa pun static situs generator lowest-risk architecture untuk indexability.

downstream benefits ikuti:

  • Faster TTFB. Pre-dibangun files disajikan dari sebuah CDN (GitHub halaman sits behind Fastly; Netlify/Vercel memiliki mereka own edges) berarti no database kueri dan no server processing — baik untuk LCP dan rest dari Core Web Vitals.
  • No diperlukan JS payload untuk konten → better FCP dan LCP daripada sebuah hydrating SPA.
  • Proper HTTP kode status di CDN layer, not client-side error handling.

tetapi none dari itu perubahan fundamentals: static situs masih perlu meta tags, sitemaps, canonical URLs, data terstruktur, dan baik konten. Jekyll’s output adalah crawler-friendly; metadata adalah pada Anda.

GitHub halaman dan Jekyll SEO

paling umum Jekyll deployment adalah GitHub halaman — push untuk sebuah branch dengan halaman enabled dan GitHub auto-membangun situs. itu convenience comes dengan SEO-relevant constraints.

Project situs vs. pengguna/org situs — URL decision

  • username.github.io/repo-name (sebuah project situs) lives pada sebuah shared subdomain dengan thousands dari lainnya unrelated situs. ini berfungsi fine untuk docs, demos, dan personal projects where URL itself doesn’t perlu untuk carry Anda brand.
  • sebuah custom domain (poin sebuah CNAME di GitHub halaman) puts situs pada sebuah URL Anda control, dengan HTTPS auto-provisioned oleh GitHub. untuk sebuah situs where domain itself penting — sebuah business situs, sebuah blog Anda’re membangun sebuah audience sekitar — sebuah custom domain dari start menghindari sebuah domain migration later.

jika Anda expect untuk move untuk sebuah custom domain eventually, set ini up early. apa pun domain migration berarti 301 redirects (jekyll-redirect-from handles ini) dan sebuah period where inbound tautan dan apa pun accumulated signals poin di old URL — avoidable churn jika Anda pick akhir domain up front alih-alih switching later. ini adalah sebuah migration-planning argument, not sebuah claim itu sebuah github.io subdomain adalah penalized pada -nya own.

baseurl — #1 canonical bug pada project situs

Project situs live di bawah sebuah subfolder (/repo-name/). jika Anda tidak set baseurl: /repo-name di _config.yml, setiap canonical URL jekyll-seo-tag generates — dan Anda tautan internal — akan menjadi wrong, missing subfolder. ini adalah single sebagian besar umum canonical-URL bug pada Jekyll project situs. (pengguna/org situs disajikan di domain root don’t perlu baseurl.)

plugin whitelist

GitHub halaman runs Jekyll dengan --safe flag dan hanya allows sebuah fixed set dari plugins. Evidence for this claim GitHub Pages builds Jekyll in safe mode and supports a documented set of plugins. Scope: GitHub Pages hosted builds. Confidence: high · Verified: GitHub Pages: Jekyll plugins SEO-relevant whitelisted ones:

  • jekyll-seo-tag
  • jekyll-sitemap
  • jekyll-redirect-from ✓ (untuk 301s when Anda perubahan URLs)
  • jekyll-paginate

Not whitelisted (dan silently won’t run, atau akan error):

  • jekyll-last-modified-at — needed untuk accurate sitemap <lastmod> dari file timestamps
  • Custom structured-data plugins
  • Anything dropped di sebuah _plugins/ folder

ini adalah not hanya which plugins — ini adalah which versi

GitHub halaman doesn’t hanya restrict which plugins run; ini pins exact versi dari setiap one, dan itu bangun environment itself adalah pinned untuk sebuah older Jekyll. sebagai dari dependency list’s last update, hosted bangun runs Jekyll 3.10.0 dengan jekyll-seo-tag 2.8.0, jekyll-sitemap 1.4.0, dan jekyll-feed 0.17.0 — while jekyllrb.com’s own docs describe saat ini upstream release, 4.4.1. sebuah perilaku documented di sebuah plugin’s latest README isn’t guaranteed untuk exist di versi GitHub halaman actually runs; periksa pages.github.com/versions.json untuk pinned versi sebelum relying pada sebuah spesifik flag atau output. sebuah GitHub tindakan bangun sidesteps ini too — Anda control Gemfile, so Anda get versi Anda pin, not GitHub’s.

GitHub tindakan workaround

fix untuk whitelist isn’t “add more gems” (terjemahan) “tambahkan more gems” — ini adalah untuk stop letting GitHub melakukan bangun. Run Jekyll yourself di CI (actions/jekyll-build-pages, atau bangun locally dan push _site/ untuk deploy branch dengan peaceiris/actions-gh-pages) dan whitelist no longer applies. Now apa pun plugin runs, dan Anda pick Jekyll dan plugin versi alih-alih inheriting GitHub’s pinned set.

jekyll-seo-tag plugin

ini adalah official, maintained plugin itu covers sebagian besar dari core metadata Jekyll doesn’t tambahkan pada -nya own. Exactly what ini emits depends pada which versi Anda memiliki installed, Anda _config.yml dan front penting, dan whether Anda layout actually panggilan {% seo %} — GitHub halaman, misalnya, pins sebuah spesifik versi alih-alih selalu shipping latest release (more pada itu below). periksa advanced usage guide untuk Anda versi’s exact output, dan confirm what actually landed oleh grepping Anda own dibangun HTML alih-alih assuming ini adalah complete.

Install:

# Gemfile
gem 'jekyll-seo-tag'
# _config.yml
plugins:
  - jekyll-seo-tag
<!-- _layouts/default.html, before </head> -->
{% seo %}

What ini generates automatically:

  • <title> — halaman judul dengan situs name appended (Page Title | Site Name)
  • <meta name="description"> — dari description: front penting atau situs deskripsi
  • <link rel="canonical"> — dibangun dari site.url + page.url
  • Open Graph tags (og:title, og:description, og:url, og:site_name, og:image)
  • Twitter Card tags (twitter:card, twitter:title, twitter:description, twitter:creator, twitter:image)
  • JSON-LD data terstruktur (BlogPosting untuk posts, WebSite untuk home halaman)
  • Pagination meta (next/prev URLs)

diperlukan _config.yml settings — without ini plugin produces broken output:

title: Your Site Title
description: Your site description
url: "https://yourdomain.com"   # CRITICAL — drives canonical URL generation
author:
  name: Patrick Stox
  twitter: patrickstox
  url: https://patrickstox.com  # author disambiguation
twitter:
  username: patrickstox
  card: summary_large_image

Per-halaman front penting overrides:

---
title: "Jekyll SEO Guide"
description: "How to optimize Jekyll sites for search engines."
image:
  path: /assets/jekyll-seo-og.png
  width: 1200
  height: 630
  alt: "Jekyll SEO diagram"
canonical_url: "https://example.com/jekyll-seo/"  # override if needed
robots: noindex   # per-page noindex
seo:
  type: BlogPosting          # schema.org type override
  date_modified: 2025-01-15  # dateModified override for JSON-LD
---

Suppression (when Anda layout sudah outputs -nya own):

{% seo title=false %}      <!-- suppress the <title> -->
{% seo canonical=false %}  <!-- suppress the canonical link -->

One gotcha worth flagging: banyak minimal themes (including minima) ship without jekyll-seo-tag wired di. menambahkan gem untuk Anda Gemfile melakukan nothing unless theme’s layout actually panggilan {% seo %}.

Sitemaps dengan jekyll-sitemap

sama install pattern (Gemfile + _config.yml). ini generates sebuah sitemaps.org- compliant sitemap.xml di /sitemap.xml pada setiap bangun.

ini memerlukan url: di _config.yml — without ini, sitemap entries memiliki no domain.

Controlling <lastmod>, di priority order:

  1. last_modified_at: di front penting (best — explicit control)
  2. Post creation date (fallback — sering wrong untuk evergreen konten updated later)
  3. Filesystem modification date (perlu non-whitelisted jekyll-last-modified-at)

Best practice: tambahkan last_modified_at: YYYY-MM-DD untuk setiap post, dan bump ini when Anda update konten — itu’s freshness signal recrawl prioritization leans pada.

Excluding halaman:

# Per-page front matter
sitemap: false

# Global pattern (in _config.yml)
defaults:
  - scope:
      path: "assets/**/*.pdf"
    values:
      sitemap: false

Permalinks adalah set globally di _config.yml atau overridden per halaman di front penting.

StylePatternSEO notes
date (default)/:categories/:year/:month/:day/:title.htmlDate-heavy, fragile jika post date perubahan
pretty/:categories/:year/:month/:day/:title/Trailing slash, no .html
none/:categories/:title.htmlNo date burial
Custom/:title/ atau /:categories/:title/sebagian besar control — recommended untuk evergreen konten

Recommended untuk sebagian besar situs:

permalink: /:title/
# or
permalink: /:categories/:title/

Why hindari date-based URLs untuk evergreen posts:

  • Changing sebuah post’s date: front penting perubahan -nya URL → inbound tautan break.
  • Deep hierarchy (/2019/03/14/post-title/) buries konten untuk no alasan.
  • (untuk news dan journalism, date URLs adalah fine dan expected — ini adalah sebuah per-context panggil, not sebuah universal aturan.)

Collections perlu mereka own permalink config:

collections:
  case_studies:
    output: true
    permalink: /case-studies/:name/

sebuah warning pada changing patterns: once URLs adalah terindeks, switching permalink styles memerlukan 301 redirects (gunakan jekyll-redirect-from). Skip redirects dan Anda break tautan equity dan generate 404s di Search Console.

Collections dan SEO

Collections adalah Jekyll’s custom konten jenis beyond posts dan halaman — docs bagian, portfolio items, team members, case studies, FAQs. Two requirements membuat atau break mereka SEO:

  1. output: true harus menjadi set. Without ini, collection documents adalah tidak pernah rendered sebagai individual HTML files dan therefore dapat’t menjadi terindeks. ini adalah sebuah silent pengindeksan killer — konten exists di Anda repo tetapi tidak pernah becomes sebuah dapat di-crawl halaman.

    collections:
      docs:
        output: true          # REQUIRED for indexable pages
        permalink: /docs/:name/
  2. setiap document perlu front penting — bahkan sebuah empty --- block. Without ini, Jekyll treats file sebagai sebuah binary static file: no Liquid processing, no metadata, no jekyll-seo-tag integration.

Note itu collections aren’t disertakan di RSS feeds (hanya posts adalah). untuk besar documentation situs, collections adalah biasanya right structure anyway.

Publishing states dan incremental membangun

Jekyll memiliki several independent switches itu control what actually ends up di dibangun situs. Mixing them up produces either halaman itu silently tidak pernah get dibangun, atau draft/future konten itu ships untuk production oleh accident:

  • Drafts (_drafts/) adalah excluded dari sebuah normal bangun entirely. mereka hanya appear when Anda run bundle exec jekyll serve --drafts (atau build --drafts) locally — moving sebuah post ke _posts/ dengan sebuah nyata date adalah what actually publishes ini.
  • Future-dated posts (sebuah date: later daripada saat ini time) adalah excluded oleh default. future: true di _config.yml, atau --future flag, mencakup them — handy untuk local preview, tetapi leaving ini pada di sebuah production config berarti scheduled posts go live moment Anda bangun, not pada mereka intended date.
  • published: false di front penting excludes sebuah document dari bangun regardless dari -nya date — sebuah separate switch dari drafts dan future posts, dan easy untuk leave set setelah testing sebuah halaman Anda dimaksudkan untuk ship.
  • Incremental regeneration (--incremental) adalah documented oleh Jekyll sebagai experimental, dan ini tracks sebuah limited dependency graph — mainly mencakup dan layouts. sebuah halaman itu iterates site.posts atau lainnya collection data (sebuah tag indeks, sebuah archive, related-posts logic) dapat go stale di bawah --incremental without Jekyll detecting itu underlying posts changed. Don’t run ini sebagai bagian dari sebuah production deploy; gunakan full bundle exec jekyll build untuk anything Anda’re pushing live.

sebelum trusting apa pun dari ini, bangun without flags Anda gunakan locally (--drafts, --future, --incremental) dan confirm output di _site/ matches what Anda intend untuk publish — safest default untuk sebuah deploy pipeline adalah sebuah clean, full, non-incremental bangun.

Custom head partials dengan Liquid

When jekyll-seo-tag isn’t enough, Anda bangun Anda own _includes/head.html:

<head>
  <meta charset="UTF-8">
  <title>
    {% if page.title %}{{ page.title }} | {{ site.title }}
    {% else %}{{ site.title }}{% endif %}
  </title>
  <meta name="description" content="
    {%- if page.description -%}{{ page.description }}
    {%- elsif page.excerpt -%}{{ page.excerpt | strip_html | strip_newlines }}
    {%- else -%}{{ site.description }}
    {%- endif -%}">
  <link rel="canonical" href="{{ page.url | prepend: site.url }}">
  {% seo %}
</head>

Key Liquid filters untuk SEO:

  • | strip_html — menghapus tags dari sebuah auto-excerpt (essential untuk clean deskripsi)
  • | strip_newlines — menghapus line breaks dari excerpts
  • | truncate: 160 — sebuah optional template-side character cap, not sebuah Google limit. Prefer sebuah authored, halaman-spesifik deskripsi dan preview rendered snippet; fit varies oleh kueri, device, language, dan script.
  • | prepend: site.url — membangun absolute URLs untuk canonical dan OG tags
  • | date_to_xmlschema — ISO 8601 dates untuk JSON-LD datePublished/dateModified
  • | default: fallback — fallback when sebuah variable adalah nil

Custom JSON-LD beyond what jekyll-seo-tag emits:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": {{ page.title | jsonify }},
  "datePublished": "{{ page.date | date_to_xmlschema }}",
  "dateModified": "{{ page.last_modified_at | default: page.date | date_to_xmlschema }}",
  "author": {
    "@type": "Person",
    "name": "{{ page.author.name | default: site.author.name }}",
    "url": "{{ page.author.url | default: site.author.url }}"
  }
}
</script>

robots.txt adalah not auto-generated

Jekyll melakukan not buat robots.txt. Anda membuat ini yourself di situs root. sertakan sebuah empty front-penting block so Liquid processes file (so {{ site.url }} resolves):

---
---
User-agent: *
Allow: /

Sitemap: {{ site.url }}/sitemap.xml

Without ini, there’s no sitemap reference di robots.txt — dan beberapa crawler gunakan itu sebagai sebuah penemuan mechanism. (robots.txt controls crawling, not pengindeksan — untuk full picture see crawling.)

umum Jekyll SEO myths

“Jekyll handles SEO automatically.” (terjemahan) “Jekyll handles SEO automatically.” static output adalah crawler-friendly, tetapi metadata memerlukan explicit setup. Default themes sering ship dengan no SEO tags di semua.

“GitHub Pages is fine for SEO — it’s free.” (terjemahan) “GitHub halaman adalah fine untuk SEO — ini adalah free.” GitHub halaman itself adalah fine — static output adalah crawler-friendly regardless dari host. catches adalah plugin whitelist (dan spesifik versi ini pins, not hanya which plugins) dan, jika Anda brand depends pada URL, deciding pada sebuah custom domain sebelum Anda bangun sebuah audience pada github.io.

“Static sites don’t need sitemaps.” (terjemahan) “Static situs don’t perlu sitemaps.” Google dapat temukan halaman via tautan, tetapi sebuah sitemap speeds penemuan dan carries <lastmod> signals. jekyll-sitemap membuat ini trivial.

“Jekyll is dead.” (terjemahan) “Jekyll adalah dead.” ini adalah di mature maintenance mode — v4.4,1 shipped di January 2025. Minimal baru fitur, tetapi maintained dan secure, dan GitHub halaman akan mendukung ini indefinitely. untuk sederhana blogs dan docs, ini adalah sebuah solid, boring choice.

“I can use any plugin on GitHub Pages.” (terjemahan) “I dapat gunakan apa pun plugin pada GitHub halaman.” No — --safe plus sebuah fixed whitelist. fix adalah GitHub tindakan, not more gems.

Where ini fits

Jekyll adalah one dari six generators di static situs generators cluster — GitHub halaman default dan one sebagian besar developers meet pertama. untuk broader context pada how Google renders JavaScript dan when Anda actually perlu ini, see JavaScript SEO hub. bangun-freshness discipline itu applies untuk setiap SSG — sebuah static situs adalah hanya sebagai saat ini sebagai -nya last bangun — applies untuk Jekyll too: edits don’t reach mesin pencari until Anda rebuild dan redeploy.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.