Кейс · сайт, который вы сейчас читаете

Сайт маркетолога: 63 страницы, которые собираются сами

Единственный проект в портфолио, который можно проверить, не веря на слово: вы уже на нём. Здесь нет CMS и админки — страницы собираются из файлов с данными скриптом на Node, а сборка не выпустит наружу страницу, которая не прошла проверки.

Главная: первый экран с цифрами по опыту

63
страницы в сборке
18
статей в блоге
24
страницы кейсов
21,6 тыс.
строк кода
Задача

Сайт, который растёт, а вести его некому

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

Дальше происходит одно и то же. Цены на странице услуги и в прайсе расходятся. Меню на новой странице отличается от старой. Кейс есть в списке, но ссылка ведёт в никуда. Каждая мелочь по отдельности не смертельна, а вместе они читаются как «человеку всё равно» — на сайте, который продаёт внимание к деталям.

Как обычно
  • Новая страница — копия старой с правками руками
  • Цена меняется в трёх местах, вспоминается одно
  • Меню правится в каждом файле отдельно
  • Ошибку в вёрстке находит посетитель
  • Через год сайт страшно трогать
Как здесь
  • Страница кейса появляется из записи в файле данных
  • Цена лежит в одном месте, сборка сверяет остальные
  • Меню и подвал существуют в единственном экземпляре
  • Ошибку находит проверка до выкладки
  • Правка занимает минуты и не ломает соседнее
Как выглядит

Скриншоты разделов

Витрина кейсов, страница отдельного кейса, отраслевая страница и лента блога — четыре типа страниц, каждый собирается из своих данных.

Витрина: 24 кейса, фильтры по услуге и нише
Страница кейса: таких 21, и все из одного файла данных
Отраслевая страница: у каждой свой разбор механики ниши
Блог: 18 статей, фильтры по темам, оглавление в каждой
Что сделано
Архитектура

Генератор статики вместо CMS

Сайт собирается скриптом на Node: данные лежат в файлах, страницы получаются из них. Ни базы, ни админки, ни PHP — отдаётся готовый HTML.

  • Каждая страница кейса собирается из одного файла с данными — сейчас их 21: правится текст в данных, перестраиваются страница, витрина, карта сайта и блоки «кейсы рядом».

  • Отраслевые страницы (4) — из общего каркаса: одинаковая вёрстка, у каждой свой разбор механики ниши.

  • Статьи блога пишутся в Markdown, лента, RSS и оглавления строятся сами.

  • Меню и подвал существуют в одном экземпляре и подставляются в страницы на сборке.

  • Нечего ломать снаружи: нет админки, нет входа, нет базы данных.

Проверки

Сборка падает, если страница получилась плохой

Самая ценная часть проекта: ошибки ловятся до выкладки, а не через месяц, когда их находит клиент.

  • Все 63 страницы открываются в браузере на десктопе и телефоне: проверяются зоны нажатия, горизонтальная прокрутка и ошибки в консоли.

  • Пиксельный поиск тёмных полос на стыках блоков — глазом такое замечается не всегда, а на телефоне бросается в глаза.

  • Ловушка мёртвых анимаций: элемент, который навсегда остался прозрачным из-за неверного контейнера прокрутки.

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

  • Проверка ссылок на посадочные у каждой услуги: без адреса кнопка «Подробнее» просто не рисуется, и это видно только глазами.

Скорость

Картинки и разметка приведены к виду, который не тормозит

Скорость здесь не самоцель, а следствие: чем меньше отдаётся, тем быстрее открывается.

  • Снимки переведены в WebP — минус 2,6 МБ без заметной потери качества.

  • Размеры каждой картинки проставляются на сборке автоматически, из заголовка самого файла: текст не прыгает при загрузке.

  • Картинки, на которые не осталось ни одной ссылки, в сборку не едут — минус ещё 4,4 МБ.

  • Шрифты подключены с преднагрузкой, чтобы шапка не «дышала» при подмене шрифта.

  • Анимации фона отключаются на слабых устройствах и вне видимой области экрана.

SEO

Разметка и структура — из данных, а не руками

Всё, что поисковик читает машинно, генерируется вместе со страницей и потому не расходится с ней.

  • Хлебные крошки, описание услуги и блоки вопросов размечены микроразметкой на всех страницах, где они есть.

  • Карта сайта собирается на каждом деплое, дата изменения берётся из данных страницы, а не из даты коммита.

  • Заголовки страниц укорачиваются автоматически, если не влезают в выдачу: хвост с доменом отбрасывается, а не режется текст.

  • Статьи связаны между собой по темам: подборка «читайте также» считается по общим тегам, а не берёт три последние.

Деплой

Пуш в репозиторий — и сайт обновился

Ручных шагов нет: правка приезжает на сервер сама, если прошли проверки.

  • GitHub Actions собирает сайт и синхронизирует его с сервером.

  • На сервере nginx: сжатие, кэширование по типам файлов, редиректы со старых адресов.

  • Сертификат продлевается сам, проверка домена лежит вне каталога сайта — чтобы синхронизация её не стёрла.

  • История правок — в репозитории: видно, что и когда менялось, и можно вернуться назад.

Стек

На чём собрано

Ничего экзотического: инструменты выбраны по принципу «переживёт смену версий и не потребует поддержки ради самой поддержки».

Node.js React (JSX + Babel) Terser Markdown Playwright sharp GitHub Actions nginx Яндекс Метрика

Скриншоты выше сняты автоматически той же связкой, которой сайт проверяется перед выкладкой, — поэтому они не устаревают незаметно.

Вопросы

Что обычно спрашивают

Почему не WordPress или конструктор?
Потому что задача другая. Конструктор хорош, когда страниц десяток и их правит нетехнический человек. Здесь 63 страницы, из которых 21 собирается из одного файла с данными, — руками это не поддерживается. Плюс у генератора статики нет админки и базы, а значит нечего ломать и нечего обновлять ради безопасности.
Вы всем делаете такие сайты?
Нет. Этот сайт — витрина возможностей, а не шаблон. В большинстве проектов нужна посадочная под рекламный запрос, и она делается проще и быстрее. Генератор со сборкой из данных оправдан там, где страниц много и они однотипные: каталог, кейсы, филиалы, отраслевые страницы. Как это выглядит в работе.
Сколько занял проект?
Он не заканчивался: сайт живёт и меняется постоянно, 351 правка в истории репозитория. Первая рабочая версия собралась за несколько дней, всё остальное — блог, кейсы, отраслевые страницы, проверки — дописывалось по мере надобности.
Зачем проверки, если сайт делает один человек?
Именно поэтому. Ревьюера нет, а ошибки одинаковые: тёмная полоса на стыке блоков, кнопка меньше пальца, ссылка в никуда после переименования страницы. Проверки ловят это до выкладки. Половина из них появилась после того, как я сам сломал ровно эту вещь и не заметил.
Можно посмотреть, как всё устроено внутри?
Часть решений описана в блоге, а результат виден прямо здесь: любая страница сайта — это то, о чём кейс. Открыть исходники целиком не могу, там лежат рабочие данные и настройки.

Нужен сайт, который не развалится через год?

Расскажите, что должно быть на сайте и кто будет его вести. Если хватит простой посадочной — так и скажу: генератор со сборкой из данных нужен далеко не всем.

Рассчитать проект