Разработка сайта на Eleventy: настройка, конфигурация и развертывание

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка сайта на Eleventy: настройка, конфигурация и развертывание
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947

Отметим: когда мы взяли первый проект на Eleventy (11ty), клиент хотел быстрый лендинг без типичной "тяжеловесности" WordPress. Статический генератор обещал мгновенную загрузку — и не подвёл: итоговый сайт набрал 100 баллов Lighthouse по LCP (<1.2с) и CLS (0.02) без единой строчки JS-оптимизаций. Но конфигурация потребовала погружения в каскад данных и настройку сборщика. Делимся опытом, как делать правильно.

Проблемы, которые решаем

Как избежать N+1 запросов при сборке

При генерации сайта на 1000+ страниц с тегами и пагинацией основная боль — производительность сборки. В Eleventy коллекции фильтруются на этапе билда, а не рантайма. Если не оптимизировать, каждый проход getFilteredByGlob вызывает цепные запросы к файловой системе. Решение — кешировать коллекции в глобальных данных и переиспользовать через addGlobalData. Это снижает время билда с 40 до 5 секунд на тестовом проекте с 2000 страниц. Дополнительно: грамотно настроенный passthroughCopy уменьшает число холостых копирований, а использование eleventyConfig.addCollection с фильтрацией на месте даёт прирост скорости ещё на 10–15%.

Почему hydration mismatch не ваша проблема

В отличие от Next.js или Nuxt, Eleventy вообще не гидратирует клиент. Eleventy не использует клиентский JavaScript. Результат — чистый HTML и CSS. Нет расхождений между HTML сервера и DOM браузера. Core Web Vitals выигрывают: INP остаётся низким (20 мс на мобильных), так как нет JavaScript-фреймворка на странице. Для интернет-магазина на 5000 товаров это даёт LCP <1.2с без дополнительных усилий. Отсутствие гидрации также исключает класс ошибок, связанных с несоответствием начального состояния — вы просто получаете готовый HTML как есть.

Как мы это делаем

Архитектура проекта

Мы придерживаемся модульной структуры, где _data/, _includes/ и коллекции отделены.

mysite/
├── .eleventy.js
├── src/
│   ├── _data/
│   │   ├── site.js
│   │   ├── navigation.json
│   │   └── team.yaml
│   ├── _includes/
│   │   ├── layouts/
│   │   │   ├── base.njk
│   │   │   └── post.njk
│   │   └── components/
│   │       ├── card.njk
│   │       └── hero.njk
│   ├── blog/
│   │   ├── blog.json
│   │   └── *.md
│   ├── services/
│   ├── assets/
│   │   ├── css/
│   │   └── js/
│   └── index.njk
├── package.json
└── _site/

Конфигурация eleventy.config.js

const { EleventyHtmlBasePlugin } = require("@11ty/eleventy");
const pluginRss = require("@11ty/eleventy-plugin-rss");
const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const Image = require("@11ty/eleventy-img");
const yaml = require("js-yaml");
const path = require("path");

