Skip to content

Create AI-Generated Images for Your Next.js Blog With DALL-E 3

Did you know that AI-generated images can be tailored to match the theme of your content perfectly? By leveraging DALL-E 3 and Cloudinary, you can effortlessly create stunning blog post banner images that resonate with your audience.

In this blog post, you’ll learn how to auto-generate AI images for your Next.js blog with DALL-E 3 by entering your post title. This process adds layered text and an opaque dark background, ensuring your banners look professional. Cloudinary‘s advanced transformation capabilities make sure your images are perfectly sized and styled.

Here’s the result:

GitHub repository is here.

To follow along, you’ll need:

First, clone the starter project into your preferred folder and checkout to the starter branch using the git commands below to quickly get started. This starter project is a Next.js application using the app directory and configured with Tailwind CSS for styling.

git clone https://github.com/Olanetsoft/auto-generate-ai-images-for-your-next.js-blog-with-dall-e-3.git
cd auto-generate-ai-images-for-your-next.js-blog-with-dall-e-3
git checkout starterCode language: JavaScript (javascript)

Next, run the following command to install all dependencies using the npm package manager and start the project on http://localhost:3000.

npm install && npm run dev

You need environment credentials from your Cloudinary dashboard to use Cloudinary image transformation later in this post to transform the AI-generated image into a blog post banner image. 

Log in to your Cloudinary dashboard to retrieve environment credentials such as the cloud name, API key, and API secret.

Then, create an .env.local file in the root folder of the project using the following command:

For macOS and Linux:

touch .env.local

For Windows(Command Prompt):

type NUL > .env.local

For Windows(PowerShell):

New-Item -Path .env.local -ItemType File

Add your environment credentials:

NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME="*********************"
NEXT_PUBLIC_CLOUDINARY_API_KEY="*********************"
NEXT_PUBLIC_CLOUDINARY_API_SECRET="*********************"Code language: JavaScript (javascript)

Replace ********************* with your credentials.

DALL·E-3, the latest version of the DALL-E text-to-image models can produce high-quality images across various domains based on text descriptions. The generation API endpoint creates an image based on a text prompt, which you will use in this tutorial. 

However, before using it, you must set up a secret key in your application to send a request to the endpoint. Login to the OpenAI dashboard to create or retrieve your secret key if you already have one.

Get a Secret Key from OpenAI
Click API Keys

Create an API key to access the OpenAI API.

Next, add it to your .env.local.

<code>OPENAI_API_KEY="sk-*********************"</code>Code language: HTML, XML (xml)

Replace sk-********************* with your secret key.

You’re all set. In the following section, you’ll implement the AI image generation API by requesting the OpenAI endpoint.

In this section, you’ll implement the AI image generation API by requesting the OpenAI endpoint using the latest version of the DALL-E text-to-image models. 

First, create a folder, generate-image inside the api directory, and add a file named route.js. 

This file will handle the AI image generation by requesting the OpenAI endpoint and authorizing it using your OpenAI secret key. The request object would include the following information:


{
  model: "dall-e-3",
  prompt: `Create a simple, professional, and relatable blog banner image that represents: "${title}". The image should be clear, not abstract, and suitable for a professional blog post. Avoid text in the image. Focus on symbolic or metaphorical representations that align with the title's theme. The image should work well as a background with text overlay.`,
  n: 1,
  size: "1024x1024"
}Code language: JavaScript (javascript)
Note:

You can modify this prompt to fit your unique style or consider any other factors you deem important.

In the request object, the model DALL-E-3 was passed with a prompt customized to generate a professional and relatable blog banner image representing the blog title. The parameter n was specified as 1 to return one image and its size. Learn more about the OpenAI image generation API.

Next, add the following code snippet to send a request to the OpenAI endpoint for image generation:


// app/api/generate-image/route.js

import { NextResponse } from "next/server";

export async function POST(req) {
  const { title } = await req.json();

  try {
    // Generate image with DALL-E
    const dalleResponse = await fetch(
      "https://api.openai.com/v1/images/generations",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
        },
        body: JSON.stringify({
          model: "dall-e-3",
          prompt: `Create a simple, professional, and relatable blog banner image that represents: "${title}". The image should be clear, not abstract, and suitable for a professional blog post. Avoid text in the image. Focus on symbolic or metaphorical representations that align with the title's theme.The image should work well as a background with text overlay.`,
          n: 1,
          size: "1024x1024",
        }),
      }
    );

    if (!dalleResponse.ok) {
      const error = await dalleResponse.json();
      console.error("Error generating image:", error);
      return NextResponse.json(
        { error: "Failed to generate image" },
        { status: 500 }
      );
    }
    const dalleData = await dalleResponse.json();
    const imageUrl = dalleData.data[0].url;

    return NextResponse.json({ imageUrl: imageUrl });
  } catch (error) {
    console.error("Error generating image:", error);
    return NextResponse.json(
      { error: "Failed to generate image" },
      { status: 500 }
    );
  }
}Code language: JavaScript (javascript)

Navigate to the components/ImageForm.js file and create a function named generateImage to send a request to the API endpoint you just created. Update the ImageForm.js with the following code snippet:


// app/components/ImageForm.js

//...
export default function ImageForm() {
  //...
    const generateImage = async () => {
      setLoading(true);
      try {
        const response = await fetch("/api/generate-image", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ title }),
        });
  
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        const data = await response.json();
        console.log(decodeURIComponent(data.imageUrl)); // Log the response for test
      } catch (error) {
        console.error("Error generating image:", error);
      } finally {
        setLoading(false);
      }
    };

  return (
    <div>
      //...
      <button
        //...
        disabled={loading}
        onClick={generateImage} // Add onclick event
      >
      </button>
    </div>
  );
}Code language: JavaScript (javascript)

