{"id":35515,"date":"2024-09-06T07:00:00","date_gmt":"2024-09-06T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=35515"},"modified":"2024-09-06T09:52:58","modified_gmt":"2024-09-06T16:52:58","slug":"create-blog-from-image-ai-react","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react","title":{"rendered":"How to Create a Blog From an Image Using AI in React"},"content":{"rendered":"\n<p>This blog post focuses on how to leverage <a href=\"https:\/\/cloudinary.com\/products\/cloudinary_ai\">Cloudinary AI<\/a> to enhance your content creation workflow by analyzing image content and generating intelligent image captions. These captions will be passed into the <a href=\"https:\/\/platform.openai.com\/docs\/guides\/chat-completions\">ChatGPT API<\/a> to craft compelling marketing blog posts tailored to the specific vertical of the provided image. We\u2019ll also walk through how to use <a href=\"https:\/\/platform.openai.com\/docs\/guides\/text-to-speech\">OpenAI&#8217;s text-to-speech<\/a> technology to create an audible version of your blog post, ensuring an engaging content experience for your audience.<\/p>\n\n\n\n<p>By following this guide, developers will be able to transform static images into dynamic marketing assets that captivate and inform their audience. Let&#8217;s explore how combining Cloudinary&#8217;s GenAI, ChatGPT, and text-to-speech technologies can revolutionize your marketing strategy.<\/p>\n\n\n\n<p>This is an example of an output of the app in which I provided the image of a red Ferrari and the app created the following marketing blog post, while also providing the user the ability to listen to the blog post with text-to-speech technology:<\/p>\n\n\n\n<p><strong>GitHub Repo<\/strong>: <a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\">Cloudinary-React-Image-to-Blog-AI<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"632\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_632,c_scale\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35516\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641425\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641425\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-1.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Part 1: Set Up Cloudinary<\/h2>\n\n\n\n<p>To begin, log in to your <a href=\"https:\/\/cloudinary.com\/\">Cloudinary account or create a free account<\/a>. If prompted with the question, \u201cWhat\u2019s your main interest?\u201d, select <strong>Coding with APIs and SDKs<\/strong> or <strong>Skip<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"400\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_400,c_scale\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35517\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641419\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641419\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-2.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Cloudinary Cloud<\/h3>\n\n\n\n<p>In your account, select <strong>Settings <\/strong>><strong> Product Environments<\/strong>. Here, you\u2019ll see the cloud that you created. Let\u2019s click the three-dot menu to edit your Cloudinary Cloud Name.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"595\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_595,c_scale\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35518\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641414\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641414\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Edit the product environment and name your cloud, then click <strong>Save Changes<\/strong>.<\/p>\n\n\n\n<p>It\u2019s important to keep the same cloud name across different tools to be consistent.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"595\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_595,c_scale\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35519\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641410\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641410\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-3-1.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Get Cloudinary API Keys<\/h3>\n\n\n\n<p>In your account, select <strong>Settings <\/strong>&gt;<strong> Product Environments Setting<\/strong> &gt;<strong> API Keys<\/strong>. Click <strong>Generate New API Key <\/strong>and save these credentials in a safe place. We\u2019ll use them later.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"597\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_597,c_scale\/f_auto,q_auto\/v1725641406\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35520\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641406\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641406\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png?_i=AA 1183w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641406\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641406\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641406\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-5.png?_i=AA 1024w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Part 2:<\/strong> Set Up OpenAI<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Create an OpenAI account<\/h3>\n\n\n\n<p>To begin, log in to your&nbsp; <a href=\"https:\/\/platform.openai.com\/playground\/chat\">OpenAI Platform account or create a free account<\/a>. You\u2019ll be redirected to your OpenAI dashboard.<br><br>Now, click your avatar in the top right corner, then click <strong>Your Profile<\/strong> and you\u2019ll be redirected to your profile page.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"588\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_588,c_scale\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35521\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641398\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641398\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-6.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Add Credit to Your OpenAI account<\/h3>\n\n\n\n<p>Deposit money to start using the<strong> OpenAI API<\/strong> or <strong>SDK<\/strong>. Even an amount as small as $2-$5 is enough for you to start playing with OpenAI.\u00a0<\/p>\n\n\n\n<p>Inside the profile page, on the left side navigation, click <strong>Billing<\/strong>, then<strong> <\/strong>click <strong>Add payment details, <\/strong>and enter your bank account information to add credit to your account.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"588\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_588,c_scale\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35522\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641394\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641394\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-7.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>With OpenAI you can set charge limits so you won\u2019t be surprised by an unexpected bill.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Get API keys<\/h3>\n\n\n\n<p>Now it\u2019s time to generate an API Key to be used on our back-end server to use OpenAI\u2019s services. To do this, on your left navigation bar, click <strong>Your<\/strong><strong>Profile<\/strong>,<strong> <\/strong>then click <strong>Create new secret key.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"588\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_588,c_scale\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35523\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641390\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641390\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-8.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In the pop-up enter the name you want to give to your API key, I entered <strong>chatbot<\/strong>, but you can give any name you want. After entering your API key name, click<strong> Create a secret key<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"588\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_588,c_scale\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35524\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641383\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641383\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-9.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"599\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_599,c_scale\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35525\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641379\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA 1999w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641379\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-10.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Copy and paste the API key generated into a safe place and click <strong>Done<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Part 3:<\/strong> Build the React app<\/h2>\n\n\n\n<p>In this tutorial, I\u2019m using <a href=\"https:\/\/vitejs.dev\/guide\/\">Vite<\/a> to build my React application. I recommend you to do the same. Follow the instructions on Vite\u2019s official website to create a React application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Build the Image to Blog UI<\/h3>\n\n\n\n<p>In your <a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\/blob\/main\/src\/App.tsx\"><strong>App.tsx<\/strong><\/a> file replace the existing code with the following:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useState, useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'axios'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">'.\/App.css'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { AdvancedImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/react'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { fill } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/actions\/resize'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> ReactMarkdown <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-markdown'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> AudioPlayer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/AudioPlayer'<\/span>;\n\n\n<span class=\"hljs-keyword\">const<\/span> ImageUpload = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n <span class=\"hljs-keyword\">const<\/span> &#91;image, setImage] = useState(<span class=\"hljs-literal\">null<\/span>);\n <span class=\"hljs-keyword\">const<\/span> &#91;caption, setCaption] = useState(<span class=\"hljs-string\">''<\/span>);\n <span class=\"hljs-keyword\">const<\/span> &#91;story, setStory] = useState(<span class=\"hljs-string\">''<\/span>);\n <span class=\"hljs-keyword\">const<\/span> &#91;error, setError] = useState(<span class=\"hljs-string\">''<\/span>);\n <span class=\"hljs-keyword\">const<\/span> &#91;loading, setLoading] = useState(<span class=\"hljs-literal\">false<\/span>);\n <span class=\"hljs-keyword\">const<\/span> &#91;shouldSubmit, setShouldSubmit] = useState(<span class=\"hljs-literal\">false<\/span>);\n <span class=\"hljs-keyword\">const<\/span> cld = <span class=\"hljs-keyword\">new<\/span> Cloudinary({\n   <span class=\"hljs-attr\">cloud<\/span>: {\n     <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">'ai-devx-demo'<\/span>\n   }\n });\n\n\n useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n   <span class=\"hljs-keyword\">if<\/span> (shouldSubmit &amp;&amp; image) {\n     handleSubmit();\n   }\n }, &#91;shouldSubmit, image]);\n\n\n <span class=\"hljs-keyword\">const<\/span> handleImageChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">if<\/span> (e.target.files&#91;<span class=\"hljs-number\">0<\/span>] !== <span class=\"hljs-literal\">null<\/span>) {\n     setImage(e.target.files&#91;<span class=\"hljs-number\">0<\/span>]);\n     setShouldSubmit(<span class=\"hljs-literal\">true<\/span>);\n   }\n };\n\n\n <span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n   <span class=\"hljs-keyword\">if<\/span> (!image) {\n     alert(<span class=\"hljs-string\">'Please select an image to upload'<\/span>);\n     setShouldSubmit(<span class=\"hljs-literal\">false<\/span>);\n     <span class=\"hljs-keyword\">return<\/span>;\n   }\n\n\n   <span class=\"hljs-keyword\">const<\/span> formData = <span class=\"hljs-keyword\">new<\/span> FormData();\n   formData.append(<span class=\"hljs-string\">'image'<\/span>, image);\n\n\n   <span class=\"hljs-keyword\">try<\/span> {\n     setLoading(<span class=\"hljs-literal\">true<\/span>);\n     <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> axios.post(<span class=\"hljs-string\">'\/api\/caption'<\/span>, formData, {\n       <span class=\"hljs-attr\">headers<\/span>: {\n         <span class=\"hljs-string\">'Content-Type'<\/span>: <span class=\"hljs-string\">'multipart\/form-data'<\/span>,\n       },\n     });\n     setCaption(response.data.caption);\n     setStory(response.data.story.content);\n     <span class=\"hljs-keyword\">const<\/span> myImage = cld.image(response.data.public_id);\n\n\n     <span class=\"hljs-comment\">\/\/ Resize to 250 x 250 pixels using the 'fill' crop mode.<\/span>\n     myImage.resize(fill().width(<span class=\"hljs-number\">500<\/span>).height(<span class=\"hljs-number\">500<\/span>));\n     setImage(myImage);\n     setError(<span class=\"hljs-string\">''<\/span>); <span class=\"hljs-comment\">\/\/ Clear any previous error messages<\/span>\n   } <span class=\"hljs-keyword\">catch<\/span> (error) {\n     <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">'Error uploading image:'<\/span>, error);\n     setError(<span class=\"hljs-string\">'Error uploading image: '<\/span> + error.message);\n   } <span class=\"hljs-keyword\">finally<\/span> {\n     setShouldSubmit(<span class=\"hljs-literal\">false<\/span>);\n   }\n };\n\n\n <span class=\"hljs-keyword\">return<\/span> (\n   <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"app\"<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Image to Blog AI<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{(e)<\/span> =&gt;<\/span> e.preventDefault()}&gt;\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"custom-file-upload\"<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> <span class=\"hljs-attr\">accept<\/span>=<span class=\"hljs-string\">\"image\/*\"<\/span> <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{handleImageChange}<\/span> \/&gt;<\/span>\n         Choose File\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n     {loading &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"spinner\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>}\n     {error &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">color:<\/span> '<span class=\"hljs-attr\">red<\/span>' }}&gt;<\/span>{error}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>}\n     {image &amp;&amp; !loading &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">AdvancedImage<\/span> <span class=\"hljs-attr\">cldImg<\/span>=<span class=\"hljs-string\">{image}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{caption}<\/span> \/&gt;<\/span>}\n     {story &amp;&amp; (\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">AudioPlayer<\/span> <span class=\"hljs-attr\">text<\/span>=<span class=\"hljs-string\">{story}<\/span> <span class=\"hljs-attr\">setLoading<\/span>=<span class=\"hljs-string\">{setLoading}\/<\/span>&gt;<\/span>\n         {!loading &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ReactMarkdown<\/span>&gt;<\/span>{story}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ReactMarkdown<\/span>&gt;<\/span>}\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n     )}\n   <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n );\n};\n\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> ImageUpload;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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\n\n<p>Let\u2019s explain our front-end code:<br><br><code>handleImageChange Function:<\/code><\/p>\n\n\n<pre class=\"wp-block-code\" 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> handleImageChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">if<\/span> (e.target.files&#91;<span class=\"hljs-number\">0<\/span>] !== <span class=\"hljs-literal\">null<\/span>) {\n    setImage(e.target.files&#91;<span class=\"hljs-number\">0<\/span>]);\n    setShouldSubmit(<span class=\"hljs-literal\">true<\/span>);\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\n\n<p>This function handles the change event when a user selects an image file and checks if the first file in the selected files is not null.<\/p>\n\n\n\n<p>The <code>e<\/code><strong> <\/strong>parameter is the event object from the input file element. If a file is selected, it sets the state image to the selected file and sets <code>shouldSubmit<\/code> to true.<\/p>\n\n\n\n<p><code>handleSubmit Function:\u00a0<\/code><\/p>\n\n\n<pre class=\"wp-block-code\" 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-keyword\">const<\/span> handleSubmit = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n  <span class=\"hljs-keyword\">if<\/span> (!image) {\n    alert(<span class=\"hljs-string\">'Please select an image to upload'<\/span>);\n    setShouldSubmit(<span class=\"hljs-literal\">false<\/span>);\n    <span class=\"hljs-keyword\">return<\/span>;\n  }\n\n  <span class=\"hljs-keyword\">const<\/span> formData = <span class=\"hljs-keyword\">new<\/span> FormData();\n  formData.append(<span class=\"hljs-string\">'image'<\/span>, image);\n\n  <span class=\"hljs-keyword\">try<\/span> {\n    setLoading(<span class=\"hljs-literal\">true<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> axios.post(<span class=\"hljs-string\">'\/api\/caption'<\/span>, formData, {\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-string\">'Content-Type'<\/span>: <span class=\"hljs-string\">'multipart\/form-data'<\/span>,\n      },\n    });\n    setCaption(response.data.caption);\n    setStory(response.data.story.content);\n    <span class=\"hljs-keyword\">const<\/span> myImage = cld.image(response.data.public_id);\n\n    <span class=\"hljs-comment\">\/\/ Resize to 500 x 500 pixels using the 'fill' crop mode.<\/span>\n    myImage.resize(fill().width(<span class=\"hljs-number\">500<\/span>).height(<span class=\"hljs-number\">500<\/span>));\n    setImage(myImage);\n    setError(<span class=\"hljs-string\">''<\/span>); <span class=\"hljs-comment\">\/\/ Clear any previous error messages<\/span>\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">'Error uploading image:'<\/span>, error);\n    setError(<span class=\"hljs-string\">'Error uploading image: '<\/span> + error.message);\n  } <span class=\"hljs-keyword\">finally<\/span> {\n    setShouldSubmit(<span class=\"hljs-literal\">false<\/span>);\n    setLoading(<span class=\"hljs-literal\">false<\/span>);\n  }\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\n\n<p>This code ensures that when a user selects an image and submits the form, the image is uploaded to the server by sending a POST request to the endpoint <code>api\/caption<\/code>, on success updates the state with the caption and story received from the server, and the resulting image is resized and displayed back to the user. It uses <a href=\"https:\/\/cloudinary.com\/documentation\/react_integration\">Cloudinary\u2019s React SDK<\/a> to create an image object with the public ID returned by the server. Resize the image to 500&#215;500 pixels using the <code>fill<\/code> crop mode.<\/p>\n\n\n\n<p>Let\u2019s now style the app. In your app, replace the code inside the <code>App.css<\/code> with the code inside this <a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\/blob\/main\/src\/App.css\">file<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Configure Your React Vite App<\/h3>\n\n\n\n<p>If you want to easily make a call to your NodeJS backend without using CORS, you can configure your Vite app to proxy the backend endpoints. This step only applies if you created the React app using Vite.\u00a0<\/p>\n\n\n\n<p>Open your <code>vite.config.js<\/code> file and replace the content with the following code.<\/p>\n\n\n<pre class=\"wp-block-code\" 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\">import<\/span> { defineConfig } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vite'<\/span>\n<span class=\"hljs-keyword\">import<\/span> react <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@vitejs\/plugin-react'<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> defineConfig({\n  <span class=\"hljs-attr\">plugins<\/span>: &#91;react()],\n  <span class=\"hljs-attr\">server<\/span>: {\n    <span class=\"hljs-attr\">port<\/span>: <span class=\"hljs-number\">3000<\/span>,\n    <span class=\"hljs-attr\">proxy<\/span>: {\n      <span class=\"hljs-string\">\"\/api\"<\/span>: {\n        <span class=\"hljs-attr\">target<\/span>: <span class=\"hljs-string\">\"http:\/\/localhost:6000\"<\/span>,\n        <span class=\"hljs-attr\">changeOrigin<\/span>: <span class=\"hljs-literal\">true<\/span>,\n        <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">false<\/span>,\n      },\n    },\n  },\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\n\n<p>What we are doing here is proxying the backend with any path that is <code>\/api<\/code> to be forwarded to the target <a href=\"http:\/\/localhost:6000\"><strong>http:\/\/localhost:6000<\/strong><\/a>, which is the address of your backend server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Part 4: Build the NodeJS App<\/h2>\n\n\n\n<p>Time to work on the back end. In the root of your React app, create a file called <code>server.js<\/code> file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Set Up Your NodeJS Server<\/h3>\n\n\n\n<p>In the root of the project you have the <code>package.json<\/code>, we will use this same file for our backend. Replace everything that you currently have in the <code>package.json<\/code> copy and paste the content of <a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\/blob\/main\/package.json\">this file<\/a> into your <code>package.json<\/code>. Create an <code>.env<\/code> file, and enter the following:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">VITE_CLOUD_NAME=YOUR CLOUDINARY CLOUD NAME\nCLOUDINARY_CLOUD_NAME=YOUR CLOUDINARY CLOUD NAME\nCLOUDINARY_API_KEY=YOUR CLOUDINARY API KEY\nCLOUDINARY_API_SECRET=CLOUDINARY SECRET\nOPENAI_API_KEY=YOUR OPEN AI KEY<\/code><\/span><\/pre>\n\n\n<p>Replace the string with the OpenAI API Key you generated earlier.<\/p>\n\n\n\n<p>Copy and paste the following code into your <code>server.js<\/code> file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/* eslint-disable no-undef *\/<\/span>\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"dotenv\/config.js\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> express <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"express\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> cors <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cors\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> multer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"multer\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> streamifier <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"streamifier\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> OpenAI <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"openai\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> path <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"path\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { fileURLToPath } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"url\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> fs <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"fs\/promises\"<\/span>;\n\n\n<span class=\"hljs-keyword\">const<\/span> openai = <span class=\"hljs-keyword\">new<\/span> OpenAI({\n <span class=\"hljs-attr\">apiKey<\/span>: process.env.OPENAI_API_KEY,\n});\n\n\n<span class=\"hljs-keyword\">const<\/span> __filename = fileURLToPath(<span class=\"hljs-keyword\">import<\/span>.meta.url);\n<span class=\"hljs-keyword\">const<\/span> __dirname = path.dirname(__filename);\n\n\n<span class=\"hljs-keyword\">const<\/span> app = express();\napp.use(express.json());\napp.use(cors());\n\n\n<span class=\"hljs-comment\">\/\/ Configure Cloudinary with secure URLs and credentials<\/span>\ncloudinary.config({\n <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUDINARY_CLOUD_NAME,\n <span class=\"hljs-attr\">api_key<\/span>: process.env.CLOUDINARY_API_KEY,\n <span class=\"hljs-attr\">api_secret<\/span>: process.env.CLOUDINARY_API_SECRET,\n});\n\n\n<span class=\"hljs-comment\">\/\/ Configure multer for file upload<\/span>\n<span class=\"hljs-keyword\">const<\/span> storage = multer.memoryStorage();\n<span class=\"hljs-keyword\">const<\/span> upload = multer({ <span class=\"hljs-attr\">storage<\/span>: storage });\n\n\n<span class=\"hljs-comment\">\/\/ Define a POST endpoint to handle image upload<\/span>\napp.post(<span class=\"hljs-string\">\"\/api\/caption\"<\/span>, upload.single(<span class=\"hljs-string\">\"image\"<\/span>), (req, res) =&gt; {\n <span class=\"hljs-keyword\">if<\/span> (!req.file) {\n   <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">400<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: <span class=\"hljs-string\">\"Image file is required\"<\/span> });\n }\n\n\n <span class=\"hljs-keyword\">const<\/span> uploadStream = cloudinary.uploader.upload_stream(\n   { <span class=\"hljs-attr\">detection<\/span>: <span class=\"hljs-string\">\"captioning\"<\/span> },\n   <span class=\"hljs-keyword\">async<\/span> (error, result) =&gt; {\n     <span class=\"hljs-keyword\">if<\/span> (error) {\n       <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Cloudinary error:\"<\/span>, error);\n       <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">500<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: error.message });\n     }\n     <span class=\"hljs-keyword\">const<\/span> story = <span class=\"hljs-keyword\">await<\/span> generateBlog(\n       result.info.detection.captioning.data.caption\n     );\n     <span class=\"hljs-keyword\">const<\/span> resObj = {\n       <span class=\"hljs-attr\">public_id<\/span>: result.public_id,\n       <span class=\"hljs-attr\">caption<\/span>: result.info.detection.captioning.data.caption,\n       story,\n     };\n     res.json(resObj);\n   }\n );\n\n\n streamifier.createReadStream(req.file.buffer).pipe(uploadStream);\n});\n\n\napp.post(<span class=\"hljs-string\">\"\/api\/generate-audio\"<\/span>, <span class=\"hljs-keyword\">async<\/span> (req, res) =&gt; {\n <span class=\"hljs-keyword\">try<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> mp3 = <span class=\"hljs-keyword\">await<\/span> openai.audio.speech.create({\n     <span class=\"hljs-attr\">model<\/span>: <span class=\"hljs-string\">\"tts-1\"<\/span>,\n     <span class=\"hljs-attr\">voice<\/span>: <span class=\"hljs-string\">\"alloy\"<\/span>,\n     <span class=\"hljs-attr\">input<\/span>: req.body.text,\n   });\n   <span class=\"hljs-keyword\">const<\/span> buffer = Buffer.from(<span class=\"hljs-keyword\">await<\/span> mp3.arrayBuffer());\n   <span class=\"hljs-keyword\">const<\/span> filePath = path.resolve(__dirname, <span class=\"hljs-string\">\"public\"<\/span>, <span class=\"hljs-string\">\"speech.mp3\"<\/span>);\n   <span class=\"hljs-keyword\">await<\/span> fs.writeFile(filePath, buffer);\n   res.json({ <span class=\"hljs-attr\">audioUrl<\/span>: <span class=\"hljs-string\">`\/speech.mp3`<\/span> });\n } <span class=\"hljs-keyword\">catch<\/span> (error) {\n   <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error generating audio:\"<\/span>, error);\n   res.status(<span class=\"hljs-number\">500<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: <span class=\"hljs-string\">\"Error generating audio\"<\/span> });\n }\n});\n\n\n<span class=\"hljs-keyword\">const<\/span> generateBlog = <span class=\"hljs-keyword\">async<\/span> (caption) =&gt; {\n <span class=\"hljs-keyword\">const<\/span> message = {\n   <span class=\"hljs-attr\">role<\/span>: <span class=\"hljs-string\">\"user\"<\/span>,\n   <span class=\"hljs-attr\">content<\/span>: <span class=\"hljs-string\">`create an 300 world blog post to be used as part of a marketing campaign from a business--\n   the blog must focused on the vertical industry of that image based on the following caption of the image: <span class=\"hljs-subst\">${caption}<\/span>.\n    This blog is not for the business but for the person interested in the vetical industry of the image`<\/span>,\n };\n\n\n <span class=\"hljs-comment\">\/**\n  * Call the OpenAI SDK and get a response\n  *\/<\/span>\n <span class=\"hljs-keyword\">try<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> openai.chat.completions.create({\n     <span class=\"hljs-attr\">model<\/span>: <span class=\"hljs-string\">\"gpt-3.5-turbo\"<\/span>,\n     <span class=\"hljs-attr\">messages<\/span>: &#91;message], <span class=\"hljs-comment\">\/\/ pass the new message and the previous messages<\/span>\n   });\n   <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"open ai response\"<\/span>, response.choices&#91;<span class=\"hljs-number\">0<\/span>].message);\n   <span class=\"hljs-keyword\">return<\/span> response.choices&#91;<span class=\"hljs-number\">0<\/span>].message;\n } <span class=\"hljs-keyword\">catch<\/span> (error) {\n   <span class=\"hljs-built_in\">console<\/span>.error(error);\n   <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">`error: Internal Server Error`<\/span>;\n }\n};\n\n\napp.use(express.static(path.resolve(__dirname, <span class=\"hljs-string\">\"public\"<\/span>)));\n<span class=\"hljs-keyword\">const<\/span> PORT = <span class=\"hljs-number\">9000<\/span>;\napp.listen(PORT, () =&gt; {\n <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Server is running on port <span class=\"hljs-subst\">${PORT}<\/span>`<\/span>);\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\n\n<p>Let\u2019s explain the code we have on our server.<\/p>\n\n\n\n<p>This code sets up an Express server that handles image uploads and generates captions and audio from those images using Cloudinary and OpenAI services. Here\u2019s a detailed explanation:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Importing Dependencies and Configuration<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"dotenv\/config.js\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> express <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"express\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> cors <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cors\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> multer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"multer\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> streamifier <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"streamifier\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> OpenAI <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"openai\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> path <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"path\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { fileURLToPath } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"url\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> fs <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"fs\/promises\"<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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\n\n<ul class=\"wp-block-list\">\n<li><strong>dotenv\/config.js<\/strong>. Loads environment variables from an <code>.env<\/code> file.<\/li>\n\n\n\n<li><strong>express.<\/strong> Web framework for creating the server.<\/li>\n\n\n\n<li><strong>cors<\/strong>. Middleware to enable Cross-Origin Resource Sharing.<\/li>\n\n\n\n<li><strong>cloudinary<\/strong>. For image upload and processing.<\/li>\n\n\n\n<li><strong>multer<\/strong>. Middleware for handling `multipart\/form-data`, used for file uploads.<\/li>\n\n\n\n<li><strong>streamifier<\/strong>. Converts a buffer into a readable stream.<\/li>\n\n\n\n<li><strong>OpenAI<\/strong>. Interface to interact with OpenAI&#8217;s API.<\/li>\n\n\n\n<li><strong>path, fileURLToPath, fs\/promises<\/strong>. Utilities for handling file paths and file operations.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">OpenAI Configuration<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" 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> openai = <span class=\"hljs-keyword\">new<\/span> OpenAI({\n  <span class=\"hljs-attr\">apiKey<\/span>: process.env.OPENAI_API_KEY,\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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\n\n<ul class=\"wp-block-list\">\n<li>Configures OpenAI with the API key from the environment variables.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Path Configuration<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" 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> __filename = fileURLToPath(<span class=\"hljs-keyword\">import<\/span>.meta.url);\n<span class=\"hljs-keyword\">const<\/span> __dirname = path.dirname(__filename);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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\n\n<ul class=\"wp-block-list\">\n<li>Defines <code>__filename<\/code> and <code>__dirname<\/code> to work with module-based imports.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Express App Setup<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> app = express();\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">express<\/span>.<span class=\"hljs-title\">json<\/span>());\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">cors<\/span>());<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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\n\n<ul class=\"wp-block-list\">\n<li>Initializes the Express app and sets up middleware for JSON parsing and CORS.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Cloudinary Configuration<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">cloudinary<\/span><span class=\"hljs-selector-class\">.config<\/span>({\n  <span class=\"hljs-attribute\">secure<\/span>: true,\n  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,\n  api_key: process.env.CLOUDINARY_API_KEY,\n  api_secret: process.env.CLOUDINARY_API_SECRET,\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Configures Cloudinary with secure URLs and credentials from environment variables.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Multer Configuration<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" 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> storage = multer.memoryStorage();\n<span class=\"hljs-keyword\">const<\/span> upload = multer({ <span class=\"hljs-attr\">storage<\/span>: storage });<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><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\n\n<ul class=\"wp-block-list\">\n<li>Configures Multer to store uploaded files in memory.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Image Upload and Caption Generation Endpoint<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">app.post(<span class=\"hljs-string\">\"\/api\/caption\"<\/span>, upload.single(<span class=\"hljs-string\">\"image\"<\/span>), (req, res) =&gt; {\n  <span class=\"hljs-keyword\">if<\/span> (!req.file) {\n    <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">400<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: <span class=\"hljs-string\">\"Image file is required\"<\/span> });\n  }\n\n  <span class=\"hljs-keyword\">const<\/span> uploadStream = cloudinary.uploader.upload_stream(\n    { <span class=\"hljs-attr\">detection<\/span>: <span class=\"hljs-string\">\"captioning\"<\/span> },\n    <span class=\"hljs-keyword\">async<\/span> (error, result) =&gt; {\n      <span class=\"hljs-keyword\">if<\/span> (error) {\n        <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Cloudinary error:\"<\/span>, error);\n        <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">500<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: error.message });\n      }\n      <span class=\"hljs-keyword\">const<\/span> story = <span class=\"hljs-keyword\">await<\/span> generateBlog(\n        result.info.detection.captioning.data.caption\n      );\n      <span class=\"hljs-keyword\">const<\/span> resObj = {\n        <span class=\"hljs-attr\">public_id<\/span>: result.public_id,\n        <span class=\"hljs-attr\">caption<\/span>: result.info.detection.captioning.data.caption,\n        story,\n      };\n      res.json(resObj);\n    }\n  );\nstreamifier.createReadStream(req.file.buffer).pipe(uploadStream);\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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\n\n<ul class=\"wp-block-list\">\n<li>Endpoint to handle image upload.<\/li>\n\n\n\n<li>Uploads the image to Cloudinary, which generates a caption.<\/li>\n\n\n\n<li>Calls `generateBlog` to create a blog post based on the caption.<\/li>\n\n\n\n<li>Returns the public ID, caption, and blog story as a JSON response.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">\u00a0Audio Generation Endpoint<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">app.post(<span class=\"hljs-string\">\"\/api\/generate-audio\"<\/span>, <span class=\"hljs-keyword\">async<\/span> (req, res) =&gt; {\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> mp3 = <span class=\"hljs-keyword\">await<\/span> openai.audio.speech.create({\n      <span class=\"hljs-attr\">model<\/span>: <span class=\"hljs-string\">\"tts-1\"<\/span>,\n      <span class=\"hljs-attr\">voice<\/span>: <span class=\"hljs-string\">\"alloy\"<\/span>,\n      <span class=\"hljs-attr\">input<\/span>: req.body.text,\n    });\n    <span class=\"hljs-keyword\">const<\/span> buffer = Buffer.from(<span class=\"hljs-keyword\">await<\/span> mp3.arrayBuffer());\n    <span class=\"hljs-keyword\">const<\/span> filePath = path.resolve(__dirname, <span class=\"hljs-string\">\"public\"<\/span>, <span class=\"hljs-string\">\"speech.mp3\"<\/span>);\n    <span class=\"hljs-keyword\">await<\/span> fs.writeFile(filePath, buffer);\n    res.json({ <span class=\"hljs-attr\">audioUrl<\/span>: <span class=\"hljs-string\">`\/speech.mp3`<\/span> });\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error generating audio:\"<\/span>, error);\n    res.status(<span class=\"hljs-number\">500<\/span>).json({ <span class=\"hljs-attr\">error<\/span>: <span class=\"hljs-string\">\"Error generating audio\"<\/span> });\n  }\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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\n\n<ul class=\"wp-block-list\">\n<li>Endpoint to generate audio from text using OpenAI&#8217;s text-to-speech model.<\/li>\n\n\n\n<li>Converts the text to audio and saves it as an MP3 file.<\/li>\n\n\n\n<li>Returns the URL to the generated audio file.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Blog Generation Function<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" 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> generateBlog = <span class=\"hljs-keyword\">async<\/span> (caption) =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> message = {\n    <span class=\"hljs-attr\">role<\/span>: <span class=\"hljs-string\">\"user\"<\/span>,\n    <span class=\"hljs-attr\">content<\/span>: <span class=\"hljs-string\">`create an 300 world blog post to be used as part of a marketing campaign from a business-- \n    the blog must focused on the vertical industry of that image based on the following caption of the image: <span class=\"hljs-subst\">${caption}<\/span>.\n     This blog is not for the business but for the person interested in the vetical industry of the image`<\/span>,\n  };\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> openai.chat.completions.create({\n      <span class=\"hljs-attr\">model<\/span>: <span class=\"hljs-string\">\"gpt-3.5-turbo\"<\/span>,\n      <span class=\"hljs-attr\">messages<\/span>: &#91;message],\n    });\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"open ai response\"<\/span>, response.choices&#91;<span class=\"hljs-number\">0<\/span>].message);\n    <span class=\"hljs-keyword\">return<\/span> response.choices&#91;<span class=\"hljs-number\">0<\/span>].message;\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.error(error);\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">`error: Internal Server Error`<\/span>;\n  }\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><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\n\n<ul class=\"wp-block-list\">\n<li>Generates a blog post based on the caption using OpenAI&#8217;s GPT-3.5-turbo model.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Static File Serving and Server Initialization<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">app.use(express.static(path.resolve(__dirname, <span class=\"hljs-string\">\"public\"<\/span>)));\n<span class=\"hljs-keyword\">const<\/span> PORT = <span class=\"hljs-number\">6000<\/span>;\napp.listen(PORT, () =&gt; {\n  <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Server is running on port <span class=\"hljs-subst\">${PORT}<\/span>`<\/span>);\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><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\n\n<ul class=\"wp-block-list\">\n<li>Serves static files from the &#8220;public&#8221; directory.<\/li>\n\n\n\n<li>Starts the server on port 6000.<\/li>\n<\/ul>\n\n\n\n<p>This code sets up a comprehensive server for handling image uploads, generating captions, creating blog posts, and converting text to speech using Cloudinary and OpenAI services.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Part 5: Test the App<\/h2>\n\n\n\n<p>The first thing we have to do is to run<strong> <\/strong><code>npm install<\/code><strong> <\/strong>in the root of your project to install the frontend and backend dependencies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Run the Back-End Server<\/h3>\n\n\n\n<p>Open your terminal and run <code>npm run start<\/code><strong>. <\/strong>Nodemon will run your express server in NodeJS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Run the Front-End Server<\/h3>\n\n\n\n<p>Open your other terminal, run <strong>npm run dev<\/strong>,<strong> <\/strong>and navigate to <a href=\"http:\/\/localhost:3000\/\">http:\/\/localhost:3000\/<\/a>.<br>You should see this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"578\" data-public-id=\"Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_578,c_scale\/f_auto,q_auto\/v1725641376\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png?_i=AA\" alt=\"\" class=\"wp-post-35515 wp-image-35526\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1725641376\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641376\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png?_i=AA 1458w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641376\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641376\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1725641376\/Web_Assets\/blog\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11\/blog-How-to-Create-a-Blog-From-an-Image-Using-AI-in-React-11.png?_i=AA 1024w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now, choose a file and convert it into a blog post. Feel free to use your own image or you can use our sample images as well.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\/blob\/main\/alquilar-deportivo-ferrari-f8.jpeg\">Red Ferrari<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\/blob\/main\/island.png\">Man looking at the ocean and mountains<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Part 6: Conclusion<\/h2>\n\n\n\n<p>In conclusion, this guide has shown you how to leverage Cloudinary&#8217;s GenAI, OpenAI&#8217;s ChatGPT, and text-to-speech technologies to enhance your marketing content creation. By automating the generation of intelligent captions and transforming them into engaging blog posts, you can efficiently produce high-quality marketing materials. The added text-to-speech capability ensures a versatile and immersive content experience for your audience.<\/p>\n\n\n\n<p>The example of a red Ferrari image turned into a compelling blog post with an audible version, highlights the practical application and potential of this approach. <a href=\"https:\/\/cloudinary.com\/\">Try Cloudinary\u2019s advanced AI<\/a> features to transform static images into dynamic marketing assets and elevate your content today.<\/p>\n\n\n\n<p>To stay updated with the latest product features, follow <a href=\"https:\/\/twitter.com\/cloudinary\">Cloudinary<\/a> on Twitter, explore other <a href=\"https:\/\/github.com\/cloudinary-community\">sample apps<\/a>, and join our <a href=\"https:\/\/discord.gg\/AJWHaMuk\">Discord server<\/a> and<a href=\"https:\/\/community.cloudinary.com\/\"> Community forum<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<p><strong>GitHub Repo<\/strong>: <a href=\"https:\/\/github.com\/cloudinary-devs\/Cloudinary-React-Image-to-Blog-AI\">&nbsp;Cloudinary-React-Image-to-Blog-AI<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog post focuses on how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions. These captions will be passed into the ChatGPT API to craft compelling marketing blog posts tailored to the specific vertical of the provided image. We\u2019ll also walk through how to [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":35528,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[336,332,383,246],"class_list":["post-35515","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-ai","tag-api","tag-nodejs","tag-react"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Create a Blog From an Image Using AI in React<\/title>\n<meta name=\"description\" content=\"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.\" \/>\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\/create-blog-from-image-ai-react\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Create a Blog From an Image Using AI in React\" \/>\n<meta property=\"og:description\" content=\"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-09-06T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-06T16:52:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1724279573\/image_to_blog-blog\/image_to_blog-blog-jpg?_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\/jpeg\" \/>\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\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"How to Create a Blog From an Image Using AI in React\",\"datePublished\":\"2024-09-06T14:00:00+00:00\",\"dateModified\":\"2024-09-06T16:52:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\"},\"wordCount\":1465,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA\",\"keywords\":[\"AI\",\"API\",\"Node(JS)\",\"React\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\",\"url\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\",\"name\":\"How to Create a Blog From an Image Using AI in React\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA\",\"datePublished\":\"2024-09-06T14:00:00+00:00\",\"dateModified\":\"2024-09-06T16:52:58+00:00\",\"description\":\"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Create a Blog From an Image Using AI in React\"}]},{\"@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:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"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":"How to Create a Blog From an Image Using AI in React","description":"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.","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\/create-blog-from-image-ai-react","og_locale":"en_US","og_type":"article","og_title":"How to Create a Blog From an Image Using AI in React","og_description":"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.","og_url":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react","og_site_name":"Cloudinary Blog","article_published_time":"2024-09-06T14:00:00+00:00","article_modified_time":"2024-09-06T16:52:58+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1724279573\/image_to_blog-blog\/image_to_blog-blog-jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"How to Create a Blog From an Image Using AI in React","datePublished":"2024-09-06T14:00:00+00:00","dateModified":"2024-09-06T16:52:58+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react"},"wordCount":1465,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA","keywords":["AI","API","Node(JS)","React"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react","url":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react","name":"How to Create a Blog From an Image Using AI in React","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA","datePublished":"2024-09-06T14:00:00+00:00","dateModified":"2024-09-06T16:52:58+00:00","description":"Read how to leverage Cloudinary AI to enhance your content creation workflow by analyzing image content and generating intelligent image captions.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/create-blog-from-image-ai-react#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Create a Blog From an Image Using AI in React"}]},{"@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:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","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"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1724279573\/image_to_blog-blog\/image_to_blog-blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/35515","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=35515"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/35515\/revisions"}],"predecessor-version":[{"id":35530,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/35515\/revisions\/35530"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/35528"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=35515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=35515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=35515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}