Skip to content

Commit b9ad2c0

Browse files
fix: OG images return 0 bytes on Next 16 + hide AI button until opted in
OG images all rendered 200 but with empty body — the edge runtime export broke ImageResponse on Next.js 16. Removing the export falls back to the default node runtime, which renders correctly. Affects /opengraph-image, /workflow/opengraph-image, /vs-books/opengraph-image, /vs-tools/opengraph-image. Also gate "Enhance with AI" behind NEXT_PUBLIC_AI_ENABLED=true so the button doesn't show on deployments that haven't set ANTHROPIC_API_KEY. Template-fill mode is unaffected. Set both env vars in Vercel when ready to enable the AI path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 3e2e63c commit b9ad2c0

6 files changed

Lines changed: 36 additions & 35 deletions

File tree

src/app/opengraph-image.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ImageResponse } from "next/og";
22

3-
export const runtime = "edge";
43
export const alt = "vibeprompt, Prompts, workflow & tools for vibe coders";
54
export const size = { width: 1200, height: 630 };
65
export const contentType = "image/png";

src/app/toolbox/page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ export default function ToolboxPage() {
8181
<span className="text-[11px] text-foreground/55">Open →</span>
8282
</div>
8383
<p className="mt-3 text-sm leading-relaxed text-foreground/80">
84-
Fill in the blanks and download a ready-to-ship AGENTS.md or PRD. Or hit
85-
&ldquo;Enhance with AI ✨&rdquo; and let Claude write a project-specific version
86-
(5 free per hour, no API key needed).
84+
Fill in the blanks and download a ready-to-ship AGENTS.md or PRD. Two modes
85+
included in the source — template-fill (default) and a Claude-powered
86+
enhance mode you can switch on with one env var if you self-host.
8787
</p>
8888
<div className="mt-4 flex flex-wrap gap-x-6 gap-y-2 text-[11px] text-foreground/55">
89-
<span>· Two modes: template fill, or AI-enhanced</span>
9089
<span>· Saves to your browser</span>
9190
<span>· No signup</span>
91+
<span>· Open source</span>
9292
</div>
9393
</Link>
9494
</section>

src/app/vs-books/opengraph-image.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ImageResponse } from "next/og";
22

3-
export const runtime = "edge";
43
export const alt = "vibeprompt vs. the vibe coding books — free, web-native, continuously updated";
54
export const size = { width: 1200, height: 630 };
65
export const contentType = "image/png";

src/app/vs-tools/opengraph-image.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ImageResponse } from "next/og";
22

3-
export const runtime = "edge";
43
export const alt = "vibeprompt vs. the vibe coding tools — Replit, Lovable, Bolt, Cursor, Claude Code";
54
export const size = { width: 1200, height: 630 };
65
export const contentType = "image/png";

src/app/workflow/opengraph-image.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ImageResponse } from "next/og";
22

3-
export const runtime = "edge";
43
export const alt = "vibeprompt workflow — 10-step interactive build loop from idea to shipped";
54
export const size = { width: 1200, height: 630 };
65
export const contentType = "image/png";

src/components/generator/generator-client.tsx

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useMemo, useState } from "react";
55
type Kind = "agents" | "prd";
66

77
const STORAGE_KEY = "vibeprompt-generator-v1";
8+
const AI_ENABLED = process.env.NEXT_PUBLIC_AI_ENABLED === "true";
89

910
type FormData = {
1011
agents: {
@@ -358,38 +359,42 @@ function OutputPanel({
358359
{markdown}
359360
</pre>
360361

361-
<div className="mt-3 flex flex-wrap items-center gap-2">
362-
{!isAi ? (
363-
<button
364-
type="button"
365-
onClick={onEnhance}
366-
disabled={aiState === "loading"}
367-
className="inline-flex items-center gap-1.5 border border-foreground/45 bg-foreground/[0.04] px-3 py-1.5 text-[11px] font-semibold text-foreground transition-colors hover:bg-foreground/[0.08] disabled:opacity-50 disabled:cursor-not-allowed"
368-
>
369-
{aiState === "loading" ? "Generating…" : "Enhance with AI ✨"}
370-
</button>
371-
) : (
372-
<button
373-
type="button"
374-
onClick={onRevertToTemplate}
375-
className="inline-flex items-center gap-1.5 border border-foreground/25 px-3 py-1.5 text-[11px] font-semibold text-foreground/70 transition-colors hover:bg-foreground/[0.04]"
376-
>
377-
← Revert to template
378-
</button>
379-
)}
380-
<p className="text-[10px] text-foreground/40">
381-
{isAi
382-
? "AI version — re-generates when you edit inputs."
383-
: "AI version uses Claude Haiku. 5 per hour. Template version is free, unlimited."}
384-
</p>
385-
</div>
362+
{AI_ENABLED && (
363+
<div className="mt-3 flex flex-wrap items-center gap-2">
364+
{!isAi ? (
365+
<button
366+
type="button"
367+
onClick={onEnhance}
368+
disabled={aiState === "loading"}
369+
className="inline-flex items-center gap-1.5 border border-foreground/45 bg-foreground/[0.04] px-3 py-1.5 text-[11px] font-semibold text-foreground transition-colors hover:bg-foreground/[0.08] disabled:opacity-50 disabled:cursor-not-allowed"
370+
>
371+
{aiState === "loading" ? "Generating…" : "Enhance with AI ✨"}
372+
</button>
373+
) : (
374+
<button
375+
type="button"
376+
onClick={onRevertToTemplate}
377+
className="inline-flex items-center gap-1.5 border border-foreground/25 px-3 py-1.5 text-[11px] font-semibold text-foreground/70 transition-colors hover:bg-foreground/[0.04]"
378+
>
379+
← Revert to template
380+
</button>
381+
)}
382+
<p className="text-[10px] text-foreground/40">
383+
{isAi
384+
? "AI version — re-generates when you edit inputs."
385+
: "AI version uses Claude Haiku. 5 per hour. Template version is free, unlimited."}
386+
</p>
387+
</div>
388+
)}
386389

387-
{aiError && (
390+
{AI_ENABLED && aiError && (
388391
<p className="mt-2 text-[11px] text-red-500">{aiError}</p>
389392
)}
390393

391394
<p className="mt-3 text-[10px] text-foreground/40">
392-
Template inputs save to your browser. Nothing leaves your machine unless you tap &ldquo;Enhance with AI&rdquo;.
395+
{AI_ENABLED
396+
? "Template inputs save to your browser. Nothing leaves your machine unless you tap “Enhance with AI”."
397+
: "All inputs save to your browser. Nothing leaves your machine."}
393398
</p>
394399
</div>
395400
);

0 commit comments

Comments
 (0)