Jekyll Front Matter: The Complete Guide
Everything you need to know about Jekyll front matter β YAML syntax, built-in variables, custom fields, defaults, and real-world examples for posts, pages, and collections.
Front matter is how Jekyll knows what to do with a file. Without it, Jekyll treats a file as a static asset and copies it unchanged. With it, Jekyll processes the file through its template engine, applies a layout, and builds a page with all the data you specified.
Understanding front matter is foundational to using Jekyll effectively. This guide covers everything from basic syntax to advanced defaults.
What is front matter?
Front matter is a block of YAML at the top of a file, enclosed between triple-dashed lines:
---
layout: post
title: "My First Post"
date: 2026-07-29
---
Content goes here.
The triple dashes are required β both opening and closing. Jekyll strips the front matter block before rendering the content and makes all the variables available in your Liquid templates.
Any file in a Jekyll site that has front matter (even empty front matter ---
---) is processed by Jekyll. Files without front matter are copied as-is.
YAML basics
Front matter uses YAML (YAML Ainβt Markup Language). You only need to know a handful of YAML patterns to write effective front matter.
Strings:
title: "My Post Title"
title: My Post Title # quotes are optional for simple strings
description: "A post about Jekyll front matter β the basics and beyond."
Numbers:
nav_order: 3
weight: 10
Booleans:
published: true
featured: false
toc: true
Lists (arrays):
tags:
- jekyll
- tutorial
- yaml
# Or inline:
tags: [jekyll, tutorial, yaml]
Nested objects:
author:
name: Marcus Webb
email: marcus@example.com
twitter: marcuswebb
Multiline strings:
description: >
This is a long description that spans
multiple lines but will be joined into
a single paragraph.
excerpt: |
This preserves
line breaks
exactly.
Built-in Jekyll front matter variables
Jekyll recognises several variable names and uses them specially:
layout
Specifies which layout file from _layouts/ to use:
layout: post # uses _layouts/post.html
layout: page # uses _layouts/page.html
layout: default # uses _layouts/default.html
layout: none # no layout β render content only
If omitted, Jekyll uses no layout (renders content only). Most files should specify a layout.
title
The page title. Available as {{ page.title }} in templates and used by jekyll-seo-tag for the <title> element:
title: "Jekyll Front Matter: The Complete Guide"
date
For posts in _posts/, the date is normally part of the filename (2026-07-29-my-post.md). You can override or supplement it with a front matter date:
date: 2026-07-29
date: 2026-07-29 14:30:00 +0100 # with time and timezone
The date variable sets page.date, which is used for sorting posts and for display in templates.
published
Controls whether Jekyll includes the page in the build output:
published: false # page is excluded from build
published: true # page is included (default)
Drafts in _drafts/ are automatically excluded unless you run jekyll serve --drafts.
permalink
Overrides Jekyllβs default URL for the page:
permalink: /about/
permalink: /blog/:year/:month/:title/
permalink: /themes/minimal/
Available :placeholders for posts: :year, :month, :day, :title, :categories, :slug.
categories and tags
Categorise and tag your content:
categories: Tutorial
categories:
- Tutorial
- Jekyll
tags: [front-matter, yaml, jekyll]
categories affects the default URL of posts (/tutorial/2026/07/29/my-post/). tags do not affect URLs.
excerpt
By default, Jekyll uses the first paragraph of a post as its excerpt. Override with:
excerpt: "A short custom summary for use in post listings and meta descriptions."
last_modified_at
Used by jekyll-seo-tag and jekyll-sitemap to set the <lastmod> value:
last_modified_at: 2026-06-18
Custom front matter variables
Any variable you add to front matter becomes available in your templates as page.variable_name:
---
layout: post
title: "My Post"
author: Marcus Webb
reading_time: 8
featured_image: /assets/images/hero.webp
show_newsletter: true
difficulty: beginner
---
In your templates:
<p>By {{ page.author }} Β· {{ page.reading_time }} min read</p>
{% if page.featured_image %}
<img src="{{ page.featured_image }}" alt="{{ page.title }}">
{% endif %}
{% if page.show_newsletter %}
{% include newsletter-form.html %}
{% endif %}
This pattern is powerful β you can add any metadata to a page and use it anywhere in your templates without touching layout files.
Front matter in different file types
Posts (_posts/)
---
layout: post
title: "How to Install a Jekyll Theme"
description: "Step-by-step guide to installing any Jekyll theme in under 10 minutes."
date: 2026-07-29
last_modified_at: 2026-06-18
image: /assets/images/blog/install-jekyll-theme.webp
author: Marcus Webb
category: Tutorial
tags: [jekyll, themes, tutorial]
featured: false
toc: true
---
Pages (_pages/ or root)
---
layout: page
title: "About JekyllHub"
description: "The story behind JekyllHub β a marketplace for Jekyll themes."
permalink: /about/
nav_order: 4
---
Collection items (_themes/, _authors/, etc.)
---
layout: theme
title: "Minimal Mistakes"
github_url: https://github.com/mmistakes/minimal-mistakes
stars: 12800
price: 0
category: Blog
tags: [responsive, dark-mode, sidebar]
---
Layouts and includes
Layouts and includes can also have front matter, but it is rarely used. One exception: layout inheritance.
---
layout: default # This layout itself uses another layout
---
Front matter defaults
Repeating the same front matter on every post is tedious. Jekyllβs defaults feature lets you set front matter values globally in _config.yml:
# _config.yml
defaults:
# Default for all posts
- scope:
path: ""
type: posts
values:
layout: post
author: Marcus Webb
toc: true
featured: false
# Default for all pages
- scope:
path: ""
type: pages
values:
layout: page
# Default for a specific directory
- scope:
path: "_themes"
type: themes
values:
layout: theme
# Default for files matching a path pattern
- scope:
path: "guides/**"
values:
layout: guide
show_sidebar: true
With these defaults set, you do not need to specify layout: post or author: Marcus Webb on every post β Jekyll applies them automatically. Front matter in the file still overrides defaults.
Specificity: More specific scopes override less specific ones. A post-level default overrides a site-wide default. Front matter in the file overrides both.
Accessing front matter in templates
All front matter variables are available in Liquid templates:
<!-- In the layout file -->
<h1>{{ page.title }}</h1>
<p>{{ page.description }}</p>
<time>{{ page.date | date: "%B %-d, %Y" }}</time>
<!-- Conditional display -->
{% if page.toc %}
{% include toc.html %}
{% endif %}
<!-- Iteration over arrays -->
{% for tag in page.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
<!-- Nested objects -->
{{ page.author.name }}
{{ page.author.twitter }}
Accessing front matter from other pages
You can loop through all pages or posts and access their front matter:
<!-- List all posts with their metadata -->
{% for post in site.posts %}
<article>
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
<p>{{ post.description }}</p>
{% if post.featured %}
<span class="badge">Featured</span>
{% endif %}
</article>
{% endfor %}
<!-- Filter by front matter value -->
{% assign featured_posts = site.posts | where: "featured", true %}
{% for post in featured_posts %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
Common front matter patterns
Hiding a page from navigation while keeping it live
---
layout: page
title: "Thank You"
permalink: /thank-you/
sitemap: false
---
Overriding the excerpt
---
layout: post
title: "My Post"
excerpt: "This custom excerpt appears in post listings and meta descriptions instead of the first paragraph."
---
Specifying an OG image for social sharing
---
layout: post
title: "My Post"
image: /assets/images/blog/my-post.webp
---
With jekyll-seo-tag, image is automatically used as the Open Graph image.
Controlling the canonical URL
---
layout: post
title: "My Post"
canonical_url: "https://original-source.com/my-post/"
---
Useful if you are syndicating content from another site.
Validating front matter
YAML syntax errors in front matter cause Jekyll build errors. Common mistakes:
Unquoted colons: A colon in a value must be quoted.
# Bad
title: Jekyll: The Complete Guide
# Good
title: "Jekyll: The Complete Guide"
Tab characters: YAML uses spaces, not tabs. Always indent with spaces.
Inconsistent list formatting:
# Bad β mixing inline and block style
tags: [jekyll
tutorial]
# Good
tags: [jekyll, tutorial]
# Or
tags:
- jekyll
- tutorial
Run bundle exec jekyll build --verbose to see detailed error output when front matter parsing fails.
Front matter is the connective tissue of a Jekyll site β it is how content communicates with templates. Mastering it unlocks the full power of Jekyllβs data-driven architecture.
Front matter best practices for scalable Jekyll sites
As your site grows from ten posts to a hundred, consistent front matter becomes increasingly important. Inconsistencies β a tags field that is sometimes a list and sometimes a string, a date field in two different formats, a description field present on half the posts β create template complexity and Liquid errors that are frustrating to debug.
Establish a front matter standard early and document it. A simple FRONT_MATTER.md file in your repository root listing the expected fields, their types, and example values takes ten minutes to write and saves hours of debugging. If you use multiple authors, a shared reference prevents each author from inventing their own front matter conventions.
Use jekyll-data-defaults or _config.yml defaults for fields that should have values across an entire category of pages. The defaults: array in _config.yml lets you set values for all posts in a given path or collection, so you are not duplicating layout: post and author: Your Name in every single front matter block. Defaults are inherited and overridable β a post can always override a sitewide default by including its own value for that field.
Validate your front matter as part of your build process. jekyll-data provides validation hooks, and the strict_front_matter: true config option causes Jekyll to raise an error on any front matter YAML parsing failure rather than silently ignoring it. For sites with multiple contributors, running a pre-commit hook that validates front matter YAML syntax catches errors before they reach the repository.
Keep custom front matter fields flat where possible. Nested YAML is powerful but creates verbose Liquid syntax β page.author.social.twitter is less readable than page.author_twitter. Unless you have a genuine reason for nesting (for example, a structured schema with required sub-fields), flat keys are easier to work with in templates. If you find yourself writing {% assign twitter = page.author.social.twitter %} frequently, it is a signal to flatten the data structure.
Front matter is one of those Jekyll features that rewards spending an afternoon thinking carefully about your data model before you start publishing. The conventions you establish for your first ten posts will shape how you write templates and how you add features for years. Take the time to get them right.
Using front matter with Jekyll collections
Collections β custom content types you define in _config.yml beyond the built-in posts and pages β use front matter identically to posts, but with different conventions depending on the collectionβs purpose. A _projects/ collection might use front matter fields like client, role, technologies, year, and live_url that would be irrelevant on a standard blog post. A _team/ collection might use name, title, department, and photo.
The defaults: array in _config.yml is especially useful for collections, because every document in a collection often needs the same layout and several shared field values. Setting layout: project and category: work as defaults for everything in _projects/ means you omit them from each individual projectβs front matter, reducing repetition and the surface area for inconsistency.
Collection front matter also drives collection-level filtering in Liquid templates. If you want to show only active team members on your team page, add an active: true or active: false field to each team member document and filter with site.team | where: "active", true. This pattern β using a boolean front matter field as a filter in Liquid β is one of the cleanest ways to manage content visibility without deleting files.
Computed and Liquid-derived front matter
Front matter values are static β they are set when you write the file and do not change based on other page data or site variables. But Liquid templates can compute values dynamically at build time from the static front matter, creating the appearance of dynamic behaviour.
A common example: a reading_time calculation. The front matter stores the postβs content length indirectly (through the content itself), and the template computes reading time from content | number_of_words | divided_by: 250. You do not need a reading_time front matter field; the template derives it from the content. This approach keeps front matter focused on data that cannot be derived and lets templates handle computation.
Another example: related posts. A related front matter field listing two or three related post slugs lets your template look up those posts from site.posts and render a related content section. But you could also compute related posts in Liquid by finding posts that share a tag with the current post β no front matter required. The manual approach (explicit related: list) produces better recommendations; the computed approach requires zero maintenance. Choose based on the size of your site and your editorial capacity.
Front matter for SEO: structured data fields
Well-designed front matter supports rich search engine results by making the data needed for structured data markup available to your templates without hard-coding it. The front matter fields most relevant to SEO are:
The description field provides the content for the <meta name="description"> tag and the description property in JSON-LD structured data. Write descriptions as concise, accurate summaries of the page content β 120-160 characters that would be useful to a reader seeing the page in a search result snippet. Do not stuff keywords; Google rewrites meta descriptions that read as keyword lists rather than natural language.
The image field (or cover_image, og_image, or similar) provides the URL of the image used in Open Graph tags (og:image) and structured data. When someone shares your post on social media, this image appears in the card preview. A 1200Γ630px JPEG or WebP is the recommended size. If no image is specified, your template should fall back to a sitewide default OG image.
The author field enables Article structured data with a named author, which can appear as a rich result in Google Search for some query types. Use a consistent format across all posts β either a full name string (author: "Jane Smith") or a reference to an author data file (author: jane-smith matched against _data/authors.yml). The data file approach allows you to store each authorβs bio, photo, and social links centrally rather than duplicating them across every post.
The canonical_url field lets you specify an explicit canonical URL for pages that are republished from another source (a Medium post, a company blog, a guest post) or for pages accessible at multiple URLs. Adding canonical_url: https://original-source.com/article-slug/ to a republished postβs front matter and rendering it as <link rel="canonical" href="{{ page.canonical_url | default: page.url | absolute_url }}"> prevents duplicate content penalties and ensures that ranking signals flow to the original source rather than splitting between two versions of the same content.
Dynamic front matter with Jekyll hooks
Jekyll hooks β Ruby code in _plugins/ that runs at specific points in the build lifecycle β can add computed front matter values that are unavailable in static YAML. A hook that reads document.content and computes a reading time estimate, then adds it to document.data["reading_time"], makes page.reading_time available in templates as if it were a static front matter field.
A practical hook that many sites implement: auto-generating an excerpt from the first 150 characters of content if no description is provided in front matter. This ensures every page has a usable description for meta tags and archive listings without requiring authors to manually write excerpts, while still allowing them to override the auto-generated excerpt with a better manually-written one when they choose to.
Hooks are Jekyll-specific (they cannot be used on GitHub Pages unless you use a custom build action) and require Ruby knowledge, but they are the most powerful extension point for front matter behaviour beyond what _config.yml defaults support. For a site with complex content requirements β multiple content types, computed metadata, content validation β a well-designed hook architecture reduces template complexity and improves editorial consistency.