Statische Exporte
Next.js ermöglicht den Start als statische Website oder Single-Page Application (SPA), mit der Option, später Server-Funktionen hinzuzufügen.
Bei Ausführung von next build
generiert Next.js eine HTML-Datei pro Route. Durch die Aufteilung einer strikten SPA in einzelne HTML-Dateien kann Next.js unnötigen JavaScript-Code auf der Client-Seite vermeiden, was die Bundle-Größe reduziert und schnellere Seitenladezeiten ermöglicht.
Da Next.js diesen statischen Export unterstützt, kann er auf jedem Webserver bereitgestellt und gehostet werden, der statische HTML/CSS/JS-Assets bereitstellen kann.
Konfiguration
Um einen statischen Export zu aktivieren, ändern Sie den Ausgabemodus in 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 `/me` -> `/me/`, behält stattdessen `href` bei
// skipTrailingSlashRedirect: true,
// Optional: Ändert das Ausgabeverzeichnis `out` -> `dist`
// distDir: 'dist',
}
module.exports = nextConfig
Nach Ausführung von next build
erzeugt Next.js einen out
-Ordner, der die HTML/CSS/JS-Assets für Ihre Anwendung enthält.
Unterstützte Funktionen
Der Kern von Next.js wurde für statische Exporte entwickelt.
Server-Komponenten
Bei Ausführung von next build
für einen statischen Export werden Server-Komponenten im app
-Verzeichnis während des Builds ausgeführt, ähnlich wie bei traditioneller statischer Seiten-Generierung.
Die resultierende Komponente wird in statisches HTML für den initialen Seitenaufruf und eine statische Nutzlast für die Client-Navigation zwischen Routen gerendert. Für Ihre Server-Komponenten sind keine Änderungen erforderlich, es sei denn, sie verwenden dynamische Server-Funktionen.
export default async function Page() {
// Dieser Fetch läuft auf dem Server während `next build`
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 zwischenzuspeichern.
'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 'Fehler beim Laden'
if (!data) return 'Lädt...'
return data.title
}
'use client'
import useSWR from 'swr'
const fetcher = (url) => fetch(url).then((r) => r.json())
export default function Page() {
const { data, error } = useSWR(
`https://jsonplaceholder.typicode.com/posts/1`,
fetcher
)
if (error) return 'Fehler beim Laden'
if (!data) return 'Lädt...'
return data.title
}
Da Routenübergänge clientseitig erfolgen, verhält sich dies wie eine traditionelle SPA. Beispielsweise ermöglicht die folgende Index-Route die Navigation zu verschiedenen Beiträgen auf dem Client:
import Link from 'next/link'
export default function Page() {
return (
<>
<h1>Index-Seite</h1>
<hr />
<ul>
<li>
<Link href="/post/1">Beitrag 1</Link>
</li>
<li>
<Link href="/post/2">Beitrag 2</Link>
</li>
</ul>
</>
)
}
import Link from 'next/link'
export default function Page() {
return (
<>
<h1>Index-Seite</h1>
<p>
<Link href="/other">Andere Seite</Link>
</p>
</>
)
}
Bildoptimierung
Bildoptimierung über next/image
kann mit einem statischen Export verwendet werden, indem ein benutzerdefinierter Image-Loader in next.config.js
definiert wird. Beispielsweise können Sie Bilder mit einem Dienst wie Cloudinary optimieren:
/** @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 entfernten Quelle abgerufen werden. Beispielsweise konstruiert der folgende Loader die URL für 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}`
}
Sie können dann next/image
in Ihrer Anwendung verwenden und relative Pfade zu den Bildern in Cloudinary angeben:
import Image from 'next/image'
export default function Page() {
return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}
import Image from 'next/image'
export default function Page() {
return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}
Route-Handler
Route-Handler rendern eine statische Antwort bei Ausführung von next build
. Nur das GET
-HTTP-Verb wird unterstützt. Dies kann verwendet werden, um statische HTML-, JSON-, TXT- oder andere Dateien aus zwischengespeicherten oder nicht zwischengespeicherten Daten zu generieren. Beispiel:
export async function GET() {
return Response.json({ name: 'Lee' })
}
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 sicherstellen, dass Sie nur im Browser darauf 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, die nicht während des Build-Prozesses berechnet werden kann, werden nicht unterstützt:
- Dynamische Routen mit
dynamicParams: true
- Dynamische Routen ohne
generateStaticParams()
- Route-Handler, die auf Request angewiesen sind
- Cookies
- Rewrites
- Redirects
- Headers
- Middleware
- Inkrementelle statische Regeneration
- Bildoptimierung mit dem Standard-
loader
- Entwurfsmodus
Der Versuch, diese Funktionen mit next dev
zu verwenden, führt zu einem Fehler, ähnlich wie das 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 bereitstellen kann.
Bei Ausführung von next build
generiert Next.js den statischen Export in den out
-Ordner. Die Verwendung von next export
ist nicht mehr erforderlich. Angenommen, 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 Rewrites von eingehenden Anfragen zu den richtigen Dateien konfigurieren:
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`.
# Kann weggelassen werden, wenn `trailingSlash: true`.
location /blog/ {
rewrite ^/blog/(.*)$ /blog/$1.html break;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
}
Versionsverlauf
Version | Änderungen |
---|---|
v13.4.0 | App Router (Stabil) fügt erweiterte Unterstützung für statische Exporte hinzu, einschließlich React Server Components und Route Handlers. |
v13.3.0 | next export ist veraltet und wurde durch "output": "export" ersetzt |