何をしようとしているのか
フロントエンドをNext.js11で開発しています。
最終的には静的HTMLを生成し、Google Cloud Storage (GCS) にホスティングして配信します。
Next.jsによる静的HTMLの生成とGCSによる静的ウェブサイトのホスティングについては以下のサイトを参考に行っています。
何があったのか
Next.jsで静的HTMLを生成する際にエラーが発生しました。
`next build && next export` で静的サイトを生成する時にnext/imageを使ってるとエラーになる。でもNext.js11ではimgタグを使うとビルドのときにエラーになる。imgタグ使ってeslintの設定変えるしかないのか? pic.twitter.com/c0g45tmpEQ
— スギヤマトシキ (@llwz886q) August 27, 2021
詳しくは以下のとおりです。
next/image を使った
サイトにロゴを設置するために、
import Image from 'next/image'
const Logo = () => (
<Image
src="/logo.svg"
alt="logo"
width={128}
height={128}
/>
)
export default Logo
↑ このようなファイルを作成しました。
ローカル環境では next dev
を実行しており、問題なくロゴが表示されています。
静的HTMLを生成するために next build && next export
を実行すると、
↑ エラー が発生しました。
確かに Basic Features: Image Optimization | Next.js には
The next/image component's default loader is not supported when using next export. However, other loader options will work.
と書かれています。
img タグを使った
そこで今度は next/image
ではなく <img>
タグを使用して、
const Logo = () => (
<img
src="/logo.svg"
alt="logo"
width="128"
height="128"
/>
)
export default Logo
logo
コンポーネントを↑このように書き換えました。
再度 next build && next export
を実行すると、
<img>
タグの代わりに next/image
を使うように、というエラー が発生しました。
From Next.js 11, ESLint is supported out-of-the-box and a new set of rules is now provided, including the @next/next/no-img-element rule.
ということで、
{
"extends": ["next", "next/core-web-vitals"],
+ "rules": {
+ "@next/next/no-img-element": "off"
+ }
}
とすることで <img>
タグが使えるようになります。
おわりに
静的HTMLを生成する際に next/image
を使えなくても画像を最適化するにはどうすればよいか?
Image optimization for static NextJS sites を参考にして next-optimized-images を使用しました。
yarn add next-optimized-images imagemin-svgo
↑パッケージをインストールして(svgのみ最適化の対象とする例)、
+ const withOptimizedImages = require('next-optimized-images')
- module.exports = {
+ module.exports = withOptimizedImages({
reactStrictMode: true,
trailingSlash: true,
+ handleImages: ['svg'],
- }
+ })
next.config.js
を↑このように修正し、next build && next export
を実行して完成です。
参考
- Advanced Features: 静的HTMLのエクスポート | Next.js
- Basic Features: Image Optimization | Next.js
- Error: Do not use <img>. Use Image from 'next/image' instead. - Next.js using html tag <img /> ( with styled components ) - Stack Overflow
- Image optimization for static NextJS sites
- 静的ウェブサイトのホスティング | Cloud Storage | Google Cloud