{"id":40470,"date":"2026-09-22T07:00:00","date_gmt":"2026-09-22T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=40470"},"modified":"2026-09-22T10:07:06","modified_gmt":"2026-09-22T17:07:06","slug":"cloudinary-image-generation-nextjs-guessing-game","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","title":{"rendered":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Why use one image model when a single Cloudinary API can give your application all five current families? Flux, Recraft, GPT Image, Nano Banana, and Ideogram have different creative strengths. Exposing them through the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon\">unified Cloudinary Image Generation API<\/a> lets a product choose the right model for each job without building separate authentication, storage, metadata, transformation, and delivery pipelines for every provider.<\/p>\n<p>Pixel Pursuit turns that multi-model advantage into a Next.js image-guessing game. Cloudinary generates the hidden image, stores it as a managed asset, transforms one original into progressive clues, and prepares it for optimized delivery with optional Enterprise multi-CDN routing. The result is a reusable, searchable media asset that can be remixed, inspected, transformed, and delivered from the same Cloudinary product environment.<\/p>\n<p>This project demonstrates standard and premium tiers across all five families, image-to-image remixing, metadata readback, a gallery, and delivery verification. Players can compare model interpretations while developers keep one API and asset workflow. The live demo limits each browser to two generation calls, then helps visitors clone the repository and connect their own Cloudinary account.<\/p>\n<ul>\n<li>\n<strong>Source code:<\/strong> <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\">https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game<\/a>\n<\/li>\n<li>\n<strong>Live demo:<\/strong> <a href=\"https:\/\/nextjs-cloudinary-ai-guessing-game.vercel.app\/\">https:\/\/nextjs-cloudinary-ai-guessing-game.vercel.app\/<\/a>\n<\/li>\n<\/ul>\n<h2>What You\u2019ll Build<\/h2>\n<p>A player opens the game and reads a short first-visit guide before spending a generation. They choose a model family and tier, then the server selects a mystery prompt and calls Cloudinary\u2019s text-to-image endpoint. The answer is never sent to the browser as plain JSON. It\u2019s protected inside an encrypted, authenticated round token and checked by a server route.<\/p>\n<p>Each incorrect guess advances the same asset through four clues:<\/p>\n<ol>\n<li>A deep blur hides nearly every detail.<\/li>\n<li>A pixelated version exposes color and shape.<\/li>\n<li>An automatic-gravity crop focuses on the likely subject.<\/li>\n<li>The complete image reveals the answer.<\/li>\n<\/ol>\n<p>Once the round is solved or revealed, the player can inspect Cloudinary provenance and use the original asset as an authenticated reference for a new image-to-image generation.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">flowchart LR\n  B&#91;Browser] --&gt;|family and tier| N&#91;Next.js server routes]\n  N --&gt;|Basic Auth| G&#91;Cloudinary Image Generation API]\n  G --&gt; A&#91;Managed original and metadata]\n  A --&gt; T&#91;URL transformations]\n  T --&gt; C&#91;Cloudinary multi-CDN delivery]\n  C --&gt; B\n  N --&gt;|asset ID| M&#91;Cloudinary Admin API]\n  M --&gt; P&#91;Proof panel and generation vault]\n<\/code><\/span><\/pre>\n<p>This architecture separates three trust zones. The browser owns presentation and player input. The Next.js server owns credentials, prompts, answer validation, quota decisions, and authenticated readback. Cloudinary owns managed originals, generation metadata, derived assets, and delivery.<\/p>\n<h2>Prerequisites<\/h2>\n<p>You\u2019ll need:<\/p>\n<ul>\n<li>Node.js 20.9 or newer.<\/li>\n<li>A <a href=\"https:\/\/cloudinary.com\/users\/register_free\">free Cloudinary account<\/a>.<\/li>\n<li>The Cloudinary Image Generation add-on.<\/li>\n<li>Familiarity with React and Next.js App Router route handlers.<\/li>\n<\/ul>\n<p>The project uses Next.js 16, React 19, TypeScript, Tailwind CSS, shadcn\/ui, <code>next-cloudinary<\/code>, and the Cloudinary Node.js SDK.<\/p>\n<p>The Image Generation API is an evolving API, so check the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon\">Image Generation add-on documentation<\/a> and <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_api_reference\">API reference<\/a> for the latest models, limits, and request fields before shipping.<\/p>\n<h2>Enable Cloudinary Image Generation<\/h2>\n<p>Open the <a href=\"https:\/\/console.cloudinary.com\/app\/marketplace\/details\/image_generation\">Image Generation add-on in the Cloudinary Console<\/a> and register for it. For a new account, making the first generation in the Console activates the available plan. The <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#getting_started\">official add-on guide<\/a> documents registration, Console generation, supported models, and current quota behavior.<\/p>\n<p>Next, open <strong>Settings &gt; API Keys<\/strong> and copy your cloud name, API key, and API secret. The project sends Image Generation API requests from a Node.js route with HTTP Basic authentication, as described in the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#api_authentication\">Image Generation authentication documentation<\/a>. The secret must remain on the server.<\/p>\n<p>Clone and configure the project:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">git <span class=\"hljs-keyword\">clone<\/span> https:<span class=\"hljs-comment\">\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game.git<\/span>\ncd nextjs-cloudinary-ai-guessing-game\nnpm install\ncp .env.example .env.local\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Add your values to <code>.env.local<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name\nCLOUDINARY_API_KEY=your_api_key\nCLOUDINARY_API_SECRET=your_api_secret\nCLOUDINARY_IMAGE_GENERATION_FOLDER=image-guessing-game\n<\/code><\/span><\/pre>\n<p>The cloud name is public because it appears in delivery URLs. The API key and secret are server-only. Do not give the secret a <code>NEXT_PUBLIC_<\/code> prefix.<\/p>\n<p>The app can use <code>CLOUDINARY_API_SECRET<\/code> to sign its demo usage cookie. To separate those concerns, generate another high-entropy value:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">openssl rand -base64 32\n<\/code><\/span><\/pre>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">DEMO_USAGE_SECRET=replace_with_the_generated_value\n<\/code><\/span><\/pre>\n<h2>Create a Signed Upload Preset<\/h2>\n<p>The API returns a managed asset. Without a preset, the code carries the folder in <code>target.public_id<\/code>. A signed preset centralizes the folder and custom tag rather than repeating storage rules. Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/upload_presets\">upload preset guide<\/a> explains preset security, folder modes, precedence, and programmatic management.<\/p>\n<p>Create the preset in the Console:<\/p>\n<ol>\n<li>Select the <strong>Settings<\/strong> gear in the Cloudinary Console.<\/li>\n<li>Open <strong>Upload<\/strong>, then select the <strong>Upload Presets<\/strong> tab.<\/li>\n<li>Click <strong>Add Upload Preset<\/strong>.<\/li>\n<li>Enter <code>pixel-pursuit-generations<\/code> for <strong>Upload preset name<\/strong>.<\/li>\n<li>Set <strong>Signing mode<\/strong> to <strong>Signed<\/strong>. The Image Generation request comes from an authenticated Next.js server, so the browser does not need an unsigned preset name.<\/li>\n<li>In the storage section, set <strong>Asset folder<\/strong> to <code>image-guessing-game<\/code>.<\/li>\n<li>In the asset metadata section, add <code>pixel-pursuit<\/code> to <strong>Tags<\/strong>.<\/li>\n<li>Leave incoming and eager transformations empty. This game applies blur, pixelation, cropping, format, and quality at delivery time so it can create several clues from the unchanged original.<\/li>\n<li>Click <strong>Save<\/strong>.<\/li>\n<\/ol>\n<p>The resulting configuration should match:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Console Field<\/th>\n<th>Value<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Upload preset name<\/td>\n<td><code>pixel-pursuit-generations<\/code><\/td>\n<\/tr>\n<tr>\n<td>Signing mode<\/td>\n<td><code>Signed<\/code><\/td>\n<\/tr>\n<tr>\n<td>Asset folder<\/td>\n<td><code>image-guessing-game<\/code><\/td>\n<\/tr>\n<tr>\n<td>Tags<\/td>\n<td><code>pixel-pursuit<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>This article assumes dynamic folder mode, where <strong>Asset folder<\/strong> controls the asset\u2019s Media Library location without changing its public ID path. If your product environment uses legacy fixed folder mode, the Console shows different folder options. Follow the <a href=\"https:\/\/cloudinary.com\/documentation\/folder_modes\">folder mode documentation<\/a> and keep the destination consistent with <code>CLOUDINARY_IMAGE_GENERATION_FOLDER<\/code>.<\/p>\n<p>Then update <code>.env.local<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">CLOUDINARY_IMAGE_GENERATION_PRESET=pixel-pursuit-generations\n<\/code><\/span><\/pre>\n<p>Restart <code>npm run dev<\/code> after changing the environment. Generate one round, open <strong>Assets &gt; Media Library<\/strong>, and inspect the <code>image-guessing-game<\/code> folder. The asset should include the custom <code>pixel-pursuit<\/code> tag plus Cloudinary\u2019s automatic <code>text-to-image<\/code> tag. An image-to-image remix receives <code>image-to-image<\/code> instead. The asset context should also expose <code>model_id<\/code>, <code>prompt<\/code>, and <code>seed<\/code>, matching the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#automatic_tags_and_metadata\">automatic tags and metadata documented for Image Generation<\/a>.<\/p>\n<p><strong>Do not<\/strong> make this the default preset for the entire product environment. The application sends <code>upload_preset: &quot;pixel-pursuit-generations&quot;<\/code> explicitly in the generation target, which limits the preset\u2019s effect to this workflow.<\/p>\n<h2>Offer the Complete Model Catalog<\/h2>\n<p>At the time of publication, the project exposes the complete <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#supported_models\">supported Image Generation model catalog<\/a>:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Family<\/th>\n<th>Standard Model<\/th>\n<th>Premium Model<\/th>\n<th>Seed Support<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Flux<\/td>\n<td><code>flux-2-klein-9b<\/code><\/td>\n<td><code>flux-2-pro<\/code><\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr>\n<td>Recraft<\/td>\n<td><code>recraft-v3<\/code><\/td>\n<td><code>recraft-v4<\/code><\/td>\n<td>No<\/td>\n<\/tr>\n<tr>\n<td>GPT Image<\/td>\n<td><code>gpt-image-1-mini<\/code><\/td>\n<td><code>gpt-image-2<\/code><\/td>\n<td>No<\/td>\n<\/tr>\n<tr>\n<td>Nano Banana<\/td>\n<td><code>nano-banana-1<\/code><\/td>\n<td><code>nano-banana-2<\/code><\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr>\n<td>Ideogram<\/td>\n<td><code>ideogram-v4-turbo<\/code><\/td>\n<td><code>ideogram-v4-base<\/code><\/td>\n<td>Yes<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>The UI presents each family with a purpose rather than only a model ID. Flux emphasizes photorealistic scenes, Recraft targets vector art and illustration, GPT Image suits campaign-style creative work, Nano Banana is a general-purpose option, and Ideogram supports text, realism, and art. Model Mix rotates through the catalog so the game can compare families across rounds.<\/p>\n<p>Seed support matters when you want reproducible or closely related output. The server generates a random seed only for model families that accept one. This avoids sending unsupported request fields while preserving the returned seed in the result and Cloudinary context. Recheck the official model table before publishing because the API is evolving.<\/p>\n<h2>Generate and Persist the Mystery Image<\/h2>\n<p>The core request lives in <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\/blob\/main\/src\/lib\/cloudinary\/image-generation.ts\"><code>src\/lib\/cloudinary\/image-generation.ts<\/code><\/a>. It follows the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_api_reference\">Image Generation API reference<\/a>, calls the account-scoped v2 endpoint, asks for a square 1K image, and persists the response as a managed asset.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(\n  <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v2\/generate\/<span class=\"hljs-subst\">${cloudName}<\/span>\/text_to_image`<\/span>,\n  {\n    <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n    <span class=\"hljs-attr\">headers<\/span>: {\n      <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${authorization}<\/span>`<\/span>,\n      <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n    },\n    <span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n      <span class=\"hljs-attr\">image_size<\/span>: { <span class=\"hljs-attr\">aspect_ratio<\/span>: <span class=\"hljs-string\">\"1:1\"<\/span>, <span class=\"hljs-attr\">resolution<\/span>: <span class=\"hljs-string\">\"1K\"<\/span> },\n      <span class=\"hljs-attr\">model<\/span>: { <span class=\"hljs-attr\">id<\/span>: modelId },\n      prompt,\n      ...(seed === <span class=\"hljs-literal\">null<\/span> ? {} : { seed }),\n      <span class=\"hljs-attr\">target<\/span>: {\n        <span class=\"hljs-attr\">public_id<\/span>: publicId,\n        <span class=\"hljs-attr\">target_type<\/span>: <span class=\"hljs-string\">\"managed_asset\"<\/span>,\n        ...(uploadPreset ? { <span class=\"hljs-attr\">upload_preset<\/span>: uploadPreset } : {}),\n      },\n    }),\n  },\n);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The full implementation adds a 120-second abort signal, structured error handling, request IDs, and add-on quota parsing. A UUID in the public ID prevents collisions. A <code>managed_asset<\/code> target can include both <code>public_id<\/code> and <code>upload_preset<\/code>, as shown in Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#control_the_stored_asset_with_target\">managed target example<\/a>. The API response provides both <code>asset_id<\/code> and <code>public_id<\/code>, and the app keeps both because they solve different problems:<\/p>\n<ul>\n<li>\n<code>public_id<\/code> is a stable input for Cloudinary delivery URLs and <code>CldImage<\/code>.<\/li>\n<li>\n<code>asset_id<\/code> is an immutable identity for Admin API readback and verified references.<\/li>\n<\/ul>\n<p>The <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\/blob\/main\/src\/app\/api\/generate\/route.ts\"><code>POST \/api\/generate<\/code> route<\/a> validates the requested family and tier, checks the demo allowance, selects a server-owned prompt, calls the helper, and returns the managed asset plus a round token.<\/p>\n<h2>Keep the Answer Off the Client<\/h2>\n<p>If the generation route returned the answer with the public ID, a player could open DevTools and bypass the game. Pixel Pursuit encrypts the answer, accepted aliases, asset ID, public ID, and expiration time using AES-256-GCM.<\/p>\n<p>The token uses a random 12-byte initialization vector, additional authenticated data, and a key derived from the server-only Cloudinary secret. It expires after two hours. The browser can carry it between requests but cannot read or modify it without invalidating authentication.<\/p>\n<p>The <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\/blob\/main\/src\/app\/api\/guess\/route.ts\"><code>POST \/api\/guess<\/code> route<\/a> decrypts the token and normalizes both the guess and accepted answers:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">normalizeGuess<\/span>(<span class=\"hljs-params\">value: string<\/span>): <span class=\"hljs-title\">string<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> value\n    .normalize(<span class=\"hljs-string\">\"NFKD\"<\/span>)\n    .replace(<span class=\"hljs-regexp\">\/\\p{Diacritic}\/gu<\/span>, <span class=\"hljs-string\">\"\"<\/span>)\n    .toLocaleLowerCase(<span class=\"hljs-string\">\"en\"<\/span>)\n    .replace(<span class=\"hljs-regexp\">\/&#91;^\\p{L}\\p{N}]+\/gu<\/span>, <span class=\"hljs-string\">\" \"<\/span>)\n    .trim()\n    .replace(<span class=\"hljs-regexp\">\/\\s+\/g<\/span>, <span class=\"hljs-string\">\" \"<\/span>);\n}\n\n<span class=\"hljs-keyword\">const<\/span> round = openRoundToken(body.roundToken);\n<span class=\"hljs-keyword\">const<\/span> accepted = &#91;round.answer, ...round.aliases].map(normalizeGuess);\n<span class=\"hljs-keyword\">const<\/span> correct = accepted.includes(normalizeGuess(guess));\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This permits harmless differences in case, spacing, punctuation, and diacritics without weakening the token. The route returns the answer only after a correct guess or an explicit reveal.<\/p>\n<h2>Turn 1 Public id Into 4 Clues<\/h2>\n<p>Generation is only the beginning of the image lifecycle. Cloudinary transformations let the game create several views from one stored original. <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\/blob\/main\/src\/components\/game\/mystery-clue-image.tsx\"><code>MysteryClueImage<\/code><\/a> maps the current stage to <a href=\"https:\/\/cloudinary.com\/documentation\/nextjs_image_transformations#using_cldimage\"><code>CldImage<\/code> transformation props<\/a>:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">if<\/span> (stage === <span class=\"hljs-number\">0<\/span>) {\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> {<span class=\"hljs-attr\">...commonProps<\/span>} <span class=\"hljs-attr\">blur<\/span>=<span class=\"hljs-string\">\"1600\"<\/span> <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fill\"<\/span> <span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"auto\"<\/span> \/&gt;<\/span><\/span>;\n}\n\n<span class=\"hljs-keyword\">if<\/span> (stage === <span class=\"hljs-number\">1<\/span>) {\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> {<span class=\"hljs-attr\">...commonProps<\/span>} <span class=\"hljs-attr\">pixelate<\/span>=<span class=\"hljs-string\">\"42\"<\/span> <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fill\"<\/span> <span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"auto\"<\/span> \/&gt;<\/span><\/span>;\n}\n\n<span class=\"hljs-keyword\">if<\/span> (stage === <span class=\"hljs-number\">2<\/span>) {\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n      {<span class=\"hljs-attr\">...commonProps<\/span>}\n      <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">type:<\/span> \"<span class=\"hljs-attr\">thumb<\/span>\", <span class=\"hljs-attr\">gravity:<\/span> \"<span class=\"hljs-attr\">auto<\/span>\", <span class=\"hljs-attr\">zoom:<\/span> \"<span class=\"hljs-attr\">1.35<\/span>\" }}\n    \/&gt;<\/span><\/span>\n  );\n}\n\n<span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span> {<span class=\"hljs-attr\">...commonProps<\/span>} <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">\"fit\"<\/span> \/&gt;<\/span><\/span>;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Deep blur makes the opening clue difficult. Pixelation exposes the broad palette and silhouette. The automatic-gravity thumbnail uses Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/image_automatic_gravity\">content-aware automatic gravity<\/a> to create a close clue without requiring manually stored crop coordinates. The final stage fits the full image.<\/p>\n<p>These are derived assets. Cloudinary preserves the original, creates a transformed version when its URL is first requested, and caches it for later delivery. You can therefore change the clue sequence without regenerating the AI image. Read the <a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations\">image transformations guide<\/a> for more combinations.<\/p>\n<p>The proof view adds <code>f_auto<\/code> and <code>q_auto<\/code> to a 960 by 960 automatic-gravity fill. The <a href=\"https:\/\/cloudinary.com\/documentation\/nextjs_image_transformations\">Next.js transformation guide<\/a> explains how these delivery parameters select an efficient format and quality for the requesting context.<\/p>\n<h2>Build a Verified Reference-Image Remix<\/h2>\n<p>After solving a round, the player can describe a variation such as \u201cturn this into a paper-cut poster at sunset.\u201d Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#generate_an_image_from_reference_images\"><code>image_to_image<\/code> endpoint<\/a> accepts managed assets by immutable asset ID. The remix route does not trust an arbitrary client asset ID. It first opens the solved round token, reads the source through the Admin API, and confirms that the returned public ID and configured generation folder match the token.<\/p>\n<p>The generation helper then calls <code>\/image_to_image<\/code> with a managed reference:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">payload: {\n  <span class=\"hljs-attr\">prompt<\/span>: <span class=\"hljs-string\">`Using &#91;1] as the reference image, <span class=\"hljs-subst\">${prompt}<\/span>`<\/span>,\n  <span class=\"hljs-attr\">reference_images<\/span>: &#91;\n    {\n      <span class=\"hljs-attr\">asset_id<\/span>: referenceAssetId,\n      <span class=\"hljs-attr\">source_type<\/span>: <span class=\"hljs-string\">\"managed_asset\"<\/span>,\n    },\n  ],\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Flux, Recraft, GPT Image, and Nano Banana currently provide edit-capable models in the project. Recraft supports the standard edit tier only, and Ideogram is omitted because the current catalog does not list an edit model for it.<\/p>\n<p>The remix is stored as another managed asset and automatically receives Cloudinary\u2019s <code>image-to-image<\/code> generation tag and context. This turns a completed game round into a second creative workflow while retaining source-of-truth asset checks.<\/p>\n<h2>Read Generations Back From Cloudinary<\/h2>\n<p>The <code>\/generations<\/code> page is not a client-side history array. <a href=\"https:\/\/github.com\/musebe\/nextjs-cloudinary-ai-guessing-game\/blob\/main\/src\/lib\/cloudinary\/generations.ts\"><code>src\/lib\/cloudinary\/generations.ts<\/code><\/a> queries <code>resources_by_tag<\/code> for both <code>text-to-image<\/code> and <code>image-to-image<\/code> in parallel, combines and de-duplicates results by asset ID, checks the configured folder, and sorts them by creation time.<\/p>\n<p>Requesting <code>tags: true<\/code> and <code>context: true<\/code> exposes the provenance Cloudinary stored with each asset:<\/p>\n<ul>\n<li>Generation type<\/li>\n<li>Model ID<\/li>\n<li>Prompt<\/li>\n<li>Seed when supported<\/li>\n<li>Asset folder and public ID<\/li>\n<li>Dimensions, format, bytes, and creation time<\/li>\n<\/ul>\n<p>This makes the gallery durable across page refreshes and application restarts. It also illustrates when to use the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api\">Admin API<\/a>: Use delivery URLs for pixels, but use authenticated server-side Admin API calls when your interface needs asset records and metadata. Never call the Admin API directly from the browser.<\/p>\n<h2>Verify Provenance and Multi-CDN Delivery<\/h2>\n<p>Once a player knows the answer, the proof route opens the solved token and performs two checks concurrently:<\/p>\n<ol>\n<li>It reads the immutable asset ID from the Cloudinary Admin API.<\/li>\n<li>It sends a <code>HEAD<\/code> request to the transformed delivery URL.<\/li>\n<\/ol>\n<p>The panel reports stored generation context plus the delivery hostname, HTTP status, content type, transformation, response time, cache header, and observed multi-CDN edge headers. This is more useful than placing a decorative \u201cmulti-CDN powered\u201d label on the screen because it connects the claim to the current asset and request.<\/p>\n<p>Cloudinary\u2019s Enterprise multi-CDN options include dynamic switching and smart selection while application URLs remain stable. Dynamic switching can route each request using current performance and availability data, while smart selection maps asset types or audiences to an appropriate network. The panel reports only the edge headers it observes and does not claim that Enterprise multi-CDN routing is active on every account. Review <a href=\"https:\/\/cloudinary.com\/documentation\/advanced_url_delivery_options#multi_cdn_solutions\">Cloudinary\u2019s multi-CDN solutions<\/a> for availability, routing behavior, and pricing implications.<\/p>\n<h2>Protect Demo Credits<\/h2>\n<p>Text-to-image rounds and image-to-image remixes consume add-on quota. Cloudinary documents the current credit model in the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#plans_and_quota\">Image Generation plans and quota section<\/a>. A public demo needs a visible, predictable boundary.<\/p>\n<p>Pixel Pursuit permits two generation calls per browser. A server-created HttpOnly cookie stores the count and an HMAC-SHA256 signature. A visitor cannot raise or lower a valid count from client JavaScript, and both generation routes consume the same allowance. At zero remaining calls, the API returns HTTP 429 with the repository URL, and the interface explains how to clone and configure the project.<\/p>\n<p>This guard is intentionally demo-grade. Cookies identify a browser, not a person, and can be cleared. If you need strict usage enforcement, add authentication and persist counters in a transactional database or shared rate limiter. Also combine application limits with Cloudinary account alerts and quota monitoring.<\/p>\n<h2>Run and Verify the Project<\/h2>\n<p>Start the development server:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm run dev\n<\/code><\/span><\/pre>\n<p>Open <code>http:\/\/localhost:3000<\/code> and test this sequence:<\/p>\n<ol>\n<li>Read and dismiss the first-visit game guide.<\/li>\n<li>Select a model family and tier, then generate a round.<\/li>\n<li>Submit incorrect guesses and confirm the clue becomes clearer.<\/li>\n<li>Solve or reveal the round and open the Cloudinary proof.<\/li>\n<li>Create a reference-image remix if one generation remains.<\/li>\n<li>Visit <code>\/generations<\/code> and confirm both assets and their metadata appear.<\/li>\n<li>Try another generation and confirm the two-call gate offers clone instructions.<\/li>\n<\/ol>\n<p>Before deployment, run:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx tsc --noEmit\nnpm run lint\nnpm run build\n<\/code><\/span><\/pre>\n<p>Configure the same environment variables in your hosting platform. Keep the API secret and demo signing secret server-only. If your platform has route duration controls, retain enough time for the project\u2019s 120-second generation request timeout.<\/p>\n<h2>Conclusion<\/h2>\n<p>Pixel Pursuit makes image generation observable from prompt to delivery. Cloudinary creates and stores the asset, Next.js protects the game state, URL transformations produce the clue sequence, the Admin API supplies durable provenance, and optional Enterprise multi-CDN delivery can complete the path to the player.<\/p>\n<p>That combination is useful beyond games. The same pattern can support campaign review tools, creative variant explorers, product visualization workflows, or moderated content pipelines. Start with the repository, connect your own Cloudinary account, and replace the prompt catalog and clue sequence with the experience your users need.<\/p>\n<p>Ready to level up your media workflow? <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Start using Cloudinary for free<\/a> and build better visual experiences today.<\/p>\n<\/div>\n\n\n<style>\n.faqs {\n    padding: 30px 60px;\n    margin-top: 40px;\n    background: var(--color-background-offset);\n    border-radius: 20px;\n}\n\n#frequently_asked_questions {\n    margin-bottom: 20px;\n}\n\n.question {\n    margin-bottom: 12px;\n    border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n}\n\n.question summary {\n    position: relative;\n    padding: 18px 40px 18px 0;\n    cursor: pointer;\n    font-weight: 700;\n    list-style: none;\n}\n\n.question summary::-webkit-details-marker {\n    display: none;\n}\n\n.question summary::after {\n    content: \"+\";\n    position: absolute;\n    top: 50%;\n    right: 0;\n    transform: translateY(-50%);\n    font-size: 24px;\n    font-weight: 400;\n    line-height: 1;\n}\n\n.question[open] summary::after {\n    content: \"\u2212\";\n}\n\n.answer {\n    padding: 0 40px 20px 0;\n}\n<\/style>\n\n<div class=\"faqs\">\n\n<h2 id=\"frequently_asked_questions\">Frequently Asked Questions<\/h2>\n\n<details class=\"question\">\n    <summary>Does Cloudinary store the AI-generated images?<\/summary>\n    <div class=\"answer\">Yes, when <code>target_type<\/code> is <code>managed_asset<\/code>, the generation result is stored in your Cloudinary product environment. The response includes an asset ID, public ID, and secure URL.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Why use both a public ID and an asset ID?<\/summary>\n    <div class=\"answer\">Use the public ID to build transformation and delivery URLs. Use the immutable asset ID to read and validate the exact resource through authenticated server-side operations.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Does every model support seeds?<\/summary>\n    <div class=\"answer\">No. The current app sends seeds for Flux, Nano Banana, and Ideogram. It omits the field for Recraft and GPT Image. Confirm the latest matrix in the <a href=\"https:\/\/cloudinary.com\/documentation\/image_generation_addon#supported_models\" target=\"_blank\" rel=\"noopener\">Image Generation model documentation<\/a>.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Does every text-to-image model support image editing?<\/summary>\n    <div class=\"answer\">No. The current edit catalog includes Flux, Recraft, GPT Image, and Nano Banana. Recraft currently has only a standard edit option, and Ideogram is not included.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Do Cloudinary transformations overwrite the generated image?<\/summary>\n    <div class=\"answer\">No. The managed original remains intact. Cloudinary creates <a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations\" target=\"_blank\" rel=\"noopener\">derived versions<\/a> for requested transformation URLs and caches them for subsequent delivery.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Is multi-CDN enabled automatically for every account?<\/summary>\n    <div class=\"answer\">No. Dynamic switching and smart selection within Cloudinary&#8217;s multi-CDN solutions are Enterprise capabilities. Check your account and the <a href=\"https:\/\/cloudinary.com\/documentation\/advanced_url_delivery_options#multi_cdn_solutions\" target=\"_blank\" rel=\"noopener\">multi-CDN documentation<\/a> before describing either capability as enabled.<\/div>\n<\/details>\n\n<details class=\"question\">\n    <summary>Is the two-generation limit secure enough for production billing?<\/summary>\n    <div class=\"answer\">No. It is a signed per-browser demo guard. Production-grade per-user enforcement requires authentication and durable server-side usage storage.<\/div>\n<\/details>\n\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Frequently Asked Questions Does Cloudinary store the AI-generated images? Yes, when target_type is managed_asset, the generation result is stored in your Cloudinary product environment. The response includes an asset ID, public ID, and secure URL. Why use both a public ID and an asset ID? Use the public ID to build transformation and delivery URLs. [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":40501,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[336,332,370],"class_list":["post-40470","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-ai","tag-api","tag-image"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.3 (Yoast SEO v28.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js<\/title>\n<meta name=\"description\" content=\"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js\" \/>\n<meta property=\"og:description\" content=\"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-22T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-22T17:07:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#\\\/schema\\\/person\\\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js\",\"datePublished\":\"2026-09-22T14:00:00+00:00\",\"dateModified\":\"2026-09-22T17:07:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game\"},\"wordCount\":237,\"publisher\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1790096813\\\/Web_Assets\\\/blog\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA\",\"keywords\":[\"AI\",\"API\",\"Image\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game\",\"url\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game\",\"name\":\"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1790096813\\\/Web_Assets\\\/blog\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA\",\"datePublished\":\"2026-09-22T14:00:00+00:00\",\"dateModified\":\"2026-09-22T17:07:06+00:00\",\"description\":\"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#primaryimage\",\"url\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1790096813\\\/Web_Assets\\\/blog\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA\",\"contentUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1790096813\\\/Web_Assets\\\/blog\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\\\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/cloudinary-image-generation-nextjs-guessing-game#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1649718331\\\/Web_Assets\\\/blog\\\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\\\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/cloudinary-marketing\\\/images\\\/f_auto,q_auto\\\/v1649718331\\\/Web_Assets\\\/blog\\\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\\\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/cloudinary.com\\\/blog\\\/#\\\/schema\\\/person\\\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js","description":"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","og_locale":"en_US","og_type":"article","og_title":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js","og_description":"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.","og_url":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","og_site_name":"Cloudinary Blog","article_published_time":"2026-09-22T14:00:00+00:00","article_modified_time":"2026-09-22T17:07:06+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","type":"image\/png"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js","datePublished":"2026-09-22T14:00:00+00:00","dateModified":"2026-09-22T17:07:06+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game"},"wordCount":237,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","keywords":["AI","API","Image"],"inLanguage":"en-US","copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","url":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","name":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","datePublished":"2026-09-22T14:00:00+00:00","dateModified":"2026-09-22T17:07:06+00:00","description":"Build a Next.js AI image-guessing game with every Cloudinary image model, managed assets, transformations, remixes, metadata, and multi-CDN delivery.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"parsely":{"version":"1.1.0","canonical_url":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","smart_links":{"inbound":0,"outbound":0},"traffic_boost_suggestions_count":0,"meta":{"@context":"https:\/\/schema.org","@type":"NewsArticle","headline":"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js","url":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game","mainEntityOfPage":{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA&w=150&h=150&crop=1","image":{"@type":"ImageObject","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA"},"articleSection":"Uncategorized","author":[{"@type":"Person","name":"melindapham"}],"creator":["melindapham"],"publisher":{"@type":"Organization","name":"Cloudinary Blog","logo":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA"},"keywords":["ai","api","image"],"dateCreated":"2026-09-22T14:00:00Z","datePublished":"2026-09-22T14:00:00Z","dateModified":"2026-09-22T17:07:06Z"},"rendered":"<meta name=\"parsely-title\" content=\"Cloudinary Image Generation: Build an AI Image-Guessing Game in Next.js\" \/>\n<meta name=\"parsely-link\" content=\"https:\/\/cloudinary.com\/blog\/cloudinary-image-generation-nextjs-guessing-game\" \/>\n<meta name=\"parsely-type\" content=\"post\" \/>\n<meta name=\"parsely-image-url\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA&w=150&amp;h=150&amp;crop=1\" \/>\n<meta name=\"parsely-pub-date\" content=\"2026-09-22T14:00:00Z\" \/>\n<meta name=\"parsely-section\" content=\"Uncategorized\" \/>\n<meta name=\"parsely-tags\" content=\"ai,api,image\" \/>\n<meta name=\"parsely-author\" content=\"melindapham\" \/>","tracker_url":"https:\/\/cdn.parsely.com\/keys\/cloudinary.com\/p.js"},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1790096813\/Web_Assets\/blog\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37\/Blog_Cloudinary_Image_Generation__Build_an_AI_Image-Guessing_Game_in_Next.js__405015ab37.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=40470"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40470\/revisions"}],"predecessor-version":[{"id":40473,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40470\/revisions\/40473"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/40501"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=40470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=40470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=40470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}