{"id":28030,"date":"2022-06-02T12:01:49","date_gmt":"2022-06-02T12:01:49","guid":{"rendered":"http:\/\/upload-images-to-cloudinary-with-node.js-and-react"},"modified":"2025-05-14T11:25:03","modified_gmt":"2025-05-14T18:25:03","slug":"upload-images-to-cloudinary-with-node-js-and-react","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/","title":{"rendered":"Upload Images to Cloudinary with Node.js and React"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>The use of multimedia on the web has gone mainstream primarily because of obvious benefits such as increased user engagement, dwell time, improved SEO, etc. Getting it right with media assets on the web entails dealing with optimization, delivery, transformation, and other management tasks. Fortunately, technologies like Cloudinary offer scalable, performant, and easy-to-use tools for practically all media management concerns.<\/p>\n<p>In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.<\/p>\n<h2>Project Setup<\/h2>\n<p>Run this command in your terminal to create the working directory:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">mkdir cloudinary-react-node\n<\/code><\/span><\/pre>\n<p>We\u2019ll also need two subdirectories within the <code>cloudinary-react-node<\/code> directory. Run this command to create them:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">cd cloudinary-react-node\nmkdir frontend server\n<\/code><\/span><\/pre>\n<p>Our React app, and its dependencies, will be kept in the <code>frontend<\/code> folder, while our backend code will be in the <code>server<\/code> folder.<\/p>\n<p>Let\u2019s initialize the working directory to be able to install the necessary dependencies that will be used for our backend. Run this command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm init --y\n<\/code><\/span><\/pre>\n<p>Next, run the following command in your terminal to install the dependencies for our backend:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install express multer cloudinary cors dotenv\n<\/code><\/span><\/pre>\n<p>The above command installs several modules: <code>express<\/code> will be used to build our web server, all the necessary routes, and handling middleware. <code>multer<\/code> is a middleware used to parse multipart form data, which includes files from the HTTP request body. The <code>cloudinary<\/code> SDK will provide us with easy-to-use APIs to upload parsed files to our Cloudinary account and do any media file manipulations as the need be. The <code>cors<\/code> module is also another middleware that would help us with CORS errors, and finally, the <code>dotenv<\/code> module will allow us to parse environment variables defined in a <code>.env<\/code> file.<\/p>\n<p>Run this command to create a file within the <code>server<\/code> folder, where we will write our serverside logic:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">touch server\/index.js\n<\/code><\/span><\/pre>\n<p>Now let\u2019s run the following command to set up our React app in the <code>frontend<\/code> folder created earlier:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-react-app frontend\n<\/code><\/span><\/pre>\n<p>Run this command to install the dependency for our React app \u2014 the axios module, which will be our HTTP client:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">cd frontend\nnpm install axios\n<\/code><\/span><\/pre>\n<p>We are not done with our setup yet. We need a way to automate the task of starting our React app and our web server concurrently. Within the working directory, run this command in your terminal to install the concurrently module:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm i concurrently --save-dev\n<\/code><\/span><\/pre>\n<p>Next, update the <code>scripts<\/code> object within the <code>package.json<\/code> file in the root of the working directory to match the following:<\/p>\n<pre class=\"js-syntax-highlighted\" 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-string\">\"scripts\"<\/span>: {\n        <span class=\"hljs-string\">\"backend\"<\/span>: <span class=\"hljs-string\">\"node server\/index.js\"<\/span>,\n        <span class=\"hljs-string\">\"frontend\"<\/span>: <span class=\"hljs-string\">\"npm run start --prefix frontend\"<\/span>,\n        <span class=\"hljs-string\">\"dev\"<\/span>: <span class=\"hljs-string\">\"concurrently \\\"npm run backend\\\" \\\"npm run frontend\\\"\"<\/span>\n      },\n<\/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<p>Here, we included three scripts, the first two are for starting our Node server and our React app, respectively, and the third uses the concurrently module to start both of them concurrently.<\/p>\n<h2>Setting up Cloudinary<\/h2>\n<p>To use Cloudinary\u2019s provisioned services, you need to 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><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_3E07C5717FA01932E33D4A07A7101B93251FA9AD5347E57006131A9DC0512E6B_1653463913697_CleanShot+2022-05-25+at+08.31.212x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"742\"\/><\/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\n    API_KEY = YOUR API API KEY\n    API_SECRET = YOUR API API SECRET\n<\/code><\/span><\/pre>\n<p>You can update the <code>.env<\/code> file with your Cloudinary credentials.<\/p>\n<h2>Setting up the Server and Defining the Upload Endpoint<\/h2>\n<p>In the following steps, we will update our <code>server.js<\/code> file with the logic needed to set up our web server and include the endpoint that will enable us to upload files to Cloudinary.<\/p>\n<ol>\n<li>Let\u2019s start by including the necessary imports we will be needing. Add the following to your <code>server.js<\/code> file:<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"dotenv\"<\/span>).config();\n<span class=\"hljs-keyword\">const<\/span> express = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"express\"<\/span>);\n<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-keyword\">const<\/span> cors = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cors\"<\/span>);\n<span class=\"hljs-keyword\">const<\/span> Multer = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"multer\"<\/span>);\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<ol start=\"2\">\n<li>Next, let\u2019s set up our Cloudinary SDK and define a function that will help us with file uploads.<\/li>\n<\/ol>\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\">cloudinary.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});\n<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleUpload<\/span>(<span class=\"hljs-params\">file<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> cloudinary.uploader.upload(file, {\n    <span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">\"auto\"<\/span>,\n  });\n  <span class=\"hljs-keyword\">return<\/span> res;\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 above, we import Cloudinary and configure it with an object consisting of our Cloudinary credentials. Next, we define the <code>handleUpload<\/code> function, which accepts a file and attempts to upload the file. The upload is made possible by calling the <code>upload<\/code> method on the <code>cloudinary<\/code> object, and it accepts two parameters. The first is the file to be uploaded, and the second is an object that holds the options we want for the uploaded file.<\/p>\n<p>When we do uploads from the server, the upload call assumes that the file is an image, i.e., <code>resource_type: &quot;image&quot;<\/code>, but setting the <code>resource_type<\/code> to <code>auto<\/code> automatically detects the file type during the upload process. Once the file is successfully uploaded, the response we get from the API is returned.<\/p>\n<ol start=\"3\">\n<li>Next, let\u2019s set up the multer middleware.<\/li>\n<\/ol>\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> storage = <span class=\"hljs-keyword\">new<\/span> Multer.memoryStorage();\n<span class=\"hljs-keyword\">const<\/span> upload = Multer({\n  storage,\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>Multer provides us with two storage options: disk and memory storage. In the snippet above, we create and initialize a Multer instance and select the memory storage option.<\/p>\n<p>Now, let\u2019s use the <code>Express<\/code> module to create a web server to listen for requests. We will also create an endpoint to handle file uploads.<\/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> app = express();\napp.use(cors());\n\napp.post(<span class=\"hljs-string\">\"\/upload\"<\/span>, upload.single(<span class=\"hljs-string\">\"my_file\"<\/span>), <span class=\"hljs-keyword\">async<\/span> (req, res) =&gt; {\n  <span class=\"hljs-keyword\">try<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> b64 = Buffer.from(req.file.buffer).toString(<span class=\"hljs-string\">\"base64\"<\/span>);\n    <span class=\"hljs-keyword\">let<\/span> dataURI = <span class=\"hljs-string\">\"data:\"<\/span> + req.file.mimetype + <span class=\"hljs-string\">\";base64,\"<\/span> + b64;\n    <span class=\"hljs-keyword\">const<\/span> cldRes = <span class=\"hljs-keyword\">await<\/span> handleUpload(dataURI);\n    res.json(cldRes);\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(error);\n    res.send({\n      <span class=\"hljs-attr\">message<\/span>: error.message,\n    });\n  }\n});\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 Listening on <span class=\"hljs-subst\">${port}<\/span>`<\/span>);\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 create an instance of express and store it in a variable called <code>app<\/code>; this is followed by including the cors middleware. Then we create an endpoint that will route any POST requests made to the <code>\/upload<\/code> path, with two middlewares to handle the request.<\/p>\n<p>The first is the multer middleware we created earlier. The <code>upload.single(&quot;my_file&quot;)<\/code> call returns a function that is set up to parse a single file contained in the request body with a named attribute \u2014 <code>my file<\/code> (this is the name we would bind to the file before it is uploaded on the client-side).\nOnce the file is parsed successfully, the multer middleware attaches a file property to the request body, i.e., req.file, which contains information about the file. Since we are using the <code>memoryStorage<\/code> option to store our file, the object looks like this for some 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_44D9D813840921CA06BA95BCB647318ABD08C0632770D0DC24EA7F4285AB332F_1652715582725_Screenshot+2022-05-16+at+16.39.36.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1334\" height=\"470\"\/><\/p>\n<p>The Second middleware then takes the request body, converts the buffer in the parsed file to base64, and further transforms this representation to a data URI, which is then fed to the <code>handleUpload<\/code> function to upload. Once it succeeds, we send the upload response we get from cloudinary back to the client-side, and if it fails, the error response is sent back.<\/p>\n<h2>Building the Frontend<\/h2>\n<p>We now have our web server ready. Next, let\u2019s build our frontend application that will communicate with it. Open the <code>frontend<\/code> folder and update the content of the <code>src\/App.js<\/code> file with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import <span class=\"hljs-string\">\".\/index.css\"<\/span>;\nimport { useState } from <span class=\"hljs-string\">\"react\"<\/span>;\nimport axios from <span class=\"hljs-string\">\"axios\"<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;file, setFile] = useState(<span class=\"hljs-keyword\">null<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;loading, setLoading] = useState(<span class=\"hljs-keyword\">false<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> &#91;res, setRes] = useState({});\n  <span class=\"hljs-keyword\">const<\/span> handleSelectFile = (e) =&gt; setFile(e.target.files&#91;<span class=\"hljs-number\">0<\/span>]);\n  <span class=\"hljs-keyword\">const<\/span> handleUpload = async () =&gt; {\n    <span class=\"hljs-keyword\">try<\/span> {\n      setLoading(<span class=\"hljs-keyword\">true<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">new<\/span> FormData();\n      data.append(<span class=\"hljs-string\">\"my_file\"<\/span>, file);\n      <span class=\"hljs-keyword\">const<\/span> res = await axios.post(<span class=\"hljs-string\">\"http:\/\/localhost:6000\/upload\"<\/span>, data);\n      setRes(res.data);\n    } <span class=\"hljs-keyword\">catch<\/span> (error) {\n      alert(error.message);\n    } <span class=\"hljs-keyword\">finally<\/span> {\n      setLoading(<span class=\"hljs-keyword\">false<\/span>);\n    }\n  };\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    &lt;div className=<span class=\"hljs-string\">\"App\"<\/span>&gt;\n      &lt;label htmlFor=<span class=\"hljs-string\">\"file\"<\/span> className=<span class=\"hljs-string\">\"btn-grey\"<\/span>&gt;\n        {<span class=\"hljs-string\">\" \"<\/span>}\n        select file\n      &lt;\/label&gt;\n      {file &amp;&amp; &lt;center&gt; {file.name}&lt;\/center&gt;}\n      &lt;input\n        id=<span class=\"hljs-string\">\"file\"<\/span>\n        type=<span class=\"hljs-string\">\"file\"<\/span>\n        onChange={handleSelectFile}\n        multiple={<span class=\"hljs-keyword\">false<\/span>}\n      \/&gt;\n      &lt;code&gt;\n        {Object.keys(res).length &gt; <span class=\"hljs-number\">0<\/span>\n          ? Object.keys(res).map((key) =&gt; (\n              &lt;p className=<span class=\"hljs-string\">\"output-item\"<\/span> key={key}&gt;\n                &lt;span&gt;{key}:&lt;\/span&gt;\n                &lt;span&gt;\n                  {typeof res&#91;key] === <span class=\"hljs-string\">\"object\"<\/span> ? <span class=\"hljs-string\">\"object\"<\/span> : res&#91;key]}\n                &lt;\/span&gt;\n              &lt;\/p&gt;\n            ))\n          : <span class=\"hljs-keyword\">null<\/span>}\n      &lt;\/code&gt;\n      {file &amp;&amp; (\n        &lt;&gt;\n          &lt;button onClick={handleUpload} className=<span class=\"hljs-string\">\"btn-green\"<\/span>&gt;\n            {loading ? <span class=\"hljs-string\">\"uploading...\"<\/span> : <span class=\"hljs-string\">\"upload to cloudinary\"<\/span>}\n          &lt;\/button&gt;\n        &lt;\/&gt;\n      )}\n    &lt;\/div&gt;\n  );\n}\nexport <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This component is quite straightforward; it simply allows the user to select a file from their computer, provides them with a button to upload the file, and displays the result received from the server on the screen if the upload is successful. The centerpiece of this component is the function called <code>handleUpload<\/code>, which performs file uploading through the following steps:<\/p>\n<ol>\n<li>\n<p>It embeds the file selected by the user into the request payload using the FormData API with a name attribute called <code>my_file<\/code> \u2014 a string that matches the one we configured on our server using the Multer middleware.<\/p>\n<\/li>\n<li>\n<p>The payload is then used to initiate an HTTP request to our backend. If the request is successful, the response is stored in a state variable called <code>res<\/code>, which is iterated on and rendered to the screen; otherwise, an error message is displayed.<\/p>\n<\/li>\n<\/ol>\n<p>We\u2019ll also need some styles to give the application a nice appearance. Copy the styles in this <a href=\"https:\/\/codesandbox.io\/s\/upload-media-files-to-cloudinary-with-node-js-and-react-m55cbn?file=\/frontend\/src\/index.css:0-954\">codeSandbox link<\/a> to your <code>index.css<\/code> file.<\/p>\n<p>To preview the running application, let\u2019s start our web server and React app. Run this command in your terminal:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm run dev\n<\/code><\/span><\/pre>\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_3E07C5717FA01932E33D4A07A7101B93251FA9AD5347E57006131A9DC0512E6B_1654004588185_CleanShot+2022-05-31+at+14.42.39.gif\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"368\"\/><\/p>\n<p>As seen above, we get the upload response displayed on the screen. You can also visit the media gallery section on your cloudinary account to see the uploaded file.<\/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_3E07C5717FA01932E33D4A07A7101B93251FA9AD5347E57006131A9DC0512E6B_1654004689892_CleanShot+2022-05-31+at+14.44.152x.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"743\"\/><\/p>\n<p>Find the complete project <a href=\"https:\/\/github.com\/ifeoma-imoh\/cloudinary-react-node\">here<\/a> on GitHub.<\/p>\n<h2>Conclusion<\/h2>\n<p>When working with media assets, platforms like Cloudinary provide you with an advantage. Hopefully, using this as a jumping-off point, you can go further and explore the platform\u2019s advanced features.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28031,"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,383,246,371,373],"class_list":["post-28030","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-nodejs","tag-react","tag-under-review","tag-upload"],"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>Upload Images to Cloudinary with Node.js and React<\/title>\n<meta name=\"description\" content=\"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.\" \/>\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\/upload-images-to-cloudinary-with-node-js-and-react\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Upload Images to Cloudinary with Node.js and React\" \/>\n<meta property=\"og:description\" content=\"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-02T12:01:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-14T18:25:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1-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\/upload-images-to-cloudinary-with-node-js-and-react\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Upload Images to Cloudinary with Node.js and React\",\"datePublished\":\"2022-06-02T12:01:49+00:00\",\"dateModified\":\"2025-05-14T18:25:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Node(JS)\",\"React\",\"Under Review\",\"Upload\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\",\"name\":\"Upload Images to Cloudinary with Node.js and React\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA\",\"datePublished\":\"2022-06-02T12:01:49+00:00\",\"dateModified\":\"2025-05-14T18:25:03+00:00\",\"description\":\"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA\",\"width\":1280,\"height\":720},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Upload Images to Cloudinary with Node.js and 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\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Upload Images to Cloudinary with Node.js and React","description":"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.","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\/upload-images-to-cloudinary-with-node-js-and-react\/","og_locale":"en_US","og_type":"article","og_title":"Upload Images to Cloudinary with Node.js and React","og_description":"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-06-02T12:01:49+00:00","article_modified_time":"2025-05-14T18:25:03+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1-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\/upload-images-to-cloudinary-with-node-js-and-react\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/"},"author":{"name":"","@id":""},"headline":"Upload Images to Cloudinary with Node.js and React","datePublished":"2022-06-02T12:01:49+00:00","dateModified":"2025-05-14T18:25:03+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA","keywords":["Guest Post","Image","Node(JS)","React","Under Review","Upload"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/","name":"Upload Images to Cloudinary with Node.js and React","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA","datePublished":"2022-06-02T12:01:49+00:00","dateModified":"2025-05-14T18:25:03+00:00","description":"In this post, we will upload files from a simple React app using a Cloudinary backend SDK on a Node.js web server.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA","width":1280,"height":720},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/upload-images-to-cloudinary-with-node-js-and-react\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Upload Images to Cloudinary with Node.js and 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":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925633\/Web_Assets\/blog\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1\/ae8d9ee2558975fe6f7f763cd5a12c6557ae1be1-1280x720-1_280317d6a1.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28030","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=28030"}],"version-history":[{"count":2,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28030\/revisions"}],"predecessor-version":[{"id":37635,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28030\/revisions\/37635"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28031"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28030"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28030"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28030"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}