Skip to main content

Чи можна використовувати Feature-Sliced Design у Next.js?

Так, Feature-Sliced Design (FSD) можна відмінно використовувати у Next.js - просто важливо розуміти межу:

  • app/ (або pages/) - це шар роутингу та композиції сторінок
  • FSD-шари (shared / entities / features / widgets / pages) - це твоя доменна/фічева архітектура

Головне правило

Не перетворюй FSD-папки на роути. Тобто features/, entities/, shared/ тощо краще тримати поза app/, щоб Next не почав сприймати їх як сегменти маршрутів.


Рекомендована структура (App Router + FSD)

txt
src/ app/ # тільки роутинг, layout, page, route handlers (public)/ page.tsx (auth)/ login/page.tsx tasks/ [id]/ page.tsx layout.tsx pages/ # (опційно) якщо використовуєш Pages Router shared/ ui/ lib/ config/ api/ entities/ task/ model/ ui/ api/ features/ solve-task/ ui/ model/ lib/ widgets/ task-workspace/ ui/ # шар pages у FSD часто НЕ потрібен у Next, тому що "pages" = app routes

Як «склеювати» FSD і Next-роути

У app/.../page.tsx ти зазвичай:

  • береш дані (server actions / fetch / ORM)
  • підключаєш widgets/features/entities і збираєш сторінку

Приклад:

tsx
// src/app/tasks/[id]/page.tsx import { TaskWorkspace } from "@/widgets/task-workspace/ui/TaskWorkspace"; export default async function Page({ params }: { params: { id: string } }) { return <TaskWorkspace taskId={params.id} />; }

Важливий нюанс: server/client компоненти у FSD

У Next App Router компонент за замовчуванням Server Component.

  • UI, де є useState, useEffect, zustand, DOM, editor - роби use client
  • Моделі/утиліти в shared/lib, entities/*/model - часто можна лишати серверними/універсальними

Типовий патерн:

  • widgets/.../ui/*.tsx - можуть бути use client
  • entities/.../api - серверні функції / репозиторії
  • features/.../model - стан/стори (зазвичай client)

Де зберігати «api» у FSD при Next

Є 2 нормальні варіанти:

Варіант A (рекомендую): серверна логіка поруч із доменом

txt
entities/task/api/task.repo.ts # Prisma/SQL

А в app/api/.../route.ts - лише thin-контролер, який викликає repo.

Варіант B: усе HTTP в app/api

txt
app/api/tasks/[id]/route.ts

А у FSD - клієнт для запитів:

txt
shared/api/http.ts entities/task/api/getTask.ts

Часті помилки

  1. Класти features/ всередину app/ Отримаєш «сміттєві» сегменти, проблеми з колізіями, плутанину.
  2. Робити «FSD pages» і «Next pages» одночасно без сенсу У Next шар pages з FSD зазвичай не потрібен, тому що роль сторінок виконує app/.
  3. Змішувати server-repo і client-код в одному файлі Next почне лаятися на імпорти й бандлінг.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.