お前、Next.js 使ってるよな?で、「ダウンロード機能」作ろうと思って Link
コンポーネント使ったら、なんかうまくいかねえってなってるだろ?そうだろ?俺もそうだった。だから、お前がハマった原因と解決法を叩き込んでやるよ。
ダウンロードボタン押しても動かねえ!
お前はこう思ったはずだ。
「
Link
コンポーネントにhref
とdownload
属性付ければ普通にいけるだろ」
……それが甘いんだよ。押してもダウンロードされねえ。なんかページ遷移っぽい挙動になるだけで、お前が求めてる「画像のダウンロード」にはならない。は?ってなるよな。
Next.jsのLinkはページ遷移用だって知ってたか?
Link コンポーネントの使い方、公式ドキュメント読んだか?読んでねえだろ?まぁ俺も読んでなかったけどな。
実は Link
はクライアントサイドナビゲーション用なんだよ。
簡単に言うと、ページ遷移を高速化するために色々小細工してんの。で、そのせいでネイティブな <a>
タグの機能(例えば download 属性)がまともに動かねえんだ。
特に、Next.js 13以降、Link
の設計がちょっと変わってて、よりナビゲーション特化になったっぽい。だから「ファイルダウンロード」みたいな使い方するのは完全に間違い。
ネイティブな<a>
タグを使えや!
解決法は簡単だ。
Link
を諦めて、素直にネイティブな <a>
タグ使え。
こう書き換えるだけでOKだ。
<a href={downloadUrl} download="emoji_image.png" className="text-blue-600">
画像をダウンロード
</a>
これだけで、お前の求めてた「普通のダウンロードボタン」が完成する。
Blob使ってもっと安全にする方法
「いや、<a>
タグだけじゃ信用ならねえ!」って奴はこれも試してみろ。
toBlob を使って確実に動くダウンロード機能にしてやるよ。
const handleDownload = () => {
const canvas = canvasRef.current;
if (!canvas) return;
canvas.toBlob((blob) => {
if (blob) {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "emoji_image.png";
a.click();
URL.revokeObjectURL(url); // URLを解放
}
});
};
そして、こうボタンに組み込め。
<button onClick={handleDownload} className="text-blue-600">
画像をダウンロードする
</button>
これでブラウザの制限とか関係なく確実にダウンロードができるようになる。
Linkでやろうとするな!
お前がダウンロード機能作ろうとしてハマった原因、それは Next.js の Link
コンポーネントが「ページ遷移用」だからだ。
解決法はシンプル、ネイティブな <a>
タグを使え。それが嫌なら toBlob
を駆使しろ。
次からは同じ失敗すんなよな!