Как создать статический экспорт приложения Next.js

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

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

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

Конфигурация

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

next.config.js
/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',

  // Опционально: Изменяет ссылки `/me` -> `/me/` и создаёт `/me.html` -> `/me/index.html`
  // trailingSlash: true,

  // Опционально: Отключает автоматическое преобразование `/me` -> `/me/`, сохраняя оригинальный `href`
  // skipTrailingSlashRedirect: true,

  // Опционально: Изменяет выходную директорию `out` -> `dist`
  // distDir: 'dist',
}

module.exports = nextConfig

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

Вы можете использовать getStaticProps и getStaticPaths для генерации HTML-файла для каждой страницы в директории pages (или больше для динамических маршрутов).

Поддерживаемые возможности

Большинство основных функций Next.js для создания статических сайтов поддерживаются, включая:

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

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

next.config.js
/** @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}`
}
export default function cloudinaryLoader({ src, width, quality }) {
  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="черепахи" src="/turtles.jpg" width={300} height={300} />
}
import Image from 'next/image'

export default function Page() {
  return <Image alt="черепахи" src="/turtles.jpg" width={300} height={300} />
}

Неподдерживаемые возможности

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

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

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

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

  • /
  • /blog/[id]

Будут сгенерированы файлы:

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

Для статических хостов типа Nginx можно настроить реврайты запросов:

nginx.conf
server {
  listen 80;
  server_name acme.com;

  root /var/www/out;

  location / {
      try_files $uri $uri.html $uri/ =404;
  }

  # Необходимо при `trailingSlash: false`.
  # Можно опустить при `trailingSlash: true`.
  location /blog/ {
      rewrite ^/blog/(.*)$ /blog/$1.html break;
  }

  error_page 404 /404.html;
  location = /404.html {
      internal;
  }
}

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

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