Превью блога Nodal-dot
Ко всем постам

Nodal-dot Блог - Первый публичный проект

Современный блог на Next.js 15 с FSD-архитектурой, глобусом навыков на Three.js и анимациями GSAP

  • Next.js
  • TypeScript
  • Three.js
  • GSAP
  • FSD
  • MDX

Начало

Я решил построить проект с правилом: никаких готовых UI-китов и шаблонов - всё практически с нуля.

Стек

Выбор технологий был простым - последнее время я увлекался документацией Next.js, что и побудило меня сделать свой сайт на нём.

СлойТехнология
ФреймворкNext.js 15 (App Router)
UIReact 19
ЯзыкTypeScript 5
СтилиSass + CSS Modules (BEM)
i18nnext-intl - EN + RU
КонтентMDX + gray-matter
3DThree.js
АнимацииGSAP
КарусельSwiper
ИконкиLucide React

Архитектура: Feature-Sliced Design (почти)

Изначально я думал, что FSD - это волшебная палочка, которая решит все мои проблемы с расположением компонентов. Но как впоследствии оказалось, в проекте не так много бизнес-сущностей, и это скорее отяготило меня, чем дало какой-либо прирост в DX. Оглядываясь назад, я думаю, что FSD - не та методология, которую стоит использовать для небольших блог-приложений.

Вот как всё устроено:

app/       → маршрутизация, провайдеры, глобальные SEO-метаданные
widgets/   → Header, Footer, PostsFeed - автономные UI-блоки
sections/  → секции страниц
features/  → интерактивная логика (фильтр постов с дебаунсом)
entities/  → модель и API Post (чтение MDX из файловой системы)
shared/    → UI-кит, утилиты, конфиг i18n

Что делает проект интересным

3D-глобус навыков (Three.js)

Секция навыков на странице «Обо мне» - полностью кастомная Three.js-сцена: сфера из иконок технологий на основе SVG-текстур, нанесённых на спрайты.

Взаимодействие: при наведении на узел подсвечиваются его соединения с ближайшими соседями через дуговую геометрию. Клик плавно поворачивает глобус к нужному узлу с помощью анимации.

Производительность управляется явно:

  • prefers-reduced-motion отключает анимацию по запросу accessibility
  • Battery API приостанавливает анимацию при заряде ниже 20%
  • Низкий hardwareConcurrency или deviceMemory также снижает нагрузку

Анимированная лента карьерного пути

Секция «Мой путь» на странице «Обо мне» использует scrub-анимацию GSAP ScrollTrigger для управления прогресс-баром и плавающим шариком между карьерными вехами по мере скролла. Ресайз пересчитывает позиции через общую утилиту дебаунса.

Переходы между страницами

PageTransitionProvider рендерит полноэкранный загрузчик через React-портал. Навигация вызывает startTransition(href) вместо прямой ссылки - загрузчик успевает появиться до рендера нового маршрута.

Посты с живым поиском и фильтрацией по тегам

На странице постов - поиск в реальном времени и фильтрация по тегам. Поисковый ввод дебаунсируется (300 мс) через хук useDebounce - фильтрация запускается только после паузы в наборе, без лишних ре-рендеров на каждое нажатие клавиши.

i18n

Каждая видимая строка живёт в src/shared/i18n/locales/en.json и ru.json. Ничего не захардкожено в компонентах - ни лейблы, ни aria-атрибуты, ни плейсхолдеры. next-intl занимается определением локали, маршрутизацией (/en/... и /ru/...) и загрузкой сообщений.

SEO

Каждая страница генерирует собственный объект Metadata через общую утилиту createPageMetadata: канонические URL, hreflang-альтернативы для обеих локалей, Open Graph-теги и полный набор фавиконок.

Запустить локально

pnpm install
pnpm dev