Spec-Zone.ru › Next.js

Статические экспортные данные

Next.js позволяет начать как статический сайт или одностраничное приложение (SPA), а затем при необходимости обновить его, чтобы использовать функции, которые требуют сервера.

При выполнении next build, Next.js генерирует файл HTML для каждого маршрута. Разбив строгое SPA на отдельные файлы HTML, Next.js может избежать загрузки ненужного JavaScript-кода на стороне клиента, уменьшая размер пакета и ускоряя загрузку страниц.

Поскольку Next.js поддерживает этот статический экспорт, его можно развернуть и разместить на любом веб-сервере, который может обслуживать статические ресурсы HTML/CSS/JS.

Настройка

Для включения статического экспорта измените режим вывода внутри next.config.js:

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',
 
  // Optional: Change links `/me` -> `/me/` and emit `/me.html` -> `/me/index.html`
  // trailingSlash: true,
 
  // Optional: Prevent automatic `/me` -> `/me/`, instead preserve `href`
  // skipTrailingSlashRedirect: true,
 
  // Optional: Change the output directory `out` -> `dist`
  // distDir: 'dist',
}
 
module.exports = nextConfig

После выполнения next build, Next.js создаст папку out, которая содержит ресурсы HTML/CSS/JS вашего приложения.

Поддерживаемые функции

Основной функционал Next.js разработан для поддержки статических экспортов.

Компоненты сервера

При выполнении next build для генерации статического экспорта, компоненты сервера, используемые в каталоге app, будут выполняться во время сборки, подобно традиционной генерации статического сайта.

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

export default async function Page() {
  // This fetch will run on the server during `next build`
  const res = await fetch('https://api.example.com/...')
  const data = await res.json()
 
  return <main>...</main>
}

Компоненты клиента

Если вы хотите выполнять получение данных на клиенте, вы можете использовать компонент клиента с SWR для кэширования запросов.

'use client'
 
import useSWR from 'swr'
 
const fetcher = (url: string) => fetch(url).then((r) => r.json())
 
export default function Page() {
  const { data, error } = useSWR(
    `https://jsonplaceholder.typicode.com/posts/1`,
    fetcher
  )
  if (error) return 'Failed to load'
  if (!data) return 'Loading...'
 
  return data.title
}

Поскольку переходы по маршрутам происходят на стороне клиента, это ведёт себя как традиционное SPA. Например, следующий маршрут индекса позволяет переходить к различным записям на клиенте:

import Link from 'next/link'
 
export default function Page() {
  return (
    <>
      <h1>Index Page</h1>
      <hr />
      <ul>
        <li>
          <Link href="/post/1">Post 1</Link>
        </li>
        <li>
          <Link href="/post/2">Post 2</Link>
        </li>
      </ul>
    </>
  )
}

Оптимизация изображений

Оптимизация изображений через next/image может быть использована со статическим экспортом путём определения пользовательского загрузчика изображений в next.config.js. Например, вы можете оптимизировать изображения с помощью сервиса, такого как Cloudinary:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    loader: 'custom',
    loaderFile: './my-loader.ts',
  },
}
 
module.exports = nextConfig

Этот пользовательский загрузчик определит, как извлекать изображения из удалённого источника. Например, следующий загрузчик сформирует URL для Cloudinary:

export default function cloudinaryLoader({
  src,
  width,
  quality,
}: {
  src: string
  width: number
  quality?: number
}) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(
    ','
  )}${src}`
}

Затем вы можете использовать next/image в своём приложении, определять относительные пути к изображению в Cloudinary:

import Image from 'next/image'
 
export default function Page() {
  return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}

Обработчики маршрутов

Обработчики маршрутов будут отображать статический ответ при запуске next build. Поддерживается только HTTP-глагол GET. Это может быть использовано для генерации статического HTML, JSON, TXT или других файлов из кэшированных или некэшированных данных. Например:

export async function GET() {
  return Response.json({ name: 'Lee' })
}

Указанный выше файл app/data.json/route.ts будет отображен в статичный файл во время next build, создавая data.json, содержащий { name: 'Lee' }.

Если вам нужно читать динамические значения из входящего запроса, вы не можете использовать статический экспорт.

API браузера

Компоненты клиента предварительно рендерятся в HTML во время next build. Поскольку веб-API, такие как window, localStorage, и navigator, недоступны на сервере, вам нужно безопасно обращаться к этим API только при выполнении в браузере. Например:

'use client';
 
import { useEffect } from 'react';
 
export default function ClientComponent() {
  useEffect(() => {
    // You now have access to `window`
    console.log(window.innerHeight);
  }, [])
 
  return ...;
}

Неподдерживаемые функции

Функции, которые требуют сервера Node.js или динамической логики, которую нельзя вычислить во время процесса сборки, не поддерживаются:

  • Динамические маршруты с dynamicParams: true
  • Динамические маршруты без generateStaticParams()
  • Обработчики маршрутов, которые зависят от запроса
  • Файлы cookie
  • Перенаправления
  • Перенаправления
  • Заголовки
  • Средства
  • Инкрементная статическая регенерация
  • Оптимизация изображений с использованием стандартного loader
  • Режим черновика

Попытка использовать любую из этих функций со next dev приведёт к ошибке, аналогично установке параметра dynamic в значение error в макете корня.

export const dynamic = 'error'

Развёртывание

С помощью статического экспорта Next.js можно развернуть и разместить на любом веб-сервере, способном обслуживать статические ресурсы HTML/CSS/JS.

При выполнении next build, Next.js создаёт статический экспорт в папку out. Например, предположим, что у вас есть следующие маршруты:

  • /
  • /blog/[id]

После выполнения next build, Next.js сгенерирует следующие файлы:

  • /out/index.html
  • /out/404.html
  • /out/blog/post-1.html
  • /out/blog/post-2.html

Если вы используете статический хост, такой как Nginx, вы можете настроить перенаправление входящих запросов на соответствующие файлы:

server {
  listen 80;
  server_name acme.com;
 
  root /var/www/out;
 
  location / {
      try_files $uri $uri.html $uri/ =404;
  }
 
  # This is necessary when `trailingSlash: false`.
  # You can omit this when `trailingSlash: true`.
  location /blog/ {
      rewrite ^/blog/(.*)$ /blog/$1.html break;
  }
 
  error_page 404 /404.html;
  location = /404.html {
      internal;
  }
}

История версий

Версия Изменения
v14.0.0 next export был удалён в пользу "output": "export"
v13.4.0 Маршрутизатор приложений (стабильная версия) добавляет расширенную поддержку статического экспорта, включая использование компонентов React Server и обработчиков маршрутов.
v13.3.0 next export устарел и заменён на "output": "export"

© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/building-your-application/deploying/static-exports

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API