Серверный await
Получение REST-данных на сервере до первого HTML.
Серверный await — базовая стратегия для данных, которые нужны до рендера страницы или серверного блока.
Когда использовать
- Данные нужны для первого HTML.
- Данные влияют на
metadata. - По результату запроса нужно вызвать
notFound()илиredirect(). - Компонент серверный и данные не зависят от состояния браузера.
Влияние на рендер
Серверный await сам по себе не означает SSR. В App Router страница может остаться static/ISR, если маршрут не использует dynamic API и запросы можно кешировать.
ISR — приоритет для общих данных. Если список или детальная страница могут обновляться по интервалу, сохраняйте кеширование и не добавляйте no-store, revalidate: 0 или force-dynamic без требования.
SSR/dynamic rendering нужен, когда данные зависят от текущего request: cookie, headers, searchParams, preview-режим или персональные данные пользователя.
Пример страницы списка
// src/app/(routes)/pets/page.tsx
import { petStoreApi } from 'infrastructure/pet-store-api'
import { PetsScreen } from 'screens/pets'
export default async function PetsPage() {
const pets = await petStoreApi.pet.findPetsByStatus({
status: 'available',
})
return <PetsScreen pets={pets} />
}page.tsx получает данные первого рендера и передаёт их ниже. UI страницы остаётся в screens/, а не пишется прямо в app/.
Пример детальной страницы
// src/app/(routes)/pets/[id]/page.tsx
import { notFound } from 'next/navigation'
import { petStoreApi } from 'infrastructure/pet-store-api'
import { PetDetailScreen } from 'screens/pet-detail'
type PetPageProps = {
params: Promise<{ id: string }>
}
export default async function PetPage({ params }: PetPageProps) {
const { id } = await params
const pet = await petStoreApi.pet.getPetById(Number(id)).catch(() => null)
if (!pet) {
notFound()
}
return <PetDetailScreen pet={pet} />
}Обработка 404 зависит от API-клиента и класса ошибок. В примере показана идея: решение о notFound() принимается на уровне маршрута, а не внутри REST-клиента.
Что не делать
// Плохо — хуки нельзя вызывать в Server Component
const { data } = useGetPetList('available')
// Плохо — прямой fetch в обход клиента
const response = await fetch('https://petstore3.swagger.io/api/v3/pet/findByStatus')Если данные нужны на сервере, вызывайте метод REST-клиента напрямую.
Когда выбрать другую стратегию
- Несколько независимых запросов — Параллельные серверные запросы.
- Часть UI можно грузить отдельно — Передача промиса ниже.
- Данные нужны клиентскому хуку сразу после гидрации — Начальные данные для клиентских хуков.