IHOR.DEVБАЗА_ЗНАНЬ
МЕНЮ

~/blog / Вебстек / loading-and-error-boundaries-in-next-js.md

// посібник · 3 хв читання

Межі завантаження й обробки помилок у Next.js

Розміщуйте loading та error-межі App Router за областями UI, відокремлюйте очікувані відмови й відновлення для Next.js 16.2.

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

loading.tsx задає fallback сегмента, error.tsx — несподівані помилки його дочірнього дерева. Для повільної області потрібен вузький Suspense. Помилки полів і відсутній контент моделюйте свідомо. Очищення error-state, refetch і повтор write — різні операції.

Практичні кроки реалізації

1. Поставте межу над очікуваною роботою

Батько з await до Suspense не показує його fallback під час очікування. Перенесіть роботу в child. Fallback відповідає розміру й призначенню області, не миготінню сторінки через panel. Повільний layout може блокувати до loading сегмента — перевірте ієрархію.

2. Визначте охоплення помилок

error є Client Component і ловить нижні помилки, не свій layout вище. Для нього потрібна parent-межа чи global-error. Global UI має власні html і body. Event handlers і callbacks потребують окремої обробки.

3. Узгодьте відновлення з версією

Репозиторій має Next.js 16.2.10 з reset і unstable_retry. retry став stable у 16.3. reset очищує error без серверного refetch, retry перечитує й рендерить children. Не копіюйте нову сигнатуру в стару версію й не обіцяйте refresh від reset.

4. Збережіть точний статус і feedback

Після headers streaming не змінить HTTP-статус заднім числом. За потрібного status перевірте existence чи access раніше. Користувачу не потрібні raw exceptions — пояснення й reference. Retry не має повторювати неідемпотентну мутацію в render.

Приклад реалізації

Компонент для API 16.2 використовує явно нестабільний unstable_retry. Кнопка обіцяє перечитування, не лише очищення error. Це не політика повторів write. Стан мутації окремий, щоб втрачена відповідь не дублювала бронювання.

// app/reports/error.tsx — Next.js 16.2
"use client";

export default function ReportsError({
  error, unstable_retry,
}: {
  error: Error & { digest?: string };
  unstable_retry: () => void;
}) {
  return (
    <section aria-labelledby="reports-error">
      <h2 id="reports-error">Reports could not load</h2>
      <p>Reload the content, or return later.</p>
      {error.digest && <p>Reference: {error.digest}</p>}
      <button type="button" onClick={unstable_retry}>Reload content</button>
    </section>
  );
}

Компроміси та альтернативи

Fallback сегмента простий, окремі межі зберігають корисний контент. Надлишкові skeletons погіршують сприйняття. Очікувана порожнеча — звичайний стан, не error. Одиницю відновлення визначають доступні дії.

Поширені помилки

Уникайте fallback після await, хибного catch свого layout, raw messages і reset як refetch. Перевіряйте direct load, missing records, delay і denied read, не лише успішні переходи.

Перевірка перед випуском

  • Awaited work під loading-межою.
  • Layout і root мають parent scope.
  • Очікувані відмови мають звичайні стани.
  • Recovery-props відповідають Next.js.
  • Status-перевірки до streaming headers.

Поширені запитання

Чи error.tsx ловить помилку кліку?

Не як загальне правило. Взаємодію обробляють handler чи action-result, межа — помилки дерева.

Чи кожній відмові потрібен retry?

Лише для безпечного й доречного відновлення. Заборона, видалення й invalid-input потребують інших дій.

Наступний крок

Перевірте повільну область, missing-record і rendering-failure. UI лишається корисним, recovery відповідає назві й версії. HTTP-статус перевіряйте окремо від підсумкового браузера.

Первинні джерела

Пов’язані матеріали та приклади

Ігор Харчишин

Незалежний full-stack інженер продуктів, який пише посібники з реалізації розширень браузера та сучасних вебпродуктів на основі першоджерел.

Потрібно реалізувати це у вашому продукті?

Перегляньте відповідні приклади продуктів або поділіться контекстом розробки вебзастосунку, розширення Chrome, API чи SaaS.