Go to your browser and access http://localhost:3000. You should see a UI like the one below, where you can enter any title and click the Generate Image button. 

Take a look at your browser console. If everything goes well, you should see the API response, which returns an image URL similar to the one below.

https://oaidalleapiprodscus.blob.core.windows.net/private/org-u7SLmTadQLSIea21t5kNJE5B/user-AEYVzQyrf7rxYk3V9sesI4X0/img-WGAy1yrVMT0A7gxRkn96oHz1.png?st=2024-07-16T22:36:18Z&se=2024-07-17T00:36:18Z&sp=r&sv=2023-11-03&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-07-16T23:36:18Z&ske=2024-07-17T23:36:18Z&sks=b&skv=2023-11-03&sig=b211x3YQOzax6c6UPOAojy/qmJiSOlnFNo0gPqHnZ3Y=Code language: JavaScript (javascript)

Now that you have implemented the AI image generation API, you can implement a Cloudinary image upload and transformation to add layered text and an opaque dark background, ensuring your banner looks professional. To do that, navigate to app/api/generate-image/route.js, where you previously implemented the image generation. 

Add Cloudinary config using your credentials:


// app/api/generate-image/route.js
import { NextResponse } from "next/server";
import { v2 as cloudinary } from "cloudinary";

cloudinary.config({
  cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
  api_key: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
  api_secret: process.env.NEXT_PUBLIC_CLOUDINARY_API_SECRET,
});

export async function POST(req) {
  //...
}
Code language: JavaScript (javascript)

Next, update it with the following code snippet to add image upload and transformation:


// app/api/generate-image/route.js
export async function POST(req) {
  //...
  try {
    //...
    const dalleData = await dalleResponse.json();
    const imageUrl = dalleData.data[0].url;

    // Upload image to Cloudinary
    const uploadResponse = await cloudinary.uploader.upload(imageUrl);

    // Apply transformations step by step
    const transformedImageUrl = cloudinary.url(uploadResponse.public_id, {
      transformation: [
        { width: 1200, height: 630, crop: "fill", gravity: "center" },
        { effect: "brightness:-80" },
        {
          overlay: {
            font_family: "Roboto",
            font_size: 70,
            font_weight: "bold",
            text: encodeURIComponent(encodeURIComponent(title)),
          },
          color: "white",
          gravity: "center",
          y: 0,
          width: 1000,
          crop: "fit",
        },
        { effect: "shadow:30", color: "black" },
      ],
    });

    return NextResponse.json({ imageUrl: transformedImageUrl });
  } catch (error) {
    console.error("Error generating image:", error);
    return NextResponse.json(
      { error: "Failed to generate image" },
      { status: 500 }
    );
  }
}Code language: JavaScript (javascript)

In the code above, you:

  • Uploaded the generated image URL to Cloudinary.
  • Applied transformations in Cloudinary:
    • Resized to 1200×630 and center cropped.
    • Applied a brightness effect of -80.
    • Overlaid the title text using the specified font and style.
    • Added a shadow effect.
  • Returned the transformed image URL as JSON.
  • Logged an error and returned a 500 status with an error message if the process fails.

Next, update the UI to display the transformed image from Cloudinary. Update the ImageForm.js with the following code snippet:


// app/components/ImageForm.js
//...
export default function ImageForm() {
  //...

  const generateImage = async () => {
    setLoading(true);
    try {
      //...
      setImageUrl(decodeURIComponent(data.imageUrl)); // set the image URL

    } catch (error) {
      console.error("Error generating image:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    //...
  );
}Code language: JavaScript (javascript)

You’re almost done. In the following section, you’ll implement the save image functionality before testing the complete application.

To implement a download button to save the image generated, you need to create a function named saveImage to save the generated image. Update the app/components/ImageForm.js file with the following code snippet:


// app/components/ImageForm.js
//...
export default function ImageForm() {
 //...

  const generateImage = async () => {
    //...
  };

  const saveImage = () => {
    const link = document.createElement("a");
    link.href = imageUrl;
    link.download = `${title.replace(/\s+/g, "_")}.png`;
    link.click();
  };

  return (
    <div>
      //...
      
      {imageUrl && (
        <div className="mt-6 text-center">
          //...
          <button
            className="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 transition-colors"
            onClick={saveImage} // Add onclick event here
          >
            Save Image
          </button>
        </div>
      )}
    </div>
  );
}Code language: JavaScript (javascript)

Now, it’s time to test the application by entering your preferred blog title, generating a blog post banner image, and downloading it. Depending on the title you entered, you should have something similar to this: 

Download the a copy of the transformed image by clicking the Save Image button.

In this blog post, you learned how to auto-generate AI images for your Next.js blog using DALL-E 3 and Cloudinary. With a blog post title, you can create stunning, professional banner images that perfectly match your content. 

Cloudinary’s integration allows you to apply advanced transformations, ensuring your images are well-styled and ready for your audience. Additionally, the easy-to-use save button makes downloading your final images effortless. Remember, you can modify any step of this tutorial to fit your use case. Automate your entire image management lifecycle, from upload and transformation to optimization and delivery. To learn more, contact us today.

If you found this blog post helpful and want to discuss it more, head over to the Cloudinary Community forum and its associated Discord. The community would love to hear about your projects and experiences.

Back to top