{"id":28413,"date":"2022-05-04T07:02:28","date_gmt":"2022-05-04T07:02:28","guid":{"rendered":"http:\/\/auto-tag-and-categorize-images-using-cloudinary"},"modified":"2025-02-25T16:17:44","modified_gmt":"2025-02-26T00:17:44","slug":"auto-tag-and-categorize-images-using-cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/","title":{"rendered":"Auto-Tag and Categorize Images Using Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>An ever-increasing amount of visual data is created and stored due to the rapid evolution of digital technology. Therefore, there is an urgent need for an effective and efficient tool or mechanism for categorizing and finding visual information on demand. <a href=\"https:\/\/cloudinary.com\/glossary\/image-tagging\">Image tagging<\/a> is adding text tags to an image based on what is in the image.<\/p>\n<p>Although images can be annotated manually by humans, this approach can be too subjective and even impractical when there are a large number of images. However, a better approach is image auto-tagging, a time-saving and cost-effective process by which tags in the form of keywords are automatically assigned to digital images and are used to organize and retrieve images of interest from a collection or database. Images that have been auto-tagged can be retrieved using those tags or labels.<\/p>\n<p><a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> offers a <a href=\"https:\/\/cloudinary.com\/documentation\/google_auto_tagging_addon\">Google auto-tagging add-on<\/a> fully integrated into its image management and transformation system and allows detecting, automatically categorizing, and assigning multiple tags to images based on the categories in each image.<\/p>\n<p>In this article, we\u2019ll go through how to use Cloudinary to generate tags for images automatically, fetch the generated image tags, and access image resources based on a specified tag.<\/p>\n<p>Here is a <a href=\"https:\/\/codesandbox.io\/s\/cloudinary-google-image-auto-tagging-l61kno\">link<\/a> to the demo CodeSandbox.<\/p>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/cloudinary-google-image-auto-tagging-l61kno?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"cloudinary-google-image-auto-tagging-l61kno\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n\n<div class=\"wp-block-cloudinary-markdown \"><h2>Setting Up the Project<\/h2>\n<p>Create a new Next.js application using the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-next-app cloudinary-image-autotag\n<\/code><\/span><\/pre>\n<p>Next, let\u2019s add the project dependencies using the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install cloudinary axios dotenv\n<\/code><\/span><\/pre>\n<p>Now we can start our application on <a href=\"http:\/\/localhost:3000\/\">http:\/\/localhost:3000\/<\/a> using the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm start\n<\/code><\/span><\/pre>\n<h2>Setting up Cloudinary<\/h2>\n<p>First, sign up for a <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">free Cloudinary account<\/a> if you don\u2019t have one already. Displayed on your account\u2019s Management Console (aka Dashboard) are important details: your cloud name, API key, etc.<\/p>\n<p>Next, let\u2019s create environment variables to hold the details of our Cloudinary account. Create a new file called <code>.env<\/code> at the root of your project and add the following to it:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">CLOUD_NAME = YOUR CLOUD NAME HERE\nAPI_KEY = YOUR API API KEY\nAPI_SECRET = YOUR API API SECRET\n<\/code><\/span><\/pre>\n<p>This will be used as a default when the project is set up on another system. To update your local environment, create a copy of the <code>.env<\/code> file using the following command:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">cp<\/span> <span class=\"hljs-selector-class\">.env<\/span> <span class=\"hljs-selector-class\">.env<\/span><span class=\"hljs-selector-class\">.local<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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<p>By default, this local file resides in the <code>.gitignore<\/code> folder, mitigating the security risk of inadvertently exposing secret credentials to the public. You can update the <code>.env.local<\/code> file with your Cloudinary credentials.<\/p>\n<p>Before using the Google Auto Tagging add-on, we need to register for the add-on. Go through these steps to register for the add-on:<\/p>\n<ul>\n<li>Click on the <a href=\"https:\/\/cloudinary.com\/addons\">Add-ons<\/a> link in your Cloudinary console.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1650993769775_CleanShot+2022-04-26+at+21.21.542x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"556\"\/><\/p>\n<ul>\n<li>You should see a page consisting of all the available Cloudinary add-ons. Scroll down to locate the <strong>Google Auto Tagging<\/strong> add-on, click on it and select your preferred plan. We\u2019ll be using the free plan for this project, which gives us 50 free image categorizations monthly.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1650994041081_CleanShot+2022-04-26+at+21.26.482x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"759\"\/><\/p>\n<p>So far, we\u2019ve set up our project and registered for Cloudinary\u2019s Google auto-tagging add-on. Let\u2019s move on to the procedures for implementing the add-on and fetching image resources based on specified tags.<\/p>\n<h2>Uploading and Auto-Tagging Images<\/h2>\n<p>Cloudinary introduces a straightforward and uncomplicated approach to automatically generating tags or labels for images. We can generate image tags by simply setting the categorization parameter of Cloudinary\u2019s upload method to <code>google-tagging<\/code> when calling Cloudinary\u2019s upload method.<\/p>\n<p>The uploaded image is processed and analyzed to categorize its many segments and scenes into tags automatically. The API gives a response consisting of the categorization information, including the status, individual tags, and confidence score.<\/p>\n<p>The confidence score is a numerical value between 0 and 1 that specifies the discovered tag\u2019s confidence level. The higher the level of confidence, the more confident the add-on is about the discovered tag and vice versa.<\/p>\n<p>Before we begin, let\u2019s add some styles to give our application a decent look. Add the following to your <code>Home.module.css<\/code> file in the <code>\/styles<\/code> directory:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-class\">.container<\/span> {\n  <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">1200px<\/span>;\n  <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">90%<\/span>;\n  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">2rem<\/span> auto;\n}\n<span class=\"hljs-selector-class\">.container<\/span> &gt; <span class=\"hljs-selector-tag\">form<\/span> {\n  <span class=\"hljs-attribute\">display<\/span>: flex;\n  <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n  <span class=\"hljs-attribute\">align-items<\/span>: center;\n  <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">20rem<\/span>;\n  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span> auto;\n}\n<span class=\"hljs-selector-class\">.container<\/span> &gt; <span class=\"hljs-selector-tag\">form<\/span> &gt; <span class=\"hljs-selector-tag\">button<\/span> {\n  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.8rem<\/span> <span class=\"hljs-number\">1.5rem<\/span>;\n  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-number\">#0000ff<\/span>;\n  <span class=\"hljs-attribute\">border<\/span>: none;\n  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">1rem<\/span> <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n  <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n  <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#fff<\/span>;\n  <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">0.9rem<\/span>;\n  <span class=\"hljs-attribute\">font-weight<\/span>: <span class=\"hljs-number\">700<\/span>;\n}\n<span class=\"hljs-selector-class\">.tags<\/span> {\n  <span class=\"hljs-attribute\">display<\/span>: flex;\n  <span class=\"hljs-attribute\">flex-wrap<\/span>: wrap;\n}\n<span class=\"hljs-selector-class\">.tags<\/span> &gt; <span class=\"hljs-selector-tag\">button<\/span> {\n  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.2rem<\/span> <span class=\"hljs-number\">0.5rem<\/span>;\n  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0.3rem<\/span> <span class=\"hljs-number\">0.2rem<\/span>;\n  <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">0.8rem<\/span>;\n  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">13<\/span>, <span class=\"hljs-number\">150<\/span>, <span class=\"hljs-number\">155<\/span>);\n  <span class=\"hljs-attribute\">border<\/span>: none;\n  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n  <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#fff<\/span>;\n}\n<span class=\"hljs-selector-class\">.images<\/span> {\n  <span class=\"hljs-attribute\">display<\/span>: grid;\n  <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-built_in\">repeat<\/span>(auto-fill, minmax(<span class=\"hljs-number\">12rem<\/span>, <span class=\"hljs-number\">1<\/span>fr));\n  <span class=\"hljs-attribute\">grid-gap<\/span>: <span class=\"hljs-number\">0.5rem<\/span>;\n  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">1.5rem<\/span> <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-class\">.images<\/span> &gt; <span class=\"hljs-selector-tag\">div<\/span> {\n  <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n  <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">12rem<\/span>;\n}\n<span class=\"hljs-selector-class\">.images<\/span> &gt; <span class=\"hljs-selector-tag\">div<\/span> &gt; <span class=\"hljs-selector-tag\">img<\/span> {\n  <span class=\"hljs-attribute\">object-fit<\/span>: cover;\n  <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n  <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100%<\/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\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Clear the existing content in your <code>index.js<\/code> file and update it with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/styles\/Home.module.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;image, setImage] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n\n  <span class=\"hljs-keyword\">const<\/span> handleInputOnChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">event<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n    reader.readAsDataURL(event.target.files&#91;<span class=\"hljs-number\">0<\/span>]);\n    reader.onload = <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">e<\/span>) <\/span>{\n      setImage(e.target.result);\n    };\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> handleOnFormSubmit = <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n    event.preventDefault();\n      <span class=\"hljs-keyword\">try<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> axios.post(<span class=\"hljs-string\">\"\/api\/uploadImage\"<\/span>, {\n          <span class=\"hljs-attr\">image<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify(image),\n        });\n        <span class=\"hljs-built_in\">console<\/span>.log(response.data);\n      } <span class=\"hljs-keyword\">catch<\/span> (error) {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"imageUpload\"<\/span> + error);\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\">{styles.container}<\/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\">{handleOnFormSubmit}<\/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\">onChange<\/span>=<span class=\"hljs-string\">{handleInputOnChange}<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">input<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{image<\/span> ? <span class=\"hljs-attr\">false<\/span> <span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">true<\/span>}&gt;<\/span>Upload to Cloudinary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\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<p>In the code snippet above, we made some imports, and then we created a <code>Home<\/code> component that has an <code>image<\/code> state which contains the data sent to our serverless function. The <code>Home<\/code> component renders a simple form with a file input field and a submit button. The input field has an <code>onChange<\/code> prop that triggers the <code>handleInputOnChange<\/code> function whenever a file is selected.<\/p>\n<p>The <code>handleInputOnChange<\/code> function uses the File reader API to convert the selected image file into its base64 string equivalent, which is then used to update the image state on successful completion. When the submit button is clicked, the <code>handleOnFormSubmit<\/code> function gets called. The <code>handleOnFormSubmit<\/code> function makes an HTTP request to the <code>UploadImage<\/code> serverless endpoint while attaching the base64 image data payload.<\/p>\n<p>With that, we\u2019ve created the upload interface. Now, let\u2019s create our serverless function to process the image using Cloudinary. Create a file named <code>uploadImage.js<\/code> in the <code>\/pages\/api<\/code> directory and add the following to it:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\n<span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"dotenv\"<\/span>).config();\ncloudinary.config({\n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUD_NAME,\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.API_KEY,\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.API_SECRET,\n  <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n});\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handler<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> image = <span class=\"hljs-built_in\">JSON<\/span>.parse(req.body.image);\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> cldResponse = <span class=\"hljs-keyword\">await<\/span> cloudinary.uploader.upload(image, {\n      <span class=\"hljs-attr\">categorization<\/span>: <span class=\"hljs-string\">\"google_tagging\"<\/span>,\n      <span class=\"hljs-attr\">auto_tagging<\/span>: <span class=\"hljs-number\">0.6<\/span>,\n    });\n    res.status(<span class=\"hljs-number\">200<\/span>).json(cldResponse);\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(error);\n    res.json({ <span class=\"hljs-attr\">message<\/span>: <span class=\"hljs-string\">\"an error occured while uploading image\"<\/span> });\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<p>In the code above, we import Cloudinary and configure it with an object consisting of our Cloudinary credentials. Then we created our serverless function, which returns the response of calling Cloudinary\u2019s upload method on success or an error if it fails.<\/p>\n<p>The <code>upload<\/code> method takes the image data sent as a payload from the frontend and an object containing optional parameters as arguments. In our case, we specified <code>google-tagging<\/code> as the value of the categorization add-on, which indicates automatically generating tags using the Google auto-tagging add-on to classify the scenes of the uploaded asset.<\/p>\n<p>The object also takes an optional <code>auto_tagging<\/code> parameter which defines the minimum confidence score of a detected category that should be automatically used as an assigned resource tag. For example, we specified that the add-on should only generate tags with a minimum confidence score of 0.6.<\/p>\n<p>Now you can upload an image to Cloudinary and view the uploaded image and its corresponding auto-generated tags in your Cloudinary account.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1651000904165_CleanShot+2022-04-26+at+23.18.192x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"895\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1651001067401_CleanShot+2022-04-26+at+23.24.002x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"890\"\/><\/p>\n<h2>Displaying the Images<\/h2>\n<p>We need to devise a way to fetch and display all uploaded image resources and filter through the auto-generated tags. To do that, let\u2019s create a <code>getImages.js<\/code> file in our <code>\/pages\/api<\/code> folder and add the following to it:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\ncloudinary.config({\n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUD_NAME,\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.API_KEY,\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.API_SECRET,\n  <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n});\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handler<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> images = <span class=\"hljs-keyword\">await<\/span> cloudinary.api.resources();\n    res.status(<span class=\"hljs-number\">200<\/span>).json(images.resources);\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    res.json({ <span class=\"hljs-attr\">message<\/span>: <span class=\"hljs-string\">\"an error occured\"<\/span> });\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We imported Cloudinary and configured it by passing in an object consisting of our Cloudinary credentials and created a serverless function that fetches a list of all resources from the Cloudinary account and returns it as JSON data.<\/p>\n<p>Now let\u2019s update our <code>index.js<\/code> file with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" 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-comment\">\/\/import useEffect<\/span>\n<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> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/styles\/Home.module.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;image, setImage] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;cldImages, setCldImages] = useState(&#91;]);\n\n  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    getAllImages();\n  }, &#91;]);\n\n  <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getAllImages<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">try<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> images = <span class=\"hljs-keyword\">await<\/span> axios.get(<span class=\"hljs-string\">\"\/api\/getImages\"<\/span>);\n      setCldImages(images.data);\n    } <span class=\"hljs-keyword\">catch<\/span> (error) {\n      <span class=\"hljs-built_in\">console<\/span>.log(error);\n    }\n  }\n\n  <span class=\"hljs-keyword\">const<\/span> handleInputOnChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">event<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  };\n  <span class=\"hljs-keyword\">const<\/span> handleOnFormSubmit = <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n    <span class=\"hljs-comment\">\/\/...<\/span>\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\">{styles.container}<\/span>&gt;<\/span>\n      \/\/...\n      {\/* Add this *\/}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.images}<\/span>&gt;<\/span>\n          {cldImages\n            ? cldImages.map((img) =&gt; (\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{img.public_id}<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{img.secure_url}<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">img<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n              ))\n            : \"Loading...\"}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/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<p>We defined a new state variable, <code>cldImages<\/code>, to hold an array of images fetched from Cloudinary. Then we called a <code>getAllImages<\/code> function in the <code>useEffect<\/code> hook which initiates an axios call to the <code>getImages<\/code> serverless endpoint and updates the <code>cldImages<\/code> state with the returned value. Finally, we display a grid of the images.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1651004389145_CleanShot+2022-04-27+at+00.19.322x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"828\"\/><\/p>\n<h2>Fetching Generated Image Tags<\/h2>\n<p>So far, we\u2019ve been able to upload images, generate tags automatically, and retrieve images from our Cloudinary account. Let\u2019s use Cloudinary\u2019s <code>tags<\/code> API to get a list of all the tags associated with a certain resource type. In your <code>\/pages\/api<\/code> folder, create a file called <code>getImageTag.js<\/code> and add the following to it:<\/p>\n<pre class=\"js-syntax-highlighted\" 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> cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\ncloudinary.config({\n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUD_NAME,\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.API_KEY,\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.API_SECRET,\n  <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n});\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handler<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> imageTags = <span class=\"hljs-keyword\">await<\/span> cloudinary.api.tags({\n      <span class=\"hljs-attr\">max_results<\/span>: <span class=\"hljs-number\">50<\/span>,\n    });\n    res.status(<span class=\"hljs-number\">200<\/span>).json(imageTags);\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(error);\n    res.json({ <span class=\"hljs-attr\">message<\/span>: <span class=\"hljs-string\">\"an error occurred\"<\/span> });\n  }\n}\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<p>We configured Cloudinary and called the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#tags\"><strong>tags<\/strong><\/a> <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#tags\"><\/a>API to get a list of tags from the <code>imageTags<\/code> endpoint. The API takes an optional parameter \u2014 <code>max_results<\/code> which defines the maximum number of tags to return, and we specified 50.<\/p>\n<p>To render the list of tags retrieved from Cloudinary, update your <code>index.js<\/code> file with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" 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\">import<\/span> { useState, useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/styles\/Home.module.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;image, setImage] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;cldImages, setCldImages] = useState(&#91;]);\n  <span class=\"hljs-comment\">\/\/ Add this<\/span>\n  <span class=\"hljs-keyword\">const<\/span> &#91;imageTags, setImageTags] = useState(&#91;]);\n\n  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/ Add this<\/span>\n    <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getCldImageTags<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-keyword\">try<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> cldTags = <span class=\"hljs-keyword\">await<\/span> axios.get(<span class=\"hljs-string\">\"\/api\/getImageTags\"<\/span>);\n        setImageTags(cldTags.data.tags);\n      } <span class=\"hljs-keyword\">catch<\/span> (error) {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"tags\"<\/span> + error);\n      }\n    }\n    getCldImageTags()\n    getAllImages();\n  }, &#91;]);\n\n  <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getAllImages<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  }\n  <span class=\"hljs-keyword\">const<\/span> handleInputOnChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">event<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  };\n  <span class=\"hljs-keyword\">const<\/span> handleOnFormSubmit = <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n    <span class=\"hljs-comment\">\/\/...<\/span>\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\">{styles.container}<\/span>&gt;<\/span>\n      \/\/...\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        {\/* Add this *\/}\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.tags}<\/span>&gt;<\/span>\n          {imageTags\n            ? imageTags.map((tag) =&gt; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{tag}<\/span>&gt;<\/span>{tag}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>)\n            : \"upload Image\"}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.images}<\/span>&gt;<\/span>\/\/...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/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<p>We added a state variable called <code>imageTags<\/code> to hold an array of all retrieved tags. Then we defined a function, <code>getCldImageTags<\/code>, to initiate an axios call to the <code>getImageTags<\/code> endpoint and store the retrieved tags in the state.<\/p>\n<p>Next, we iterate through the image tags and render a button for each.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1651129128046_CleanShot+2022-04-28+at+10.58.342x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"818\"\/><\/p>\n<h2>Retrieve Images by Tag<\/h2>\n<p>Finally, we want to click on a tag and retrieve all images associated with that particular tag. Cloudinary provides an <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#get_resources_by_tag\"><strong>api.resources_by_tag<\/strong><\/a> method that handles fetching image resources based on a given tag.<\/p>\n<p>The method takes a required parameter, <code>tag<\/code>, which defines the category of resources to be returned and some <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#get_resources_by_tag_optional_parameters\">optional parameters<\/a>. To implement this, create a file called <code>getImagesByTag.js<\/code> in your <code>\/pages\/api<\/code> folder and add the following to it:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" 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> cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\ncloudinary.config({\n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUD_NAME,\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.API_KEY,\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.API_SECRET,\n  <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>,\n});\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handler<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> tag = <span class=\"hljs-built_in\">JSON<\/span>.parse(req.body.tag).tag;\n    <span class=\"hljs-keyword\">const<\/span> resources = <span class=\"hljs-keyword\">await<\/span> cloudinary.api.resources_by_tag(tag);\n    res.status(<span class=\"hljs-number\">200<\/span>).json(resources);\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(error);\n    res.json({ <span class=\"hljs-attr\">message<\/span>: <span class=\"hljs-string\">\"an error occured\"<\/span> });\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This file\u2019s setup is identical to the ones we\u2019ve defined earlier, but we now expect a tag value obtained from the request body, which is passed to the <code>api.resources_by_tag<\/code> method to retrieve the image resources based on that tag.<\/p>\n<p>Finally, let\u2019s update our <code>index.js<\/code> file with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" 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> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/styles\/Home.module.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;image, setImage] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;cldImages, setCldImages] = useState(&#91;]);\n  <span class=\"hljs-keyword\">const<\/span> &#91;imageTags, setImageTags] = useState(&#91;]);\n\n  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n    getCldImageTags()\n    getAllImages();\n  }, &#91;]);\n\n  <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getAllImages<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  }\n\n  <span class=\"hljs-keyword\">const<\/span> handleInputOnChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">event<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  };\n  <span class=\"hljs-keyword\">const<\/span> handleOnFormSubmit = <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n  };\n\n  <span class=\"hljs-comment\">\/\/ Add this<\/span>\n  <span class=\"hljs-keyword\">const<\/span> handleTagClick = <span class=\"hljs-keyword\">async<\/span> (tag) =&gt; {\n      <span class=\"hljs-keyword\">try<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> resImages = <span class=\"hljs-keyword\">await<\/span> axios.post(<span class=\"hljs-string\">\"\/api\/getImagesByTag\"<\/span>, {\n          <span class=\"hljs-attr\">tag<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n            <span class=\"hljs-attr\">tag<\/span>: tag,\n          }),\n        });\n        setCldImages(resImages.data.resources);\n      } <span class=\"hljs-keyword\">catch<\/span> (error) {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"tagClick\"<\/span> + error);\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\">{styles.container}<\/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\">{handleOnFormSubmit}<\/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\">onChange<\/span>=<span class=\"hljs-string\">{handleInputOnChange}<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">input<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{image<\/span> ? <span class=\"hljs-attr\">false<\/span> <span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">true<\/span>}&gt;<\/span>Upload to Cloudinary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.tags}<\/span>&gt;<\/span>\n          {\/* Add onClick event listener to the button *\/}\n          {imageTags\n            ? imageTags.map((tag) =&gt; (\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{tag}<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> handleTagClick(tag)}&gt;\n                  {tag}\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n              ))\n            : \"upload Image\"}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.images}<\/span>&gt;<\/span>\n          {cldImages\n            ? cldImages.map((img) =&gt; (\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{img.public_id}<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{img.secure_url}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{img.public_id}<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">img<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n              ))\n            : \"Loading...\"}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the code above, we added an <code>onClick<\/code> event listener to the <code>button<\/code> element that triggers the <code>handleTagClick<\/code> function when any of the buttons get clicked. The <code>handleTagClick<\/code> function makes a call to the <code>\/api\/getImagesByTag<\/code> endpoint while attaching the tag as payload. The response images get saved in the <code>cldImages<\/code> to re-render a new set of images based on the clicked tag.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_00EA7970FB03FD4B40B1D49B0CB7E7AFFAFE4AB40E549C04E004AB88ACAEE78E_1651136006882_CleanShot+2022-04-28+at+12.51.35.gif\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"334\"\/><\/p>\n<p>Find the complete project <a href=\"https:\/\/github.com\/ifeoma-imoh\/auto-tag-images-cloudinary\">here<\/a> on GitHub.<\/p>\n<h2>Conclusion<\/h2>\n<p>Cloudinary provides a comprehensive range of image processing and analysis tools with the ability to extract semantic data from uploaded images. In this article, we looked at how to implement Cloudinary\u2019s Google auto-tagging add-on in a simple application. We also looked at how to retrieve images by tags.<\/p>\n<p><strong>Resources You May Find Helpful<\/strong><\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/admin_api\">Cloudinary Admin API reference<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference\">Cloudinary Upload API reference<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/google_auto_tagging_addon\">Cloudinary Google Auto Tagging add-on<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/nextjs.org\/docs\/api-routes\/introduction\">Next.js API routes documentation<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28414,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,212,371],"class_list":["post-28413","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-next-js","tag-under-review"],"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>Auto-Tag and Categorize Images Using Cloudinary<\/title>\n<meta name=\"description\" content=\"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.\" \/>\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\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Auto-Tag and Categorize Images Using Cloudinary\" \/>\n<meta property=\"og:description\" content=\"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-04T07:02:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-26T00:17:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\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\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Auto-Tag and Categorize Images Using Cloudinary\",\"datePublished\":\"2022-05-04T07:02:28+00:00\",\"dateModified\":\"2025-02-26T00:17:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Next.js\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\",\"name\":\"Auto-Tag and Categorize Images Using Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA\",\"datePublished\":\"2022-05-04T07:02:28+00:00\",\"dateModified\":\"2025-02-26T00:17:44+00:00\",\"description\":\"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA\",\"width\":1280,\"height\":720},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Auto-Tag and Categorize Images Using Cloudinary\"}]},{\"@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\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Auto-Tag and Categorize Images Using Cloudinary","description":"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.","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\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/","og_locale":"en_US","og_type":"article","og_title":"Auto-Tag and Categorize Images Using Cloudinary","og_description":"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-05-04T07:02:28+00:00","article_modified_time":"2025-02-26T00:17:44+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420-png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/"},"author":{"name":"","@id":""},"headline":"Auto-Tag and Categorize Images Using Cloudinary","datePublished":"2022-05-04T07:02:28+00:00","dateModified":"2025-02-26T00:17:44+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA","keywords":["Guest Post","Image","Next.js","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/","name":"Auto-Tag and Categorize Images Using Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA","datePublished":"2022-05-04T07:02:28+00:00","dateModified":"2025-02-26T00:17:44+00:00","description":"This article will go through how to implement the Cloudinary Google auto-tagging add-on to automatically generate tags for images, fetch the generated image tags, and access image resources based on a specified tag.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA","width":1280,"height":720},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/auto-tag-and-categorize-images-using-cloudinary\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Auto-Tag and Categorize Images Using Cloudinary"}]},{"@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":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924577\/Web_Assets\/blog\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420\/0f5085fc3820491d465d0d5bd7d85656eb5e5bef-1280x720-1_2841420420.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28413","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\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28413"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28413\/revisions"}],"predecessor-version":[{"id":37029,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28413\/revisions\/37029"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28414"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}