Next.js + Yandex Object Storage = Не работают ссылки

Очень часто при попытке хостить Next.js приложение использующее App Router в S3 бакете можно столкнуться с тем что страницы приложения не открываются при заходе по прямой ссылке.

Next.js + Yandex Object Storage = Не работают ссылки
Дата публикации
13.05.24
Дата обновления
16.05.26
Время чтения
3 мин.

Размещая этот блог в Yandex Object Storage мы столкнулись с некоторыми проблемами.

В этой статье мы расскажем об одной из них.

Проблема

Очень часто при попытке хостить Next.js приложение использующее App Router в S3 бакете можно столкнуться с тем что:

  • Страницы приложения не открываются при заходе по прямой ссылке,
  • при этом при переходе через нажатие по внутренней ссылке всё работает как надо.

На первый взгляд такое поведение вводит в ступор. Но у этой ситуации есть две вполне логичные причины.

Причина 1

По умолчанию для страницы /about генерируются страницы вида /about.html.

Такой формат файлов не подходит для того чтобы хоститься в S3 бакете по той причине что URL-адрес example.com/about будет всегда отвечать ошибкой 404.

Происходит это потому что в бакете нет объекта с таким именем.

Для того чтобы получить этот объект URL-адрес должен содержать ещё и расширение файла (example.com/about.html)

Причина 2

По умолчанию Next.js перенаправляет URL-адреса с косой чертой в конце на их аналог без косой черты в конце.

Например, /about/ будет перенаправляться на /about.

Нам нужно настроить это поведение так, чтобы оно действовало противоположным образом:

URL-адреса без завершающих косых черт должны перенаправляться на их аналоги с завершающими косыми чертами.

Решение

Чтобы изменить поведение по умолчанию, нужно изменить пару параметров в файле next.config.js.

Добавляем настройку trailingSlash со значением true.

  trailingSlash: true,

И проверяем что значением поля output является export.

  output: "export",

Итоговый конфиг должен выглядеть следующим образом:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "export",
  trailingSlash: true,
};

module.exports = nextConfig;

При такой конфигурации страница /about генерит файл /about/index.html (вместо /about.html по умолчанию).

В таком случае при обращении по адресу example.com/about:

  • Next.js перенаправит нас по адресу example.com/about/
  • Бакет при обращении по адресу example.com/about/ отдаст нам файл /about/index.html

И мы увидим искомую страницу! 🎉

На этом всё. Спасибо за внимание!

Расскажите о вашем проекте

Связаться иначе

Часто задаваемые вопросы

При клиентской навигации Next.js подгружает уже собранные маршруты в браузере. Прямой заход по URL — это запрос к S3-бакету: он ищет объект с точным путём в хранилище. Если файл лежит как /about.html, а запрашивают /about, бакет вернёт 404, хотя в SPA переход с главной сработает.

По умолчанию Next.js убирает слэш в конце URL (/about//about). Для статики в бакете удобнее обратное поведение: /about редиректится на /about/, и S3 отдаёт /about/index.html — стандартный способ раздавать «папку» как страницу.

Режим статического экспорта: при next build генерируются готовые HTML/CSS/JS-файлы без Node.js-сервера. Именно их нужно загружать в Object Storage; SSR, API Routes и серверные компоненты с динамикой на сервере в этом режиме недоступны.

Так по умолчанию собирает Next.js без trailingSlash: true. Файл about.html соответствует URL с расширением (/about.html), а не «чистому» пути /about, который ожидают пользователи и настройки веб-хостинга в бакете.

Да, статья как раз про App Router на статическом экспорте. Важно, чтобы маршруты можно было собрать статически; динамические сегменты без generateStaticParams и серверные фичи без статической генерации в output: "export" не подойдут.

Заново выполните next build, загрузите содержимое папки out (или каталога экспорта вашей версии Next.js) в бакет, заменив старые файлы. Проверьте прямой заход по URL вложенных страниц и главной в режиме инкогнито.

Пошаговая инструкция по Yandex Object Storage, Cloud DNS и сертификату — в статье Хостинг в S3 от Яндекса. Текущий материал дополняет её настройками именно для Next.js.

Вам может быть интересно

Хостинг в S3 от Яндекса
Хостинг в S3 от Яндекса

Хостинг в S3 от Яндекса

6 мин.

Рассказываем как использовать Yandex Object Storage для хостинга статического сайта...

Пост#yandex
Добавляем Not Found (404) страницу в Next.js приложение
Добавляем Not Found (404) страницу в Next.js приложение

Добавляем Not Found (404) страницу в Next.js приложение

3 мин.

Инструкция по добавлению Not Found (404) страницы в Next.js приложение...

Пост#nextjs#seo
Добавляем sitemap.xml в Next.js приложение
Добавляем sitemap.xml в Next.js приложение

Добавляем sitemap.xml в Next.js приложение

9 мин.

Инструкция по добавлению sitemap.xml в Next.js приложение...

Пост#nextjs#seo
Добавляем robots.txt в Next.js приложение
Добавляем robots.txt в Next.js приложение

Добавляем robots.txt в Next.js приложение

5 мин.

Инструкция по добавлению robots.txt в Next.js приложение...

Пост#nextjs#seo
Подключение счётчика Яндекс Метрики к Next.js приложению
Подключение счётчика Яндекс Метрики к Next.js приложению

Подключение счётчика Яндекс Метрики к Next.js приложению

13 мин.

Инструкция по добавлению счётчика Яндекс Метрики к Next.js блогу...

Пост#nextjs#yandex
Добавляем поиск по тегам в статический блог на Next.js
Добавляем поиск по тегам в статический блог на Next.js

Добавляем поиск по тегам в статический блог на Next.js

5 мин.

Инструкция по добавлению простейшего поиска по тегам в статическом Next.js блоге...

Пост#туториалы#nextjs
Добавляем пагинацию в статический блог на Next.js
Добавляем пагинацию в статический блог на Next.js

Добавляем пагинацию в статический блог на Next.js

4 мин.

Инструкция по добавлению пагинации постов в статическом блоге на Next.js...

Пост#туториалы#nextjs
Добавляем RSS-фид к статическому Next.js приложению
Добавляем RSS-фид к статическому Next.js приложению

Добавляем RSS-фид к статическому Next.js приложению

5 мин.

Инструкция по добавлению RSS фида к статическому Next.js приложению...

Пост#nextjs#фиды
Frontend разработка
Frontend разработка

Frontend разработка

Разрабатываем интерфейсы, которые быстро работают, удобно используются и масштабируются вместе с продуктом.

Услуга#frontend#веб-разработка