Home Blog Jekyll Data Files: The Complete Guide to _data
Tutorial

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.

Jekyll Data Files: The Complete Guide to _data

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 (.yml or .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.

Share LinkedIn