[{"data":1,"prerenderedAt":765},["ShallowReactive",2],{"content-/nuxt-build-vs-generate":3,"all-pages-for-dir":742,"related-/nuxt-build-vs-generate":743,"og-image-/nuxt-build-vs-generate":764},{"id":4,"title":5,"body":6,"category":727,"concepts":727,"description":728,"extension":729,"meta":730,"navigation":246,"ogImage":727,"path":731,"project_name":727,"published":732,"publishedAt":733,"seo":734,"source":727,"stem":735,"tags":736,"todo":727,"unpublished":732,"updatedAt":727,"__hash__":741},"pages/2025-12/2025-12-24/nuxt-build-vs-generate.md","Nuxt 3: build vs generate の違い",{"type":7,"value":8,"toc":711},"minimark",[9,13,17,72,75,79,85,105,115,118,123,141,147,150,156,159,162,354,357,365,468,473,486,497,515,518,522,536,540,554,557,566,577,587,601,604,690,707],[10,11,5],"h1",{"id":12},"nuxt-3-build-vs-generate-の違い",[14,15,16],"h2",{"id":16},"一言で言うと",[18,19,20,36],"table",{},[21,22,23],"thead",{},[24,25,26,30,33],"tr",{},[27,28,29],"th",{},"コマンド",[27,31,32],{},"出力",[27,34,35],{},"サーバー",[37,38,39,57],"tbody",{},[24,40,41,48,51],{},[42,43,44],"td",{},[45,46,47],"code",{},"nuxt build",[42,49,50],{},"アプリケーション + サーバー",[42,52,53],{},[54,55,56],"strong",{},"必要",[24,58,59,64,67],{},[42,60,61],{},[45,62,63],{},"nuxt generate",[42,65,66],{},"静的HTMLファイル",[42,68,69],{},[54,70,71],{},"不要",[14,73,74],{"id":74},"本質的な違い",[76,77,47],"h3",{"id":78},"nuxt-build",[80,81,82],"p",{},[54,83,84],{},"「アプリケーションをビルドする」",[86,87,88,92,95,102],"ul",{},[89,90,91],"li",{},"Node.jsサーバー（または Cloudflare Functions等）で動作するアプリケーションを生成",[89,93,94],{},"リクエストごとにサーバーでHTMLを生成できる（SSR: Server-Side Rendering）",[89,96,97,98,101],{},"APIルート（",[45,99,100],{},"server/api/","）が動作する",[89,103,104],{},"動的なコンテンツ生成が可能",[106,107,112],"pre",{"className":108,"code":110,"language":111},[109],"language-text","出力: .output/\n├── server/          # サーバーコード\n│   └── index.mjs    # エントリーポイント\n├── public/          # 静的アセット\n└── nitro.json       # Nitro設定\n","text",[45,113,110],{"__ignoreMap":114},"",[76,116,63],{"id":117},"nuxt-generate",[80,119,120],{},[54,121,122],{},"「静的サイトを生成する」",[86,124,125,128,131,138],{},[89,126,127],{},"ビルド時に全ページをHTMLファイルとして書き出す（SSG: Static Site Generation）",[89,129,130],{},"サーバー不要、CDNから直接配信可能",[89,132,133,134,137],{},"APIルートは",[54,135,136],{},"含まれない","（ビルド時に存在しないため）",[89,139,140],{},"全てのページが事前に生成される",[106,142,145],{"className":143,"code":144,"language":111},[109],"出力: dist/\n├── index.html\n├── blog/\n│   └── index.html\n├── 2025-12-24/\n│   └── some-article/\n│       └── index.html\n└── _nuxt/           # JS/CSSアセット\n",[45,146,144],{"__ignoreMap":114},[14,148,149],{"id":149},"レンダリング戦略の比較",[106,151,154],{"className":152,"code":153,"language":111},[109],"┌─────────────────────────────────────────────────────────────────┐\n│                    レンダリングのタイミング                        │\n├─────────────────────────────────────────────────────────────────┤\n│                                                                 │\n│   ビルド時                    リクエスト時                        │\n│   ─────────                  ────────────                       │\n│                                                                 │\n│   ┌─────────┐                ┌─────────┐                        │\n│   │   SSG   │                │   SSR   │                        │\n│   │ generate│                │  build  │                        │\n│   └─────────┘                └─────────┘                        │\n│                                                                 │\n│   HTMLを事前生成              リクエストごとに                     │\n│   サーバー不要                HTMLを生成                          │\n│                              サーバー必要                         │\n│                                                                 │\n└─────────────────────────────────────────────────────────────────┘\n",[45,155,153],{"__ignoreMap":114},[14,157,158],{"id":158},"ハイブリッドレンダリング",[80,160,161],{},"ページごとにレンダリング戦略を選択できるのが、Nuxt 3の特徴だ:",[106,163,167],{"className":164,"code":165,"language":166,"meta":114,"style":114},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// nuxt.config.ts\nexport default defineNuxtConfig({\n  routeRules: {\n    // 静的生成（ビルド時にHTML生成）\n    '/blog/**': { prerender: true },\n\n    // SSR（リクエスト時にHTML生成）\n    '/dashboard/**': { ssr: true },\n\n    // SPA（クライアントのみ）\n    '/admin/**': { ssr: false },\n\n    // ISR（一定時間キャッシュ後に再生成）\n    '/products/**': { isr: 3600 }\n  }\n})\n","typescript",[45,168,169,178,196,206,212,241,248,254,275,280,286,307,312,318,342,348],{"__ignoreMap":114},[170,171,174],"span",{"class":172,"line":173},"line",1,[170,175,177],{"class":176},"sxvE3","// nuxt.config.ts\n",[170,179,181,185,188,192],{"class":172,"line":180},2,[170,182,184],{"class":183},"sHkkW","export",[170,186,187],{"class":183}," default",[170,189,191],{"class":190},"senZ8"," defineNuxtConfig",[170,193,195],{"class":194},"shFtX","({\n",[170,197,199,203],{"class":172,"line":198},3,[170,200,202],{"class":201},"sz8Xr","  routeRules",[170,204,205],{"class":194},": {\n",[170,207,209],{"class":172,"line":208},4,[170,210,211],{"class":176},"    // 静的生成（ビルド時にHTML生成）\n",[170,213,215,219,223,226,229,232,235,238],{"class":172,"line":214},5,[170,216,218],{"class":217},"sMJiu","    '",[170,220,222],{"class":221},"sdGka","/blog/**",[170,224,225],{"class":217},"'",[170,227,228],{"class":194},": { ",[170,230,231],{"class":201},"prerender",[170,233,234],{"class":194},": ",[170,236,237],{"class":183},"true",[170,239,240],{"class":194}," },\n",[170,242,244],{"class":172,"line":243},6,[170,245,247],{"emptyLinePlaceholder":246},true,"\n",[170,249,251],{"class":172,"line":250},7,[170,252,253],{"class":176},"    // SSR（リクエスト時にHTML生成）\n",[170,255,257,259,262,264,266,269,271,273],{"class":172,"line":256},8,[170,258,218],{"class":217},[170,260,261],{"class":221},"/dashboard/**",[170,263,225],{"class":217},[170,265,228],{"class":194},[170,267,268],{"class":201},"ssr",[170,270,234],{"class":194},[170,272,237],{"class":183},[170,274,240],{"class":194},[170,276,278],{"class":172,"line":277},9,[170,279,247],{"emptyLinePlaceholder":246},[170,281,283],{"class":172,"line":282},10,[170,284,285],{"class":176},"    // SPA（クライアントのみ）\n",[170,287,289,291,294,296,298,300,302,305],{"class":172,"line":288},11,[170,290,218],{"class":217},[170,292,293],{"class":221},"/admin/**",[170,295,225],{"class":217},[170,297,228],{"class":194},[170,299,268],{"class":201},[170,301,234],{"class":194},[170,303,304],{"class":183},"false",[170,306,240],{"class":194},[170,308,310],{"class":172,"line":309},12,[170,311,247],{"emptyLinePlaceholder":246},[170,313,315],{"class":172,"line":314},13,[170,316,317],{"class":176},"    // ISR（一定時間キャッシュ後に再生成）\n",[170,319,321,323,326,328,330,333,335,339],{"class":172,"line":320},14,[170,322,218],{"class":217},[170,324,325],{"class":221},"/products/**",[170,327,225],{"class":217},[170,329,228],{"class":194},[170,331,332],{"class":201},"isr",[170,334,234],{"class":194},[170,336,338],{"class":337},"sM54T","3600",[170,340,341],{"class":194}," }\n",[170,343,345],{"class":172,"line":344},15,[170,346,347],{"class":194},"  }\n",[170,349,351],{"class":172,"line":350},16,[170,352,353],{"class":194},"})\n",[14,355,356],{"id":356},"buildでも静的ページは作れる",[80,358,359,361,362,364],{},[45,360,47],{},"でも",[45,363,231],{},"設定があれば静的HTMLを生成する:",[106,366,368],{"className":164,"code":367,"language":166,"meta":114,"style":114},"// nuxt.config.ts\nexport default defineNuxtConfig({\n  nitro: {\n    preset: \"cloudflare-pages\",\n    prerender: {\n      crawlLinks: true,\n      routes: ['/blog', '/']\n    }\n  }\n})\n",[45,369,370,374,384,391,409,416,427,455,460,464],{"__ignoreMap":114},[170,371,372],{"class":172,"line":173},[170,373,177],{"class":176},[170,375,376,378,380,382],{"class":172,"line":180},[170,377,184],{"class":183},[170,379,187],{"class":183},[170,381,191],{"class":190},[170,383,195],{"class":194},[170,385,386,389],{"class":172,"line":198},[170,387,388],{"class":201},"  nitro",[170,390,205],{"class":194},[170,392,393,396,398,401,404,406],{"class":172,"line":208},[170,394,395],{"class":201},"    preset",[170,397,234],{"class":194},[170,399,400],{"class":217},"\"",[170,402,403],{"class":221},"cloudflare-pages",[170,405,400],{"class":217},[170,407,408],{"class":194},",\n",[170,410,411,414],{"class":172,"line":214},[170,412,413],{"class":201},"    prerender",[170,415,205],{"class":194},[170,417,418,421,423,425],{"class":172,"line":243},[170,419,420],{"class":201},"      crawlLinks",[170,422,234],{"class":194},[170,424,237],{"class":183},[170,426,408],{"class":194},[170,428,429,432,435,437,440,442,445,447,450,452],{"class":172,"line":250},[170,430,431],{"class":201},"      routes",[170,433,434],{"class":194},": [",[170,436,225],{"class":217},[170,438,439],{"class":221},"/blog",[170,441,225],{"class":217},[170,443,444],{"class":194},", ",[170,446,225],{"class":217},[170,448,449],{"class":221},"/",[170,451,225],{"class":217},[170,453,454],{"class":194},"]\n",[170,456,457],{"class":172,"line":256},[170,458,459],{"class":194},"    }\n",[170,461,462],{"class":172,"line":277},[170,463,347],{"class":194},[170,465,466],{"class":172,"line":282},[170,467,353],{"class":194},[80,469,470],{},[54,471,472],{},"結果:",[86,474,475,480],{},[89,476,477,479],{},[45,478,439],{},"配下 → 静的HTML（プリレンダリング）",[89,481,482,485],{},[45,483,484],{},"/api/*"," → Cloudflare Functions（サーバー処理）",[80,487,488,489,492,493,496],{},"これが",[45,490,491],{},"build","と",[45,494,495],{},"generate","の最大の違い:",[86,498,499,504],{},[89,500,501,503],{},[45,502,495],{},": 全て静的、サーバーなし",[89,505,506,508,509,511,512],{},[45,507,491],{}," + ",[45,510,231],{},": 静的ページ + サーバー機能の",[54,513,514],{},"両方",[14,516,517],{"id":517},"使い分けの指針",[76,519,521],{"id":520},"generate-を使うべき場合","generate を使うべき場合",[86,523,524,527,530,533],{},[89,525,526],{},"ブログ、ドキュメントサイトなど完全に静的なサイト",[89,528,529],{},"サーバーコストをゼロにしたい",[89,531,532],{},"最高のパフォーマンス（CDN配信）が必要",[89,534,535],{},"APIルートが不要",[76,537,539],{"id":538},"build-を使うべき場合","build を使うべき場合",[86,541,542,545,548,551],{},[89,543,544],{},"サーバーAPIが必要（認証、データベース接続、外部API呼び出し）",[89,546,547],{},"動的OGP画像生成など、リクエスト時の処理が必要",[89,549,550],{},"一部のページだけ動的にしたい",[89,552,553],{},"ユーザーごとに異なるコンテンツを返したい",[14,555,556],{"id":556},"今回のプロジェクトでの選択",[80,558,559,562,563,565],{},[54,560,561],{},"Before:"," ",[45,564,495],{},"（完全静的）",[86,567,568,571,574],{},[89,569,570],{},"全ページをビルド時にHTML生成",[89,572,573],{},"APIルートなし",[89,575,576],{},"OGP画像は固定",[80,578,579,562,582,508,584,586],{},[54,580,581],{},"After:",[45,583,491],{},[45,585,231],{},"（ハイブリッド）",[86,588,589,592,598],{},[89,590,591],{},"コンテンツページは静的HTML（prerender）",[89,593,594,597],{},[45,595,596],{},"/api/og/japanese-quiz"," は Cloudflare Functions",[89,599,600],{},"クイズ結果に応じた動的OGP画像が可能に",[14,602,603],{"id":603},"まとめ",[18,605,606,617],{},[21,607,608],{},[24,609,610,613,615],{},[27,611,612],{},"観点",[27,614,495],{},[27,616,491],{},[37,618,619,629,637,648,657,668,679],{},[24,620,621,623,626],{},[42,622,32],{},[42,624,625],{},"HTMLファイル",[42,627,628],{},"アプリ + サーバー",[24,630,631,633,635],{},[42,632,35],{},[42,634,71],{},[42,636,56],{},[24,638,639,642,645],{},[42,640,641],{},"APIルート",[42,643,644],{},"❌",[42,646,647],{},"✅",[24,649,650,653,655],{},[42,651,652],{},"動的コンテンツ",[42,654,644],{},[42,656,647],{},[24,658,659,662,665],{},[42,660,661],{},"パフォーマンス",[42,663,664],{},"最高（CDN）",[42,666,667],{},"良い〜最高",[24,669,670,673,676],{},[42,671,672],{},"コスト",[42,674,675],{},"低（静的ホスティング）",[42,677,678],{},"中（サーバーレス）",[24,680,681,684,687],{},[42,682,683],{},"柔軟性",[42,685,686],{},"低",[42,688,689],{},"高",[80,691,692,694,695,697,698,701,702,694,704,706],{},[45,693,495],{},"は",[45,696,491],{},"の",[54,699,700],{},"サブセット","と考えると分かりやすい。\n",[45,703,491],{},[45,705,495],{},"の機能を含みつつ、サーバー機能も追加できる。",[708,709,710],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":114,"searchDepth":180,"depth":180,"links":712},[713,714,718,719,720,721,725,726],{"id":16,"depth":180,"text":16},{"id":74,"depth":180,"text":74,"children":715},[716,717],{"id":78,"depth":198,"text":47},{"id":117,"depth":198,"text":63},{"id":149,"depth":180,"text":149},{"id":158,"depth":180,"text":158},{"id":356,"depth":180,"text":356},{"id":517,"depth":180,"text":517,"children":722},[723,724],{"id":520,"depth":198,"text":521},{"id":538,"depth":198,"text":539},{"id":556,"depth":180,"text":556},{"id":603,"depth":180,"text":603},null,"nuxt buildとnuxt generateの本質的な違いを理解する","md",{},"/nuxt-build-vs-generate",false,"2025-12-24T00:00:00.000Z",{"title":5,"description":728},"2025-12/2025-12-24/nuxt-build-vs-generate",[737,738,739,740],"Nuxt","SSR","SSG","Nitro","RTLma5OHJO5wmn_FPWTWeh0pM0_B7TuVHhgupjctjB4",[],[744,748,752,756,760],{"title":745,"path":746,"publishedAt":747},"Cloudflare Pages の 1MB Worker bundle 制限に当たって構成図A〜Dを書きながら設計判断を整理した","/cloudflare-pages-workers-bundle-architecture","2026-06-16T00:00:00.000Z",{"title":749,"path":750,"publishedAt":751},"Cloudflare Pages SSG の OOM を Excel 教材データ分離で根本対応した話 — Codex 再帰レビューと SSR fetch 404 の突破","/excel-data-separation-cloudflare-ssg-oom","2026-05-10T00:00:00.000Z",{"title":753,"path":754,"publishedAt":755},"Nuxtビルド最適化：341ページを137秒でSSG","/nuxt-devtools-optimization","2026-01-02T00:00:00.000Z",{"title":757,"path":758,"publishedAt":759},"ページ遷移が遅い問題：SSR vs SSG の選択ミス","/ssr-vs-ssg-page-transition-slow","2025-12-05T00:00:00.000Z",{"title":761,"path":762,"publishedAt":763},"Cloudflare Worker のバンドル削減2日目、外部HTML化で287KiB空けて miller-viewer 島は予測の1割だった","/nuxt-worker-bundle-reduction-miller-viewer","2026-07-30T00:00:00.000Z","https://log.eurekapu.com/og/blog/nuxt-build-vs-generate.png?v=2025-12-24T00%3A00%3A00.000Z&title=Nuxt%203%3A%20build%20vs%20generate%20%E3%81%AE%E9%81%95%E3%81%84&author=Kei%20Komatsu&sig=2334d45d5c91e06a",1785654690391]