Static Exports
Next.js は、静的サイトまたはシングルページアプリケーション(SPA)として開始し、その後オプションで、require した server の機能を使用するためのアップグレードを可能にします。
next build
を実行すると、Next.js は route ごとに HTML ファイルを生成します。厳密な SPA を個々の HTML ファイルに分けることで、Next.js は Client 側で不必要な JavaScript code の loading を回避し、バンドル size を削減してページの読み込みを高速化することができます。
Next.js がこの静的な export をサポートしているため、HTML/CSS/JS の静的アセットを提供できる任意のウェブ server にデプロイおよびホスティングできます。
Configuration
next.config.js
の中で出力モードを変更し、静的な export を有効にします:
/**
* @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 はあなたのアプリケーションのための HTML/CSS/JS の資産を含むout
フォルダーを生成します。
Supported Features
Next.js の中心部は、静的 export をサポートするように設計されています。
Server Components
next build
を実行して静的な export を生成するとき、app
ディレクトリ内で使用される Server Components は、従来の静的サイト生成と同様に、build の間に実行されます。
結果として得られる component は、初回のページ読み込みのために静的な HTML にレンダリングされ、また、client の routes 間のナビゲーション用の静的ペイロードとして機能します。静的な export を使用する際には、Server Components を変更する必要はありません。ただし、dynamic serverfunctions を使用する場合は例外です。
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>
}
Client Components
client でデータの取り出しを行いたい場合は、SWR を用いた Client Component を使って Request をメモ化することができます。
'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
}
'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 'Failed to load'
if (!data) return 'Loading...'
return data.title
}
route の遷移はクライアント側で行われるため、これは従来の SPA のように動作します。例えば、以下の index route を使用すると、 client 上の異なる投稿に移動できます。
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>
</>
)
}
import Link from 'next/link'
export default function Page() {
return (
<>
<h1>Index Page</h1>
<p>
<Link href="/other">Other Page</Link>
</p>
</>
)
}
Image Optimization
Image Optimization は、next.config.js
でカスタムの image loader を定義することにより、静的な export と共にnext/image
を用いて使用できます。例えば、Cloudinary のようなサービスで画像を最適化することができます:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
loader: 'custom',
loaderFile: './my-loader.ts',
},
}
module.exports = nextConfig
このカスタムの loader は、リモートの source から画像を fetch する方法を定義します。たとえば、以下の loader は Cloudinary の URL を構築します。
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 の image への paths を相対的に定義することができます:
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 ハンドラー
Route ハンドラーは、next build
を実行するときに静的な response を render します。サポートされるのはGET
HTTPMethod のみです。これは、キャッシュされたデータまたはキャッシュされていないデータから静的な HTML、JSON、TXT、または他のファイルを生成するために使用できます。例えば:
export async function GET() {
return Response.json({ name: 'Lee' })
}
export async function GET() {
return Response.json({ name: 'Lee' })
}
上記のファイル app/data.json/route.ts
は next build
中に、静的ファイルに render され、{ name: 'Lee' }
を含む data.json
を生成します。
あなたが入ってくる request から dynamic な値を読み取る必要がある場合、静的な export を使用することはできません。
ブラウザ API
Client Components はnext build
の間に HTML へレンダリング済みです。Web APIs 、例えばwindow
、localStorage
、そしてnavigator
のような API が server 上では利用できないので、これらの API を安全に利用するためにはブラウザで実行する必要があります。例えば:
'use client';
import { useEffect } from 'react';
export default function ClientComponent() {
useEffect(() => {
// You now have access to `window`
console.log(window.innerHeight);
}, [])
return ...;
}
Unsupported Features
Node.js server が必要な require 機能や、build プロセス中に計算できない dynamic ロジックはサポートされていません:
- Dynamic Routes と
dynamicParams: true
- Dynamic Routes
generateStaticParams()
がなし - Route ハンドラー は Request に依存しています
- Cookies
- Rewrites
- Redirects
- Headers
- Middleware
- Incremental Static Regeneration
- Image Optimization には default の
loader
が含まれています - Draft Mode
これらの機能のいずれかを next dev
で使用しようとすると、dynamic
オプションを root layout の error
に設定するのと同様の error が発生します。
export const dynamic = "error";
Deploying
静的な export を使って、HTML/CSS/JS の静的アセットをサーブできるあらゆるウェブ server で Next.js をデプロイおよびホストできます。
next build
を実行すると、 Next.js は静的な export をout
フォルダに生成します。例えば、次のような routes があるとします。
/
/blog/[id]
next build
を実行した後、Next.js は以下のファイルを生成します:
/out/index.html
/out/404.html
/out/blog/post-1.html
/out/blog/post-2.html
静的な host、例えば Nginx を使用している場合、着信 Request を適切なファイルに rewrites するよう設定できます:
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;
}
}
Version History
Version | Changes |
---|---|
v14.0.0 | next export は"output": "export" に優先して削除されました |
v13.4.0 | App Router (安定版)は、強化された静的 export のサポートを追加し、React Server Components および Route ハンドラの使用も含まれています。 |
v13.3.0 | next export は廃止され、"output": "export" に置き換えられました |