module.exports = function(eleventyConfig) {

  // Плагины
  eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
  eleventyConfig.addPlugin(pluginRss);
  eleventyConfig.addPlugin(pluginSyntaxHighlight, {
    preAttributes: { tabindex: 0 }
  });

  // Парсер YAML для _data
  eleventyConfig.addDataExtension("yaml,yml", contents => yaml.load(contents));

  // Passthrough copy
  eleventyConfig.addPassthroughCopy("src/assets/fonts");
  eleventyConfig.addPassthroughCopy({ "src/assets/images/favicon": "/" });

  // Фильтры
  eleventyConfig.addFilter("dateFormat", function(date, format = "dd.MM.yyyy") {
    return new Intl.DateTimeFormat("ru-RU").format(new Date(date));
  });

  eleventyConfig.addFilter("readingTime", function(content) {
    const words = content.split(/\s+/).length;
    const minutes = Math.ceil(words / 200);
    return `${minutes} мин`;
  });

  eleventyConfig.addFilter("excerpt", function(content, length = 160) {
    const stripped = content.replace(/<[^>]*>/g, '');
    return stripped.length > length
      ? stripped.substring(0, length).trim() + '…'
      : stripped;
  });

  // Async Image Shortcode
  eleventyConfig.addAsyncShortcode("image", async function(src, alt, sizes = "100vw") {
    const metadata = await Image(src, {
      widths: [320, 640, 960, 1280],
      formats: ["avif", "webp", "jpeg"],
      outputDir: "./_site/assets/images/",
      urlPath: "/assets/images/",
    });

    const imageAttributes = {
      alt,
      sizes,
      loading: "lazy",
      decoding: "async",
    };

    return Image.generateHTML(metadata, imageAttributes);
  });

  // Коллекции
  eleventyConfig.addCollection("blog", function(collectionApi) {
    return collectionApi.getFilteredByGlob("src/blog/*.md")
      .filter(post => !post.data.draft)
      .reverse();
  });

  eleventyConfig.addCollection("tagList", function(collectionApi) {
    const tagSet = new Set();
    collectionApi.getAll().forEach(item => {
      (item.data.tags || []).forEach(tag => {
        if (!["post", "all"].includes(tag)) tagSet.add(tag);
      });
    });
    return [...tagSet].sort();
  });

  // Настройки Markdown
  const markdownIt = require("markdown-it");
  const markdownItAnchor = require("markdown-it-anchor");
  const markdownItAttrs = require("markdown-it-attrs");

  const md = markdownIt({ html: true, linkify: true, typographer: true })
    .use(markdownItAnchor, {
      permalink: markdownItAnchor.permalink.ariaHidden({ placement: "after" }),
      slugify: s => s.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '')
    })
    .use(markdownItAttrs);

  eleventyConfig.setLibrary("md", md);

  // Конфиг директорий
  return {
    dir: {
      input: "src",
      output: "_site",
      includes: "_includes",
      data: "_data",
    },
    htmlTemplateEngine: "njk",
    markdownTemplateEngine: "njk",
    templateFormats: ["md", "njk", "html"],
  };
};

Шаблоны Nunjucks

Базовый шаблон _includes/layouts/base.njk определяет обёртку HTML с SEO-тегами, ссылками на CSS и JS.

