Jekyll Data Files: The Complete Guide to _data
Master Jekyll data files — store structured content in YAML, JSON, and CSV, loop through it in Liquid templates, and build navigation, team pages, and more.
The _data folder is one of Jekyll’s most underused features. It lets you store structured content — navigation menus, team members, FAQs, pricing tables, social links — in clean YAML, JSON, or CSV files, then access them in any template with site.data. This guide covers everything.
What Are Data Files?
Data files live in the _data/ folder in your Jekyll site root. Jekyll reads them at build time and makes the data available globally via site.data.filename.
Supported formats:
- YAML (
.ymlor.yaml) — best for nested structures - JSON (
.json) — good if you’re pulling from an API or other tool - CSV (
.csv) — useful for tabular data, spreadsheet exports - TSV (
.tsv) — tab-separated, similar to CSV
Basic Usage
A Simple YAML Data File
Create _data/social.yml:
- name: Twitter
url: https://twitter.com/yourhandle
icon: twitter
- name: GitHub
url: https://github.com/yourusername
icon: github
- name: LinkedIn
url: https://linkedin.com/in/yourprofile
icon: linkedin
Access it in any template with site.data.social:
<ul class="social-links">
{% for link in site.data.social %}
<li>
<a href="{{ link.url }}" aria-label="{{ link.name }}" target="_blank" rel="noopener">
<span class="icon icon--{{ link.icon }}"></span>
{{ link.name }}
</a>
</li>
{% endfor %}
</ul>
Real-World Use Cases
1. Navigation Menu
The most common use — keeps nav out of layout HTML:
# _data/navigation.yml
main:
- title: Themes
url: /themes/
- title: Blog
url: /blog/
- title: About
url: /about/
- title: Contact
url: /contact/
footer:
- title: Privacy Policy
url: /privacy/
- title: Terms
url: /terms/
- title: FAQ
url: /faq/
<!-- Main nav -->
{% for item in site.data.navigation.main %}
<a href="{{ item.url | relative_url }}">{{ item.title }}</a>
{% endfor %}
<!-- Footer nav -->
{% for item in site.data.navigation.footer %}
<a href="{{ item.url | relative_url }}">{{ item.title }}</a>
{% endfor %}
2. Team Members
# _data/team.yml
- name: Sarah Jones
role: Lead Developer
bio: "10 years building Jekyll themes and static sites."
avatar: /assets/images/team/sarah.jpg
github: sarahjones
twitter: sarahjones
- name: James Park
role: Designer
bio: "UI/UX designer specialising in minimal, fast-loading designs."
avatar: /assets/images/team/james.jpg
github: jamespark
twitter: jamespark
<div class="team-grid">
{% for member in site.data.team %}
<div class="team-card">
<img src="{{ member.avatar | relative_url }}" alt="{{ member.name }}" loading="lazy">
<h3>{{ member.name }}</h3>
<p class="role">{{ member.role }}</p>
<p>{{ member.bio }}</p>
<div class="social">
{% if member.github %}
<a href="https://github.com/{{ member.github }}">GitHub</a>
{% endif %}
{% if member.twitter %}
<a href="https://twitter.com/{{ member.twitter }}">Twitter</a>
{% endif %}
</div>
</div>
{% endfor %}
</div>
3. FAQ with Structured Data
# _data/faq.yml
- question: "How do I install a Jekyll theme?"
answer: "Download or fork the theme repository, add the gem to your Gemfile if it's gem-based, run bundle install, and set the theme in _config.yml."
category: installation
- question: "Are Jekyll themes free?"
answer: "Many Jekyll themes are free and open-source on GitHub. Premium themes with extra features and support are also available."
category: themes
- question: "Can I use Jekyll with GitHub Pages?"
answer: "Yes. Jekyll has native GitHub Pages support — push your site to a GitHub repository and it builds and deploys automatically."
category: hosting
<!-- Group by category -->
{% assign faq_by_category = site.data.faq | group_by: "category" %}
{% for group in faq_by_category %}
<h2>{{ group.name | capitalize }}</h2>
{% for item in group.items %}
<details>
<summary>{{ item.question }}</summary>
<p>{{ item.answer }}</p>
</details>
{% endfor %}
{% endfor %}
4. Pricing Table
# _data/pricing.yml
- name: Free
price: 0
period: forever
features:
- Access to all free themes
- GitHub Pages compatible
- Community support
cta_text: Browse Free Themes
cta_url: /themes/?type=free
featured: false
- name: Premium
price: 49
period: one-time
features:
- Beautiful premium design
- Full source code
- 6 months support
- Commercial licence
- Updates included
cta_text: Browse Premium Themes
cta_url: /themes/?type=premium
featured: true
<div class="pricing-grid">
{% for plan in site.data.pricing %}
<div class="pricing-card {% if plan.featured %}pricing-card--featured{% endif %}">
<h3>{{ plan.name }}</h3>
<div class="price">
{% if plan.price == 0 %}
Free
{% else %}
${{ plan.price }}
<span class="period">{{ plan.period }}</span>
{% endif %}
</div>
<ul>
{% for feature in plan.features %}
<li>{{ feature }}</li>
{% endfor %}
</ul>
<a href="{{ plan.cta_url }}" class="btn {% if plan.featured %}btn--primary{% endif %}">
{{ plan.cta_text }}
</a>
</div>
{% endfor %}
</div>
5. Skills / Technologies List
# _data/skills.yml
- category: Frontend
items:
- name: HTML/CSS
level: 95
- name: JavaScript
level: 88
- name: React
level: 80
- category: Tools
items:
- name: Jekyll
level: 95
- name: Git
level: 90
- name: Figma
level: 75
{% for group in site.data.skills %}
<div class="skill-group">
<h3>{{ group.category }}</h3>
{% for skill in group.items %}
<div class="skill-bar">
<span class="skill-name">{{ skill.name }}</span>
<div class="skill-track">
<div class="skill-fill" style="width: {{ skill.level }}%"></div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
6. CSV Data (Spreadsheet-Friendly)
Jekyll reads CSV files too. Great for tabular data you manage in a spreadsheet:
# _data/themes.csv
name,stars,category,url
Minimal Mistakes,27000,Blog,/themes/minimal-mistakes/
Chirpy,7000,Blog,/themes/chirpy/
Just the Docs,8000,Documentation,/themes/just-the-docs/
{% for theme in site.data.themes %}
<tr>
<td><a href="{{ theme.url }}">{{ theme.name }}</a></td>
<td>{{ theme.stars | number_with_delimiter }}</td>
<td>{{ theme.category }}</td>
</tr>
{% endfor %}
Nested Data Files (Subdirectories)
You can organise data files in subdirectories. Access them with dot notation:
_data/
content/
homepage.yml
about.yml
settings/
theme.yml
social.yml
{{ site.data.content.homepage.hero_title }}
{{ site.data.settings.social.twitter }}
Filtering and Sorting Data in Liquid
<!-- Filter by a field value -->
{% assign free_themes = site.data.themes | where: "type", "free" %}
<!-- Filter with expression -->
{% assign featured = site.data.themes | where_exp: "item", "item.stars > 1000" %}
<!-- Sort by a field -->
{% assign by_stars = site.data.themes | sort: "stars" | reverse %}
<!-- Limit results -->
{% assign top_5 = by_stars | limit: 5 %}
<!-- Find a specific item -->
{% assign chirpy = site.data.themes | find: "name", "Chirpy" %}
Data Files vs Collections vs Front Matter
| Use case | Best approach |
|---|---|
| Site-wide config (author, title) | _config.yml |
| Repeated structured lists (nav, team, FAQs) | _data/ files |
| Content with its own pages | Collections (_themes/, _posts/) |
| Page-specific metadata | Front matter |
Rule of thumb: If the data is used across multiple pages and doesn’t need its own URL, put it in _data/. If it needs its own page, use a collection.
Keeping Data Files in Sync
Data files are just text files in your repository. You can:
- Edit them directly in VS Code or any text editor
- Generate them from a script (e.g. a Python script that pulls GitHub star counts and writes
_data/stars.yml) - Commit updates via GitHub’s web interface (useful for non-developers)
For example, a nightly GitHub Action that updates star counts:
# .github/workflows/update-stars.yml
on:
schedule:
- cron: '0 6 * * *' # Daily at 6am
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update star counts
run: python3 tools/update-stars.py
- name: Commit changes
run: |
git config user.name "github-actions"
git config user.email "actions@github.com"
git add _data/stars.yml
git diff --staged --quiet || git commit -m "Update star counts"
git push
Data files are one of Jekyll’s most powerful and underappreciated features. Once you start using them, you’ll find dozens of places to replace hard-coded content with clean, maintainable YAML.
Browse Jekyll themes on JekyllHub — many themes use data files for navigation, settings, and author information, giving you a practical example to learn from.