ПРАКТИЧЕСКИЙ РАЗБОР · 7 минут

Почему Next.js работает локально, но ломается после деплоя

Разбираем ошибки сборки Next.js, переменные окружения, серверные запросы и проверку production перед публикацией

Вы сделали приложение на Next.js. Команда npm run dev запускает сайт, страницы открываются, поиск работает. Затем вы отправляете проект на Vercel или другой хостинг. Сборка завершается ошибкой либо сайт публикуется, но часть функций перестаёт работать.

Такое расхождение встречается, когда среда разработки отличается от той, в которой приложение собирается и запускается для пользователей. Причина может быть в коде, переменных окружения, внешнем API или способе выполнения серверных функций. Разберём, что проверять и в каком порядке.

Сначала определите, где возникает ошибка

Проблемы после деплоя разделим на три случая.

Сборка не завершилась. Хостинг показывает ошибку во время next build. Сайт с новой версией не опубликован. Нужно изучить журнал сборки и найти первое сообщение об ошибке.

Сборка прошла, но страница не открывается. Приложение запущено, однако определённый маршрут возвращает ошибку. В этом случае нужно смотреть журналы серверного выполнения.

Страница открывается, но функция не работает. Например, интерфейс отображается, а поиск не получает данные. Здесь понадобятся инструменты браузера и проверка запросов к API.

Не стоит начинать с переустановки всех зависимостей. Сначала нужно понять, на каком этапе ломается приложение.

Проверьте production-сборку локально

Режим next dev рассчитан на разработку. Он не заменяет проверку production-сборки. Перед публикацией выполните команды из корня проекта.

npm run lint
npm run typecheck
npm run build
npm run start

Команды lint и typecheck должны существовать в package.json вашего проекта. В Next.js их можно настроить отдельно. Если таких скриптов нет, используйте принятые в проекте команды ESLint и TypeScript. npm run build собирает production-версию приложения. npm run start запускает её локально. После этого откройте сайт и повторите действия, которые раньше проверяли через npm run dev.

Если ошибка проявилась уже здесь, она не зависит от конкретного хостинга. Нужно исправить код или конфигурацию до отправки проекта.

Почему на сервере не находится переменная окружения

Одна из частых причин связана с переменными окружения. Локально приложение читает значения из .env.local, но на хостинге этих значений нет. Предположим, сервер Next.js обращается к внешнему API через переменную API_BASE_URL. На вашем компьютере она настроена, а в настройках production не добавлена. Тогда код может сформировать неправильный адрес запроса или завершиться ошибкой.

Проверьте, какие значения требуются приложению, где они заданы и для какой среды доступны. На хостингах часто разделяются Development, Preview и Production.

При этом секретные ключи нельзя переносить в переменные с префиксом NEXT_PUBLIC_. Такие значения могут попасть в браузерный JavaScript. Есть ещё одна особенность. Публичные переменные NEXT_PUBLIC_ подставляются в клиентский код во время сборки. Если изменить такое значение после создания сборки, уже собранный клиентский код автоматически не обновится. Понадобится новая сборка.

Не выводите содержимое секретных переменных в логи ради диагностики. Достаточно проверить факт их наличия и правильность конфигурации.

Проверьте адреса запросов

Локально frontend может обращаться к API по адресу http://localhost:8000. На вашем компьютере сервер действительно работает по этому адресу. После деплоя слово localhost означает уже другое окружение. Если запрос выполняется в браузере посетителя, это его собственный компьютер. Если запрос отправляет сервер приложения, это серверная среда хостинга. Поэтому нельзя рассчитывать, что адрес локального Django продолжит работать после публикации Next.js.

Для production используйте публичный адрес backend либо серверный маршрут приложения, который обращается к нужному сервису. Проверьте также настройки CORS, если браузер отправляет запросы напрямую на другой домен.

В инструментах разработчика браузера откройте вкладку Network. Посмотрите фактический адрес запроса, HTTP-статус и ответ сервера. Это поможет отличить ошибку маршрутизации от отказа API.

Почему серверный код ведёт себя иначе

В Next.js App Router часть компонентов выполняется на сервере. Такой код не может напрямую обращаться к window и localStorage, потому что этих объектов нет в серверной среде. Иногда ошибка возникает ещё на этапе сборки, когда Next.js пытается подготовить страницу. В другом случае проблема появляется только при открытии определённого маршрута.

Если библиотека зависит от браузера, её нужно использовать в подходящем клиентском компоненте. Но добавление "use client" ко всей странице не всегда решает проблему. Клиентские компоненты тоже могут участвовать в серверной подготовке HTML, поэтому обращения к браузерным объектам следует размещать в соответствующем жизненном цикле или обработчиках событий.

В моей статье на Habr о проверке Next.js перед production разобраны сборка, изображения и метаданные. Отдельная статья «Почему useEffect в React запускается дважды» объясняет, как работать с эффектами в клиентских компонентах.

Что делать, если не работает только одна страница

Допустим, главная открывается, а страница каталога возвращает ошибку. Проверьте, какие данные она загружает, какие параметры получает и какие серверные функции выполняет. Возможно, внешний API недоступен или возвращает ответ другой структуры. Возможно, на хостинге отсутствует нужная переменная. Иногда проблема связана с кэшированием и тем, когда именно Next.js запрашивает данные.

Для диагностики нужно найти первый неуспешный шаг. Не ограничивайтесь сообщением «Application error» на экране. Изучите серверный журнал и запросы, которые выполнялись перед ошибкой. Отдельно проверьте поведение, когда внешний источник временно недоступен. Приложение должно корректно обрабатывать такой случай, а не рассчитывать, что API всегда возвращает успешный ответ.

Как проверять сайт перед следующей публикацией

После исправления повторите production-сборку и пройдите несколько пользовательских сценариев. Откройте главную страницу, перейдите в каталог, выполните поиск и проверьте карточку товара.

Эти действия можно автоматизировать с помощью Playwright. В статье «Как проверить работу сайта с помощью Playwright» показан первый браузерный тест после сборки.

Для небольшого приложения достаточно сначала проверить основные маршруты и один путь пользователя. Затем набор проверок можно расширять по мере появления новых функций.

От локального проекта к опубликованному приложению

В демонстрационном Goods Finder можно посмотреть приложение на Next.js с каталогом, поиском и маршрутизацией.

Курс «Next.js I: JavaScript 2026» проходит путь от компонентов App Router до работы с данными, переменными окружения и деплоя приложения.

Если сайт работает в next dev, это подтверждает только работу в среде разработки. Проверка build, запуск production-версии и просмотр реальных запросов помогают найти расхождения до того, как они появятся у посетителей.