Про Next.js 15 писали переважно в жанрі «революція». Далі — без цього. Розберемо, що саме змінилося в релізі, які зміни ламають робочий код мовчки, і як за пів години перевірити, чи ваш проєкт узагалі отримує з нової версії щось, крім номера в package.json.
Turbopack: швидше, але не там, де ви думаєте
Turbopack отримав стабільний статус для next dev — це зафіксовано в офіційних release notes Next.js. Замість повного перебудовування графа модулів після кожної правки він перезбирає тільки те, що змінилося, і тримає результат у пам'яті між збірками.
Наскільки швидше стане особисто у вас — залежить від кількості модулів, глибини імпортів, набору CSS-обробників і швидкості диска. Порівняльної таблиці «було / стало» тут не буде: цифри з чужого ноутбука на чужому проєкті нічого не кажуть про ваш. Заміряйте самі — time перед запуском dev-сервера, потім перемкніть прапорець і повторіть на тому самому коді.
І головне, про що зазвичай мовчать. Швидкість dev-сервера не має жодного стосунку до того, як швидко сайт відкриється у відвідувача. Turbopack працює на вашій машині під час розробки. Відвідувач бачить продакшн-збірку, віддану з сервера в іншій країні, через мобільну мережу, на телефоні п'ятирічної давності. Це два різні світи, і прискорення першого не покращує другий ні на мілісекунду.
Що справді впливає на швидкість у відвідувача
Між кліком і появою контенту людина не бачить нічого. Чим довша ця пауза, тим більша частка людей закриває вкладку — і ці люди не побачать ні товару, ні ціни, ні форми. Швидкість не продає. Вона визначає, скільком людям вашу пропозицію взагалі покажуть.
Технічно тут два важелі: TTFB (час до першого байта — кешування, запити до бази, налаштування сервера) і вага HTML, який браузер має завантажити до першого рендеру. Next.js допомагає з обома, але роботу за вас не робить.
Наші заміри на живих сайтах, зроблені зовнішньо через curl 31.07.2026:
- корпоративний односторінковий сайт консалтингової компанії на Next.js — TTFB 254 мс, повний документ за 342,6 мс, HTML 102,1 КБ;
- SaaS-платформа для рерайту описів товарів — TTFB 220,6 мс при 141 КБ HTML.
Це наш вимір, і це стан сервера, а не бізнес-показник клієнта. Чесна межа тут така: TTFB — тільки серверна частина. Повний час до інтерактивності в реального відвідувача залежить ще від його пристрою, мережі, ваги картинок і сторонніх скриптів, які підключили вже після нашого заміру. І ще важливіше: сайт, що відкривається за 200 мс, просто швидше покаже людині причину піти, якщо ціна вища за ринок або товару немає в наявності. Швидкість прибирає технічну втрату. Попиту вона не створює.
Кешування: fetch більше не кешується за замовчуванням
Найтихіша зміна релізу. У Next.js 14 результат fetch() за замовчуванням кешувався, у 15-й — ні. Те саме з GET-обробниками в Route Handlers і з клієнтським кешем роутера.
Ламається це без помилок. Код працює, тести проходять, а сервер починає ходити в API на кожен запит замість одного разу на хвилину. Помічають зазвичай по рахунку від хостингу або по TTFB, який виріс утричі після оновлення.
Що робити при міграції: пройтися по всіх fetch() у серверних компонентах і проставити намір явно.
// Раніше вистачало голого fetch — тепер намір треба озвучити
const products = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 }, // кешувати годину
})
// Жорсткий кеш, якщо дані статичні
const config = await fetch('https://api.example.com/config', {
cache: 'force-cache',
})
Асинхронні params, searchParams, cookies і headers
Друга зміна, яку не можна пропустити: динамічні API стали асинхронними. params і searchParams у сторінках, а також cookies() і headers() тепер повертають проміс.
// Next.js 15
export default async function ProductPage({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
return <Product slug={slug} />
}
Офіційний codemod (npx @next/codemod@canary upgrade latest) перепише більшість викликів автоматично. Але не всі: звернення до params через проміжну змінну або деструктуризацію в іншому файлі він не бачить. Після прогону перевірте типи руками — саме тут ховаються помилки, які виявляться тільки в рантаймі на проді.
Server Actions і те, про що забувають
Синтаксис не змінився, змінилася зрілість підходу.
'use server'
import { revalidatePath } from 'next/cache'
import { auth } from '@/lib/auth'
export async function createPost(formData: FormData) {
const session = await auth()
if (!session?.user) throw new Error('Unauthorized')
const title = formData.get('title') as string
await db.post.create({ data: { title, authorId: session.user.id } })
revalidatePath('/blog')
return { success: true }
}
Зверніть увагу на перші два рядки тіла функції. Server Action — це публічний HTTP-ендпоінт зі згенерованим ідентифікатором. Те, що на фронтенді кнопка показується лише залогіненому користувачу, не заважає викликати дію напряму з консолі. Авторизація перевіряється всередині дії. Завжди, навіть коли здається очевидним, що сюди ніхто чужий не потрапить.
React 19: useOptimistic
Next.js 15 працює на React 19, і найкорисніше з нового для типового комерційного проєкту — оптимістичні оновлення без ручного керування станом.
function CommentForm({ comments }) {
const [optimisticComments, addOptimistic] = useOptimistic(
comments,
(state, newComment) => [...state, { ...newComment, pending: true }]
)
async function formAction(formData: FormData) {
const text = formData.get('comment') as string
addOptimistic({ text })
await submitComment(text)
}
return <form action={formAction}>{/* ... */}</form>
}
Коментар з'являється у списку миттєво, а при помилці сервера React сам відкочує стан до попереднього. Раніше під це писали окремий редюсер і руками тримали список «ще не збережених» елементів.
Що бачить пошуковий бот і AI-асистент
Тут у Next.js є перевага, яку легко втратити необережною архітектурою. Серверний рендеринг віддає готовий HTML одразу — і саме це потрібно агентам AI-асистентів, які здебільшого не виконують JavaScript. Якщо сайт зібраний як клієнтська оболонка, що добирає контент після завантаження, агент побачить порожню сторінку і процитує когось іншого.
З виміряного нами: у виробника негорючих стінових панелей на Next.js карта сайту містить 164 URL і жодного дубля, TTFB на головній 244 мс, а в розмітці — 8 типів JSON-LD, включно з Organization, PostalAddress і SearchAction (наш вимір 01.08.2026). У SaaS-платформи з прикладу вище в розмітці лежать FAQPage, SoftwareApplication і Offer.
Чесна межа: ніхто, включно з нами, не може обіцяти згадку у відповіді AI-асистента. У вендорів немає ні гарантій, ні прозорих правил відбору, а обсяг переходів з асистентів поки що малий порівняно зі звичайним пошуком. Це робота на випередження з невідомою віддачею, і подавати її інакше було б неправдою.
Окремо про карту сайту. App Router уміє генерувати її з коду через app/sitemap.ts, і це варто зробити відразу. Але Google у власній документації прямо пише, що карта допомагає знайти сторінки й не гарантує ні сканування, ні індексації. Кількість URL у карті ніколи не дорівнює кількості сторінок в індексі — реальну цифру видно тільки у вашій Search Console.
Перевірка свого проєкту за пів години
Чотири команди дадуть більше розуміння, ніж будь-яка стаття, включно з цією.
Перша відповідь сервера на проді:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s | всього: %{time_total}s | розмір: %{size_download} байт\n" https://ваш-сайт.com/
Що бачить бот, який не виконує JavaScript:
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1)" https://ваш-сайт.com/ | wc -c
Якщо в цьому HTML немає назви товару чи заголовка h1, який видно в браузері, — контент збирається на клієнті, і для бота сторінка порожня:
curl -s https://ваш-сайт.com/product/example | grep -c "назва товару"
Чи живий sitemap:
curl -sI https://ваш-сайт.com/sitemap.xml | head -3
Останнє ламається частіше, ніж здається. У наших замірах регулярно трапляються два сценарії: robots.txt посилається на карту, яка віддає 404, або карта відповідає кодом 200 із тілом на нуль байт. Формально працює, фактично бот не отримує нічого — і жоден моніторинг доступності цього не покаже, бо статус-код правильний.
Коли мігрувати
| Ситуація | Що робити |
|---|---|
| Новий проєкт | Стартувати одразу на 15-й |
| Активна розробка, реліз не завтра | Планувати міграцію, починати з codemod на окремій гілці |
| Стабільний прод, змін мало | Не поспішати; спершу перевірити сумісність залежностей із React 19 |
| Багато сторонніх UI-бібліотек | Перевірити React 19 до всього іншого — це найчастіша причина застрягти на пів дороги |
Найбільший ризик міграції — не сам Next.js, а екосистема навколо нього. Оновлення фреймворку зазвичай проходить за день. Тиждень з'їдає бібліотека компонентів, яку автор ще не оновив під React 19, і вибір між форком, заміною та очікуванням.
Що з цього має значення
Turbopack робить приємнішою вашу роботу, і це чесна користь — просто вона не переходить у метрики сайту. Зміни в кешуванні й асинхронні API вимагають уваги при оновленні, інакше проєкт почне поводитись гірше без жодного повідомлення про помилку. А серверний рендеринг залишається тим, заради чого Next.js має сенс у комерційному проєкті: він віддає готовий HTML і людині, і боту, і агенту асистента.
Наскільки це вплине на ваші заявки й продажі — залежить від ніші, попиту й поточного стану сайту. Технічна частина прибирає втрати. Решту вирішує пропозиція.

