Демо-проект
Магазин Notion-шаблонов: TemplateForge
Каталог цифровых товаров, корзина на Zustand, статический экспорт.
разработка · Next.js 15 · TypeScript · Tailwind · Zustand

Задача
TemplateForge - магазин цифровых товаров: один мейкер продаёт 10 Notion-шаблонов в четырёх категориях, от трекера привычек за $9 до набора для запуска продукта за $49. Товар доставляется ссылкой на email, склада и логистики нет - значит, и сервер магазину не обязателен: витрина, карточки и корзина должны работать как статика и стоить ноль в хостинге. При этом путь покупателя полный: фильтр по категориям, страница товара с составом и отзывами, корзина, оформление заказа. Демо-проект: компания вымышленная, задача типовая и настоящая.
Решение
Формат - тёмный тех-минимализм под аудиторию, которая живёт в Notion: фон почти чёрный, один фиолетовый акцент, моноширинные цены и метки. Товар нельзя сфотографировать, поэтому его показывают скриншоты самих шаблонов в рамке окна - по три на товар, у бестселлера первым слотом идёт видео.
- Next.js 15 со статическим экспортом: 10 страниц товаров генерируются из одного файла данных, деплой - на любой статический хостинг, серверного кода ноль.
- Каталог фильтруется на клиенте, у каждой категории счётчик: «Все 10, Продуктивность 3, Финансы 2, Бизнес 3, Студентам 2» - цифры сходятся с каталогом.
- Карточка товара: галерея, табы «Что внутри» и «Отзывы», блок похожих шаблонов - сначала своя категория, добор из соседних, всегда ровно три.
- Корзина на Zustand с persist в localStorage. Цифровой товар без количеств: одна покупка - одна позиция, повторный клик честно отвечает «Уже в корзине» и дубль не добавляет.
- Checkout минимальный: имя и email обязательны, телефон - нет; чек и товар цифровому покупателю приходят на почту, лишние поля только роняют конверсию.
- Корзина очищается не на сабмите, а на странице «Спасибо» по одноразовому флагу: прямой заход на /thanks чужую корзину не трогает.
Детали, которые легко не заметить
- Гидрация статического экспорта: счётчик корзины и маска телефона считаются после mount, иначе HTML с сервера не совпал бы с localStorage и локалью браузера. Консоль без ошибок гидрации - проверено в тест-отчёте.
- Маска телефона смотрит на язык браузера: русскоязычным - формат +7, остальным - +1. Согласие с политикой конфиденциальности - обязательный чекбокс с внятным текстом ошибки.
- Доступность: табы размечены как tablist/tab/tabpanel, FAQ - aria-expanded, у видео кнопка паузы с aria-label, автовоспроизведение отключается при prefers-reduced-motion.
- Юридическая гигиена демо: страница-дисклеймер, продавец подписан как демо-организация с нулевым ИНН, контакт на зарезервированном домене .demo, noindex в метаданных и X-Robots-Tag в заголовках - демо не конкурирует в поиске с реальными магазинами.
- Состояния интерфейса описаны, а не только счастливый путь: пустая корзина с кнопкой в каталог, невалидный email, снятый чекбокс, оговорка про карты российских банков на шаге оплаты.
Цифры
В готовом сайте 17 страниц: витрина с фильтром по 4 категориям, 10 карточек товаров, корзина, оформление заказа и служебные страницы. У каждого шаблона 3 скриншота, у бестселлера - видео. Серверного кода нет: магазин работает как чистая статика и деплоится на любой бесплатный статический хостинг.
Скриншоты