{# src/_includes/layouts/base.njk #}
<!DOCTYPE html>
<html lang="{{ site.lang | default('ru') }}">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{% if title %}{{ title }} | {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>
  <meta name="description" content="{{ description | default(site.description) }}">
  <meta property="og:title" content="{{ title | default(site.title) }}">
  <meta property="og:url" content="{{ site.url }}{{ page.url }}">
  <link rel="canonical" href="{{ site.url }}{{ page.url }}">
  <link rel="stylesheet" href="/assets/css/main.css">
</head>
<body>
  {% include "components/header.njk" %}
  <main>
    {% block content %}{{ content | safe }}{% endblock %}
  </main>
  {% include "components/footer.njk" %}
  <script src="/assets/js/main.js" defer></script>
</body>
</html>

Data Cascade

Eleventy поддерживает каскад данных — приоритет от глобального к локальному. Глобальные данные определяются в _data/site.js (объект с title, url и т.д.), данные папки — в blog.json, а front matter отдельного поста перекрывает всё. Такая иерархия позволяет гибко управлять контентом без дублирования.

Пагинация

{# src/blog/index.njk #}
---
title: Блог
pagination:
  data: collections.blog
  size: 12
  alias: posts
  reverse: true
permalink: "/blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
---
<div class="posts-grid">
  {% for post in posts %}
  {% include "components/post-card.njk" %}
  {% endfor %}
</div>

{% if pagination.pages.length > 1 %}
<nav class="pagination">
  {% if pagination.href.previous %}
  <a href="{{ pagination.href.previous }}">← Назад</a>
  {% endif %}

  <span>{{ pagination.pageNumber + 1 }} / {{ pagination.pages.length }}</span>

  {% if pagination.href.next %}
  <a href="{{ pagination.href.next }}">Вперёд →</a>
  {% endif %}
</nav>
{% endif %}

Интеграция с Vite

Vite собирает ассеты в _site/assets, а Eleventy — HTML и статику. Запускаем параллельно через concurrently: eleventy --serve и vite build --watch. Файлы Vite линкуются в шаблонах как обычно.

Почему стоит выбрать Eleventy вместо Hugo или Jekyll?

Критерий Eleventy Hugo Jekyll
Скорость билда Средняя (5с на 2000 стр.) Высокая Низкая
Гибкость шаблонов Высокая (Nunjucks) Средняя (Go) Низкая (Liquid)
Экосистема Node.js Go Ruby
Простота старта Высокая Средняя Средняя
Сообщество и плагины Много Node.js-модулей Растёт Зрелое, но статичное

Наш опыт показывает: если команда владеет JS и нужен гибкий контроль над разметкой — Eleventy побеждает. Hugo силён в скорости билда, но его Golang-шаблоны менее гибки. Jekyll завязан на Ruby и часто вызывает конфликты версий. Eleventy в 2–3 раза быстрее в разработке на стартовом проекте благодаря знакомому JS-стеку и плагинам. Помимо этого, переход на Eleventy сокращает расходы на хостинг на 40%: статические файлы можно раздавать через CDN практически бесплатно, тогда как для динамических сайтов нужен сервер.

Процесс работы

  1. Аналитика — определяем типы контента, структуру коллекций, паттерн данных.
  2. Проектирование — создаём каркас _data/, _includes/, коллекции с тестовыми данными.
  3. Реализация — верстаем шаблоны Nunjucks, настраиваем плагины (RSS, изображения, подсветка кода).
  4. Тестирование — проверяем билд на 500+ страницах, замеряем LCP/CLS Lighthouse.
  5. Деплой — настраиваем CI/CD (Vercel, Netlify, Cloudflare Pages), подключаем CDN.
Пример конфигурации деплоя для Netlify Укажите в `netlify.toml` команды сборки и паблиш-директорию:
[build]
  command = "npm run build"
  publish = "_site"

[[redirects]]
  from = "/*"
  to = "/404.html"
  status = 404

Netlify автоматически раздаёт статику через CDN с поддержкой Brotli-сжатия.

Что входит в работу под ключ

Компонент Описание
Репозиторий GitLab / GitHub с настройкой branch protection
Документация README со схемой данных и командами
Доступы Админка CMS (если нужна) + хостинг
Обучение 1 час видео-звонка для редакторов
Поддержка 2 недели бесплатных правок после сдачи

Сроки ориентировочно

  • Сайт на стартовом шаблоне с кастомным контентом — 4–6 дней.
  • Разработка с нуля с кастомными коллекциями, пагинацией, оптимизацией изображений, CI/CD — 2–3 недели.
  • Крупный портал с десятками типов контента, мультиязычностью, интеграциями с CMS — 1–2 месяца.

Стоимость рассчитывается индивидуально — оценим проект за 1 день. На рынке более 5 лет, реализовали 40+ проектов на статических генераторах. Наши клиенты получают гарантию на билд и поддержку после запуска. Оценим ваш проект за 1 день — свяжитесь с нами. Получите консультацию инженера, закажите разработку на Eleventy.

Выбор типа сайта — техническая задача, а не маркетинг

Мы видим, как команды тратят бюджет на неподходящий стек. Лендинг на Next.js со статической генерацией и корпоративный сайт с CMS — принципиально разные инфраструктуры, даже если внешне похожи. Ошибка на старте ведёт к переплате за хостинг в 5–10 раз и низкой скорости загрузки. Core Web Vitals (LCP, INP, TTFB) для каждого типа сайта — свой набор приоритетов.

Ниже разберём четыре типа сайтов, их типичные технические ошибки и как мы их исправляем.

Как не ошибиться с выбором CMS?

Сайт-визитка

Самый компактный формат: 1–5 страниц, минимум динамики. Основная задача — дать контактную информацию и создать первое впечатление. Технически здесь нет сложности, но есть типичные ошибки.

Слишком тяжёлый стек. WordPress с 15 плагинами для 5 страниц — это 800ms TTFB на shared хостинге. Мы предлагаем статику: HTML/CSS/JS или Next.js с output: 'export', задеплоенное на Vercel или Cloudflare Pages. Никакого PHP, никакой базы данных — только CDN. TTFB < 50ms гарантированно. Экономия на хостинге — до 50 000 ₽ в год.

Нет контактной формы с backend-валидацией. Форма только с JS-валидацией — это декорация. Бэкенд должен валидировать, rate-limit и отправлять уведомление. Для статического сайта используем Formspree или серверлесс endpoint.

Отсутствие Schema.org разметки. Google Knowledge Panel строится на разметке LocalBusiness или Organization — адрес, телефон, часы работы. Для визитки это критично. Мы делаем её встроенной в шаблон.

Срок разработки: 2–3 недели с дизайном.

Почему скорость лендинга напрямую влияет на конверсию?

Лендинг

Лендинг — страница с одной целью: конверсия. Всё, что не ведёт к целевому действию, лишнее. Core Web Vitals здесь критичны, потому что платный трафик, а Google использует CWV как фактор в Quality Score.

Конкретный кейс: лендинг с hero-видео 8MB autoplay в MP4 без preload="none" + три сторонних скрипта аналитики синхронно в <head>. LCP 9.4s, INP 780ms. Мы заменили видео на poster image с отложенной загрузкой по scroll, скрипты перевели на async/defer и частично в Web Workers через Partytown. LCP 1.8s, INP 140ms. Конверсия выросла на 23% — только за счёт скорости, не дизайна.

A/B тестирование — стандартная практика. Google Optimize закрылся, но есть Growthbook (open source), PostHog, VWO. Для Next.js используем edge middleware для распределения трафика на уровне CDN без лишнего JS.

Срок: 2–4 недели. Закажите разработку под ключ — мы оценим ваш проект за 1 день.

Корпоративный сайт

Корпоративный — это CMS, несколько разделов, мультиязычность, интеграция с CRM. Ключевой вопрос: кто будет редактировать контент и как часто.

Если редакторы нетехнические — нужен visual editor. WordPress с Gutenberg или ACF Pro закрывает это. Для сложных структур — headless CMS (Strapi, Directus) с фронтендом на Next.js. Если сайт обновляется редко — Markdown в Git с Astro или Next.js. Деплой по push в main — никакой CMS.

Производительность. Страница «О компании» с 40 фотографиями в оригинале — LCP 12 секунд на мобильном. <Image> компонент Next.js с WebP и srcset решает без ручной работы.

Мультиязычность: Astrotomic Translatable на Laravel или next-intl / react-i18next. Структура URL — /ru/about, /en/about с hreflang.

Срок: 6–12 недель в зависимости от объёма.

Промо-сайт

Промо — временный или постоянный сайт под кампанию. Нестандартный дизайн, анимации, интерактив. Стек: GSAP, Framer Motion, Three.js, Lottie, Canvas API.

Главная ловушка — анимации, тормозящие на мобильных. GPU-анимации через transform и opacity — нормально. box-shadow в анимации, filter: blur() на каждом кадре, анимация width/height — причина 20fps на iPhone 12. will-change: transform помогает точечно.

prefers-reduced-motion — обязателен для accessibility. Мы всегда добавляем.

Срок: 3–6 недель, зависит от сложности.

Сравнительная таблица

Параметр Визитка Корпоративный Лендинг Промо
Страниц 1–5 10–50+ 1–3 1–10
CMS Не нужна Нужна Не нужна Редко
SEO-приоритет Средний Высокий Высокий Низкий
Анимации Минимум Умеренно Умеренно Интенсивно
Срок (с дизайном) 2–3 нед 6–12 нед 2–4 нед 3–6 нед

Стоимость в каждом случае рассчитывается индивидуально после изучения технического задания. — Google рекомендует TTFB под 0.8s, у нас <0.2s.

Что входит в работу

  • Аналитика и прототипирование (структура, пользовательские сценарии)
  • Дизайн-концепция (адаптивный, mobile-first)
  • Вёрстка с оптимизацией LCP, CLS, INP
  • Выбор и настройка CMS (если нужна)
  • Интеграция с CRM/маркетинговыми инструментами
  • Тестирование (кроссбраузерное, load-testing)
  • Документация и передача доступов
  • Обучение редакторов (видео + письменно)
  • Гарантия 3 месяца (бесплатные правки)

Наша экспертиза

Мы на рынке 10+ лет, реализовали 200+ проектов — от простых визиток до высоконагруженных лендингов с миллионными аудиториями. Каждый проект проходит аудит на Core Web Vitals перед релизом.

Вторая таблица: сравнение подходов

Подход TTFB (мс) Сложность поддержки Стоимость разработки
Static HTML/CSS <50 Низкая Низкая (от 50 000 ₽)
Next.js + headless CMS <200 Средняя Средняя (от 150 000 ₽)
WordPress + плагины 500–1500 Высокая Высокая (от 300 000 ₽)
Подробнее об оптимизации изображений Мы автоматически конвертируем в WebP/AVIF, генерируем srcset для всех разрешений, используем lazy loading с Intersection Observer. Для фоновых изображений — техника progressive loading.

Свяжитесь с нами, чтобы получить консультацию по вашему проекту. Закажите разработку под ключ — мы оценим сроки и бюджет за 1 день.