Menu

Statische Exporte

Next.js ermöglicht es, als statische Website oder Single-Page-Anwendung (SPA) zu starten und später optional Funktionen zu aktivieren, die einen Server erfordern.

Bei Ausführung von next build generiert Next.js pro Route eine HTML-Datei. Indem eine strikte SPA in einzelne HTML-Dateien aufgeteilt wird, kann Next.js das Laden von unnötigem JavaScript-Code auf der Clientseite vermeiden und so die Bundle-Größe reduzieren und schnellere Seitenladevorgänge ermöglichen.

Da Next.js diesen statischen Export unterstützt, kann er auf jedem Webserver bereitgestellt und gehostet werden, der statische HTML/CSS/JS-Assets bedienen kann.

Konfiguration

Um einen statischen Export zu aktivieren, ändern Sie den Ausgabemodus in next.config.js:

next.config.js
/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',
 
  // Optional: Ändert Links `/me` -> `/me/` und erzeugt `/me.html` -> `/me/index.html`
  // trailingSlash: true,
 
  // Optional: Verhindert automatische Umleitung `/me` -> `/me/`, stattdessen wird `href` beibehalten
  // skipTrailingSlashRedirect: true,
 
  // Optional: Ändert das Ausgabeverzeichnis `out` -> `dist`
  // distDir: 'dist',
}
 
module.exports = nextConfig

Nach Ausführung von next build wird Next.js einen out-Ordner erzeugen, der die HTML/CSS/JS-Assets für Ihre Anwendung enthält.

Unterstützte Funktionen

Der Kern von Next.js wurde entwickelt, um statische Exporte zu unterstützen.

Server-Komponenten

Bei Ausführung von next build zur Generierung eines statischen Exports werden Server-Komponenten innerhalb des app-Verzeichnisses während des Build-Prozesses ausgeführt, ähnlich der traditionellen statischen Site-Generierung.

Die resultierende Komponente wird in statisches HTML für den initialen Seitenaufruf und eine statische Payload für Client-Navigation zwischen Routen gerendert. Für Server-Komponenten sind keine Änderungen beim statischen Export erforderlich, es sei denn, sie verwenden dynamische Serverfunktionen.

app/page.tsx
TypeScript
export default async function Page() {
  // Dieser Fetch wird während `next build` auf dem Server ausgeführt
  const res = await fetch('https://api.example.com/...')
  const data = await res.json()
 
  return <main>...</main>
}

Client-Komponenten

Wenn Sie Daten auf dem Client abrufen möchten, können Sie eine Client-Komponente mit SWR verwenden, um Anfragen zu memoisieren.

app/other/page.tsx
TypeScript
'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 'Laden fehlgeschlagen'
  if (!data) return 'Lädt...'
 
  return data.title
}

Da Routenübergänge clientseitig erfolgen, verhält sich dies wie eine traditionelle SPA. Die folgende Index-Route erlaubt beispielsweise die Navigation zu verschiedenen Posts auf dem Client:

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

Bildoptimierung

Bildoptimierung durch next/image kann mit einem statischen Export verwendet werden, indem ein benutzerdefinierter Bildlader in next.config.js definiert wird. Beispielsweise können Sie Bilder mit einem Dienst wie Cloudinary optimieren:

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

Dieser benutzerdefinierte Loader definiert, wie Bilder von einer Remote-Quelle abgerufen werden. Der folgende Loader konstruiert beispielsweise die URL für Cloudinary:

my-loader.ts
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}`
}
my-loader.js
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}`
}

Sie können dann next/image in Ihrer Anwendung verwenden und relative Pfade zum Bild in Cloudinary definieren:

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

Routen-Handler

Routen-Handler rendern eine statische Antwort bei Ausführung von next build. Nur die HTTP-Methode GET wird unterstützt. Dies kann verwendet werden, um statische HTML-, JSON-, TXT- oder andere Dateien aus zwischengespeicherten oder nicht zwischengespeicherten Daten zu generieren. Beispiel:

app/data.json/route.ts
export async function GET() {
  return Response.json({ name: 'Lee' })
}
app/data.json/route.js
export async function GET() {
  return Response.json({ name: 'Lee' })
}

Die obige Datei app/data.json/route.ts wird während next build in eine statische Datei gerendert und erzeugt data.json mit dem Inhalt { name: 'Lee' }.

Wenn Sie dynamische Werte aus der eingehenden Anfrage lesen müssen, können Sie keinen statischen Export verwenden.

Browser-APIs

Client-Komponenten werden während next build in HTML vorgerendert. Da Web-APIs wie window, localStorage und navigator auf dem Server nicht verfügbar sind, müssen Sie sicher nur beim Ausführen im Browser auf diese APIs zugreifen. Beispiel:

'use client';
 
import { useEffect } from 'react';
 
export default function ClientComponent() {
  useEffect(() => {
    // Sie haben jetzt Zugriff auf `window`
    console.log(window.innerHeight);
  }, [])
 
  return ...;
}

Nicht unterstützte Funktionen

Funktionen, die einen Node.js-Server erfordern oder dynamische Logik benötigen, die während des Build-Prozesses nicht berechnet werden kann, werden nicht unterstützt:

Der Versuch, eine dieser Funktionen mit next dev zu verwenden, führt zu einem Fehler, ähnlich wie beim Setzen der dynamic-Option auf error im Root-Layout.

export const dynamic = 'error'

Bereitstellung

Mit einem statischen Export kann Next.js auf jedem Webserver bereitgestellt und gehostet werden, der statische HTML-/CSS-/JS-Assets bedienen kann.

Bei Ausführung von next build generiert Next.js den statischen Export in den out-Ordner. Nehmen wir beispielsweise an, Sie haben die folgenden Routen:

  • /
  • /blog/[id]

Nach Ausführung von next build generiert Next.js die folgenden Dateien:

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

Wenn Sie einen statischen Host wie Nginx verwenden, können Sie Weiterleitungen von eingehenden Anfragen zu den richtigen Dateien konfigurieren:

nginx.conf
server {
  listen 80;
  server_name acme.com;
 
  root /var/www/out;
 
  location / {
      try_files $uri $uri.html $uri/ =404;
  }
 
  # Dies ist notwendig, wenn `trailingSlash: false`.
  # Sie können dies weglassen, wenn `trailingSlash: true`.
  location /blog/ {
      rewrite ^/blog/(.*)$ /blog/$1.html break;
  }
 
  error_page 404 /404.html;
  location = /404.html {
      internal;
  }
}

Versionshistorie

VersionÄnderungen
v14.0.0next export wurde zugunsten von "output": "export" entfernt
v13.4.0App Router (stabil) fügt erweiterte statische Export-Unterstützung hinzu, einschließlich Verwendung von React Server Components und Route Handlers.
v13.3.0next export ist veraltet und wird durch "output": "export" ersetzt