#app_router — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #app_router, aggregated by home.social.
-
SEO‑поиск в Next.js App Router, индексируемые landing pages из фильтров и URL
Поиск в Next.js App Router связывает несколько механизмов — Server Components, dynamic routes, searchParams , metadata и клиентские фильтры. Если в проекте одна форма и несколько результатов, состояние можно держать в useState . В каталоге или агрегаторе каждый фильтр меняет URL, набор данных и правила индексации. В статье на примере учебного проекта EventMap — агрегатора событий, разберем, как спроектировать систему фильтрации, которая генерирует чистые, индексируемые URL для поисковых роботов и обновляет выдачу при изменении фильтров. Страницы вроде «Концерты в Москве» или «Выставки в Петербурге» могут работать как отдельные landing pages. Для них нужны серверный HTML, постоянный URL, свой title , description , h1 , canonical и отдельная политика index или noindex . Произвольные запросы, сортировки и глубокая пагинация остаются частью поиска и не попадают автоматически в индекс. Поиск построен через App Router, optional catch‑all route, серверный рендер результатов и общий набор функций для URL, metadata, canonical и sitemap. Поиск по каталогу создаёт отдельное состояние для каждой комбинации фильтров. Категория, город, дата, сортировка, поисковая строка и номер страницы попадают в URL. При десяти категориях, пятидесяти городах и пяти вариантах сортировки получается 2500 комбинаций без учёта пагинации и свободного текста. Интерфейс должен обработать все допустимые комбинации. В поисковый индекс обычно попадает только часть из них. Страница категории music , страница города london и сочетание music/london могут содержать устойчивую подборку. Запрос ?q=free+jazz+tonight , сортировка по цене и восьмая страница выдачи относятся к текущему действию пользователя. Фильтры без отдельной политики создают большое пространство URL. Google описывает эту проблему в документации по faceted navigation. Изменение каждого параметра создаёт новый адрес, краулер тратит запросы на многочисленные комбинации и позже обнаруживает, что многие из них не содержат самостоятельного материала. ( Google for Developers )
https://habr.com/ru/articles/1063570/
#nextjs #seo #typescript #react #javascript #app_router #server_components #canonical #sitemap #noindex
-
Optimistic UI и autosave в Next.js без гонок и ложного сохранено
Optimistic UI и autosave выглядят как естественное улучшение интерфейса. Хочется, чтобы новый элемент появлялся сразу, текст не терялся, статус сохранения успокаивал пользователя, а редактор не дёргался на каждом символе. Но здесь интерфейс начинает врать. Новый проект уже нарисован в списке, хотя сервер его ещё не подтвердил. Статус показывает saved, хотя это был ответ от старого запроса. updatedAt обновился, хотя запись на сервере не прошла. В какой-то момент становится ясно, что скорость интерфейса и правдивость интерфейса это разные вещи. В моем учебном проекте Workbench эта граница показана на двух местах. Первое это optimistic create для inline CRUD. Второе это autosave редактора и отдельное демо с requestId. В обоих случаях задача одна и та же. UI должен быть быстрым, но не должен придумывать серверную истину раньше времени. Иначе вместо отзывчивости получается рассинхрон.
https://habr.com/ru/articles/1059760/
#nextjs #typescript #app_router #optimistic_ui #autosave #server_actions #react #вебразработка
-
Server Actions без ручного API, предсказуемый useActionState для inline CRUD в Next.js
В Next.js формы и inline CRUD довольно быстро упираются в одну и ту же развилку. Можно пойти привычным путём и собрать ручной API: отдельный route handler, fetch из клиента, локальные флаги pending, error, success, плюс своя логика для blur, Enter, Escape и закрытия редактора. На небольшом примере это выглядит терпимо. Но как только в проекте появляются создание, переименование, удаление и несколько inline-форм на одном экране, код начинает расползаться не по бизнес-логике, а по обвязке. Проблема в количестве промежуточных слоёв между формой и записью данных. Отдельный endpoint, отдельный клиентский submit, отдельный формат ответа, отдельные флаги состояния, отдельная синхронизация UI после успеха или ошибки. Для таких сценариев Server Actions в App Router нужны потому, что для форм и inline-редактирования дают более короткую и предсказуемую write-точку. В проекте примере Workbench покажем на создании, переименовании и удалении проектов, секций и заметок. У формы есть action, серверная функция получает FormData, возвращает типизированное состояние, а клиент живёт вокруг одного паттерна: state, formAction, isPending. В результате форма собирается как связанный цикл, а не как набор разрозненных обработчиков.
https://habr.com/ru/articles/1043970/
#nextjs #typescript #app_router #server_actions #useactionstate #react #forms #вебразработка
-
Route Handlers как мини-бэкенд внутри Next.js App Router
Когда проект на Next.js только начинается, прямой fetch во внешний API кажется самым коротким путём. Есть страница списка, есть поиск, есть внешний источник данных, значит можно сходить туда напрямую и сразу показать результат. На маленьком экране это работает. Но дальше почти всегда начинаются одинаковые проблемы. Интерфейс начинает зависеть от чужой структуры ответа. Ошибки приходят в форме, которую неудобно показывать пользователю. Параметры запроса приходится валидировать в UI. Потом появляется базовый URL, который не хочется держать строкой в коде. Затем появляется ключ или другой секрет, который уже нельзя светить в браузере. В этот момент становится видно, что между UI и внешним API не хватает серверной границы. В App Router такую роль часто закрывает Route Handlers. В официальной документации Next.js они описаны как пользовательские обработчики запросов внутри app directory на основе стандартных Web Request и Response API. Они доступны только в app , по смыслу заменяют старые API Routes из pages и поддерживают GET , POST , PUT , PATCH , DELETE , HEAD и OPTIONS . (
https://habr.com/ru/articles/1042048/
#nextjs #app_router #route_handlers #proxy_api #environment_variables #next_public #server_components #react #javascript #вебразработка
-
Кэширование в Next.js App Router, как увидеть, почему данные не обновились
С кэшированием в Next.js обычно случается одна и та же история. API уже отдаёт новые данные, страница открывается заново, а на экране всё ещё старая версия. После этого в код быстро добавляют cache: "no-store" , данные начинают запрашиваться на каждый заход, и через пару минут появляется уже другой вопрос - зачем тогда вообще нужен встроенный механизм кэширования. Проблема в том, что кэширование обычно звучит как одно явление, а на практике в App Router похожие ощущения могут давать разные уровни поведения. Навигация назад и вперёд может переиспользовать клиентский кэш маршрута, сам маршрут может рендериться по-разному, а серверный fetch в Next.js имеет собственные стратегии кэширования и перевалидации. В актуальной документации это уже разделено на новый режим с Cache Components и на прежнюю модель без них. В этой статье речь именно о привычной модели App Router без Cache Components, где поведение обычно задаётся через fetch , cache , next.revalidate и route segment config. ( Next.js ) Полезнее всего разбирать такую тему не с теории, а с наблюдения. Не с вопроса как устроены все слои кэша в Next.js, а с вопроса почему на одном и том же маршруте иногда обновляется рендер страницы, а иногда обновляются данные, и это не всегда одно и то же. Для примеров ниже используется проект Goods Finder и внешний API DummyJSON. Идея - сначала добавить на страницу штамп серверного рендера, потом отдельно показать момент получения данных, а уже после этого сравнить force-cache , no-store и revalidate .
https://habr.com/ru/articles/1030134/
#nextjs #app_router #caching #revalidate #nostore #forcecache #server_components #react #javascript #вебразработка
-
Формы как контракт в Next.js: Zod, fieldErrors и одинаковые правила на client и server
С формами в Next.js проблема обычно начинается не на уровне кнопки submit. Кнопка как раз почти всегда работает. Настоящая путаница начинается позже, когда форма уже живёт в проекте какое-то время. В одном месте ошибка показывается под полем, в другом только общей строкой сверху. Где-то кнопка блокируется на pending, а где-то можно отправить запрос несколько раз подряд. Клиент считает данные валидными, а сервер отвечает, что правило нарушено. Поле уже зелёное, а сохранение всё равно не прошло. В этот момент становится видно, что форма была собрана как кусок UI, а не как контракт. Используем как примеры паттерны из проекта Workbench. Полезно смотреть на форму не как на набор input и submit, а как на договор между UI, валидацией и местом записи данных. У такого договора есть простая форма - какие данные считаются допустимыми, где и как они проверяются, в каком виде ошибка возвращается в интерфейс, что происходит на pending, когда форма блокируется, что считается успехом, а что общей ошибкой, не привязанной к конкретному полю. Как только форма описывается так, код перестаёт расползаться. И здесь Zod в Next.js даёт не просто удобную схему, а способ удерживать client и server в одном наборе правил.
https://habr.com/ru/articles/1025472/
#nextjs #typescript #app_router #zod #forms #validation #react #вебразработка
-
TypeScript в Next.js как система контрактов, а не типизация ради типизации
Когда разработчик начинает писать на Next.js с TypeScript, первая реакция часто довольно холодная. Вместо того чтобы двигаться быстрее, он начинает чаще видеть ошибки. Где-то не совпал shape объекта, где-то строка не подходит в более узкий тип, где-то TypeScript напоминает, что значение может быть undefined. На этом месте легко сделать неправильный вывод. Кажется, что TS просто добавляет трение и требует больше служебного кода. Обычно проблема не в TypeScript, а в способе мышления. Если использовать его как набор аннотаций поверх уже написанного кода, пользы действительно немного. Но если смотреть на типы как на систему контрактов между слоями приложения, картина меняется. Особенно в Next.js App Router, где у нас постоянно есть границы server и client, внешний ввод из URL, формы, мутации и разные состояния интерфейса. В этот момент TypeScript перестаёт быть типизацией ради типизации. Он начинает отвечать на более важный вопрос: какие состояния в проекте вообще допустимы, а какие не должны пройти дальше границы. По такой модели я выстроил один из своих проектов Workbench. Не начинать с мысли давайте везде поставим типы, а начинать с мысли где у нас проходит граница, что в неё входит и что из неё может выйти. После этого многие решения в коде становятся почти очевидными.
https://habr.com/ru/articles/1018382/
#nextjs #typescript #app_router #server_components #type_safety #zod #react #вебразработка
-
URL как источник правды в Next.js App Router
Когда разработчик приходит в Next.js из обычного React SPA, он часто тащит с собой старую схему мышления. Есть поле ввода, значит будет useState . Есть поиск, значит будет useEffect . Есть список данных, значит будем следить за изменением состояния и вручную запускать новый запрос. На маленьком экране это вроде работает. Но очень быстро выясняется, что в приложении уже не одно состояние, а три. Есть значение в поле, значение в URL, данные, загруженные по одному из этих значений. Потом появляется четвёртая проблема. Кнопки Back и Forward начинают вести себя странно. Ссылкой на результат поиска неудобно делиться. А отладка превращается в угадайку, потому что не до конца понятно, что именно сейчас считается главным источником правды. В App Router это решается проще. Если фильтр является частью состояния страницы, его логично держать в URL. Тогда схема становится прямой: URL изменился -> сервер прочитал searchParams -> выполнил fetch -> отрендерил новый список. В этот момент Next.js начинает восприниматься как понятный инженерный инструмент.
https://habr.com/ru/articles/1016068/
#nextjs #nextjs_app_router #app_router #searchparams #url_state #server_components #react #javascript #вебразработка
-
Как я устал вручную писать сервис-воркеры и сделал next-pwa-pack, чтобы больше не страдать
Сколько лет уже кто-то говорит: «А можно, чтобы оно работало без интернета и ставилось на домашний экран?» И каждый раз после этой фразы начинается медленный спуск в персональный ад — ты лезешь в документацию по PWA, где всё разваливается на ровном месте, service worker живёт своей жизнью, кеш то работает, то ломается, App Router рушит весь твой кастомный пайплайн, а пользователи сидят на старых версиях, потому что вручную обновлять им, конечно, влом. Словом, если ты когда-то пробовал прикрутить оффлайн-режим к Next.js-проекту, ты наверняка вспоминал всех, кто придумал этот стек. Я — точно. Поэтому, как человек, у которого было слишком много кофе и слишком мало терпения, я сделал единственное разумное: написал свою обёртку. Так и появился next-pwa-pack — дроп-ин пакет, который превращает любой Next.js-проект в полноценное PWA, буквально одной строкой. Да, даже с App Router. Просто заворачиваешь свой layout в PWAProvider, и всё: приложение можно установить, оно кэширует страницы, работает оффлайн, синхронизирует вкладки и даже показывает отладочную панель, чтобы не гадать, сработало ли что-нибудь. Воткнул — и живи дальше. А то: Сервис-воркер? Напиши вручную. Кешировать HTML? Сам придумай как. Синхронизация вкладок? Ну это уже магия, удачи. Обновление кеша после деплоя? Ну ты ж senior, сам справишься. 🤡 И ты сидишь, как идиот, с 300 вкладками про Workbox, cache-first , network-only , костылями из Stack Overflow 2019 года, и потеешь. Если раньше каждый запрос «сделай оффлайн» вызывал у меня флэшбэк на тему next-pwa, неподдерживаемых версий, кривого кеша и плясок с бубном вокруг обновлений — теперь всё это ушло. Я хотел простой setup, который просто работает: предзагрузка, нормальные TTL, понятное обновление и синхронизация. Без фокусов, без багов, без “подожди, сейчас DevTools открою”. Погнали дальше!
https://habr.com/ru/articles/935024/
#nextjs #progressive_web_apps #app_router #serviceworker #reactjs #react
-
Путешествие по Next.js: от ошибок с not-found до форка next-runtime-env
Недавно столкнулся с интересным багом в Next.js. Если на странице not-found делать навигацию через router.push(pathname) , теряются все переменные окружения, которые мы инициализируем через библиотеку next-runtime-env (значение window.__ENV становится undefined ). В проекте мы используем next-runtime-env , так как придерживаемся подхода Build once, deploy many — это позволяет держать один Docker-образ, в который при запуске прокидываются нужные переменные окружения. Next.js из коробки не поддерживает такое поведение, ведь он хочет собирать env-переменные на этапе сборки приложения. Баг проявился на not-found странице, где у нас есть кнопка, позволяющая создать элемент в один клик, если что-то не найдено. Этот же компонент кнопки используется и на других страницах, и вот что интересно: на остальных страницах router.push(pathname) работает корректно, а на not-found — нет. Сначала я подумал, что проблема кроется в next-runtime-env . Наверное, библиотека переопределяется при обновлении страницы, потому что скрипт, устанавливающий переменные в window.__ENV , размещён в root layout. Я также пробовал версионировать Next.js, предполагая, что баг связан с определёнными версиями фреймворка, но это не дало результатов. В итоге, временным решением стало использование window.location.href , что предотвращало рефреш страницы и помогало сохранить переменные. Однако на этом история не закончилась.
https://habr.com/ru/articles/847586/
#nextjs #nextjs_14 #frontend #react #reactjs #serverside_rendering #app_router #nextruntimeenv