Налаштування і кастомізація теми Eleventy
Eleventy не має офіційного маркетплейсу тем — основний джерело це стартові шаблони (starters) від спільноти та офіційних партнерів. На відмінність від Hugo або Jekyll, «теми» в Eleventy — це повнофункціональні проекти з залежностями, які форкуються та кастомізуються, а не підключаються як пакет. Це дає більше свободи та вимагає розуміння структури чужого коду.
Популярні стартери
| Стартер | Особливості |
|---|---|
eleventy-base-blog (офіційний) |
Мінімальний блог, Nunjucks |
11ty-webc-starter |
WebC компоненти, сучасний стек |
eleventy-excellent |
Повний набір: RSS, sitemap, OG, dark mode |
eleventy-duo |
Портфоліо + блог |
slinkity |
React/Vue компоненти + Vite |
Клонування стартера:
# Через degit (без git-історії)
npx degit 11ty/eleventy-base-blog mysite
cd mysite
npm install
npm start
Структура типового стартера
eleventy-base-blog/
├── eleventy.config.js # Конфіг — точка входу для кастомізації
├── src/
│ ├── _includes/
│ │ └── layouts/
│ │ ├── base.njk
│ │ └── post.njk
│ ├── _data/
│ │ └── metadata.json # Замінити першим ділом
│ ├── blog/
│ ├── css/ # Стилі — редагувати напрямку
│ └── index.njk
├── package.json
└── .eleventy.js # Іноді обидва файли конфіга існують
Первинна настройка: metadata та конфіг
// src/_data/metadata.json
{
"title": "Назва сайту",
"url": "https://example.com",
"language": "uk",
"description": "Опис для SEO",
"author": {
"name": "Ім'я автора",
"email": "[email protected]",
"url": "https://example.com/about/"
}
}
// eleventy.config.js — додавання кастомної логіки
module.exports = function(eleventyConfig) {
// Базові настройки стартера (не трогати)
// ...
// Ваші додатки:
eleventyConfig.addFilter("ukDate", function(dateObj) {
return new Intl.DateTimeFormat("uk-UA", {
day: "numeric",
month: "long",
year: "numeric"
}).format(new Date(dateObj));
});
eleventyConfig.addFilter("limit", function(arr, limit) {
return arr.slice(0, limit);
});
// Додаткові passthrough
eleventyConfig.addPassthroughCopy("src/uploads");
};
Кастомізація шаблонів Nunjucks
Принцип той же, що в Hugo: знайти потрібний шаблон, редагувати напрямку (стартер — це копія, не пакет).
Додавання навігації в base.njk:
{# src/_includes/layouts/base.njk #}
<!DOCTYPE html>
<html lang="{{ metadata.language }}">
<head>
...
</html>
<body>
<header class="site-header">
<div class="container">
<a href="/" class="logo">
<img src="/assets/images/logo.svg" alt="{{ metadata.title }}">
</a>
<nav class="main-nav" aria-label="Основна навігація">
{% for item in navigation %}
<a href="{{ item.url }}"
{% if page.url == item.url %}aria-current="page"{% endif %}
class="nav-link">
{{ item.label }}
</a>
{% endfor %}
</nav>
</div>
</header>
...
// src/_data/navigation.json
[
{ "label": "Головна", "url": "/" },
{ "label": "Послуги", "url": "/services/" },
{ "label": "Блог", "url": "/blog/" },
{ "label": "Контакти", "url": "/contact/" }
]
Кастомізація CSS
Стартери використовують різні підходи до стилів: vanilla CSS custom properties, SASS, Tailwind. Типова кастомізація через CSS variables:
/* src/css/custom.css — додати після imports стартера */
:root {
/* Переопреділення змінних теми */
--color-primary: #2563eb;
--color-primary-dark: #1d4ed8;
--color-text: #1e293b;
--color-bg: #ffffff;
--color-bg-muted: #f8fafc;
--font-sans: "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", "Fira Code", monospace;
--radius: 8px;
--shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
--container-max: 1280px;
}
/* Тема темрявини */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #e2e8f0;
--color-bg: #0f172a;
--color-bg-muted: #1e293b;
}
}
Якщо стартер використовує Tailwind, кастомізація через tailwind.config.js:
module.exports = {
content: ["./src/**/*.{njk,md,js,html}"],
theme: {
extend: {
colors: {
primary: { 500: '#2563eb', 600: '#1d4ed8' },
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
},
},
};
Додавання нових секцій та компонентів
{# src/_includes/components/features.njk #}
{% set features = features or [] %}
<section class="features">
<div class="container">
{% if featuresTitle %}
<h2 class="section-title">{{ featuresTitle }}</h2>
{% endif %}
<div class="features-grid">
{% for feature in features %}
<div class="feature-card">
{% if feature.icon %}
<div class="feature-icon">{{ feature.icon | safe }}</div>
{% endif %}
<h3>{{ feature.name }}</h3>
<p>{{ feature.description }}</p>
</div>
{% endfor %}
</div>
</div>
</section>
Використання на сторінці:
---
layout: layouts/base.njk
title: Про нас
featuresTitle: Наші переваги
features:
- name: "Досвід"
icon: "<svg>...</svg>"
description: "10 років розробки"
- name: "Команда"
icon: "<svg>...</svg>"
description: "25 спеціалістів"
---
Додавання RSS та Sitemap
Якщо стартер не включає:
npm install @11ty/eleventy-plugin-rss
// eleventy.config.js
const pluginRss = require("@11ty/eleventy-plugin-rss");
eleventyConfig.addPlugin(pluginRss);
{# src/feed.njk #}
---
permalink: /feed.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{ metadata.title }}</title>
<link href="{{ metadata.url }}/feed.xml" rel="self"/>
<updated>{{ collections.blog | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
{% for post in collections.blog | reverse | limit(10) %}
<entry>
<title>{{ post.data.title }}</title>
<link href="{{ metadata.url }}{{ post.url }}"/>
<updated>{{ post.date | dateToRfc3339 }}</updated>
<content type="html">{{ post.templateContent | htmlToAbsoluteUrls(metadata.url) }}</content>
</entry>
{% endfor %}
</feed>
Терміни
Первинна настройка стартера (metadata, навігація, кольори, шрифти) — 1–2 дні. Глибока кастомізація шаблонів, додавання компонентів, кастомна сторінка тегів, RSS — 3–6 днів.







