{"id":40056,"date":"2026-05-21T07:00:00","date_gmt":"2026-05-21T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=40056"},"modified":"2026-05-20T11:56:48","modified_gmt":"2026-05-20T18:56:48","slug":"travel-gallery-react-upload-widget","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","title":{"rendered":"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><ul>\n<li>\n<strong>GitHub repo:<\/strong> <a href=\"https:\/\/github.com\/musebe\/react-travel-gallery\">https:\/\/github.com\/musebe\/react-travel-gallery<\/a>\n<\/li>\n<li>\n<strong>Live demo:<\/strong> <a href=\"https:\/\/react-travel-gallery.vercel.app\/\">https:\/\/react-travel-gallery.vercel.app<\/a>\n<\/li>\n<\/ul>\n<p>Building upload features in React sounds simple at first: add file input, add previews. Then users want drag-and-drop, progress bars, retries, and support for multiple files at once. Your beginner project has now snowballed into an even bigger one.<\/p>\n<p>In this guide, you\u2019ll build a simple travel gallery using React and the Cloudinary Upload Widget. Instead of building the upload UI from scratch, you\u2019ll open a ready-made upload modal from a button.<\/p>\n<p>By the end, users will be able to upload travel photos, get instant feedback, and see the images appear in the gallery. Cloudinary will handle the upload flow, progress, file sources, and image delivery for you, while React will handle the button, gallery state, and user feedback.<\/p>\n<h2>The Problem: Upload UI Gets Messy, Fast<\/h2>\n<p>Image upload starts with a basic file input:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> \/&gt;<\/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\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>But users need more than a simple button: They want to upload many photos simultaneously, drag files into the browser, and get real-time progress updates while each file uploads (just to make sure the app isn\u2019t frozen).<\/p>\n<p>Building this yourself means you also have to handle:<\/p>\n<ul>\n<li>\n<strong>Error states.<\/strong> What happens if the Wi-Fi drops mid-upload?<\/li>\n<li>\n<strong>Retries.<\/strong> How do you resume a failed 10MB photo upload?<\/li>\n<li>\n<strong>Previews.<\/strong> Showing a thumbnail before the user hits \u201csubmit.\u201d<\/li>\n<li>\n<strong>File sources.<\/strong> Supporting uploads from Google Drive, Dropbox, or a device camera.<\/li>\n<\/ul>\n<p>For a beginner React project, this complexity can slow you down before you\u2019ve even made any meaningful progress. Instead of spending days on tedious upload logic, you should focus on the core of your app. In this case, that app is a travel gallery where users can add and view their favorite memories.<\/p>\n<h2>The Solution: Use the Cloudinary Upload Widget<\/h2>\n<p>The <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">Cloudinary Upload Widget<\/a> gives you a ready-made upload modal, so you don\u2019t have to build the full upload flow yourself. It includes:<\/p>\n<ul>\n<li>Local file and camera uploads.<\/li>\n<li>URL, Google Drive, and Dropbox imports.<\/li>\n<li>Multi-file support with upload progress.<\/li>\n<li>Optional cropping and editing.<\/li>\n<li>Success and error callbacks for your app logic.<\/li>\n<\/ul>\n<p>In this project, React triggers the widget from a single button. Once a user uploads their photos, Cloudinary returns the details for each image. You\u2019ll then use that data to update the travel gallery instantly.<\/p>\n<p>This architecture keeps your app lean: React handles the gallery UI, while Cloudinary manages the complex upload work.<\/p>\n<h2>What You\u2019ll Build<\/h2>\n<p>Your small travel gallery app in React will enable users to:<\/p>\n<ul>\n<li>Click a button to open the Cloudinary Upload Widget.<\/li>\n<li>Upload one or more travel photos.<\/li>\n<li>See a toast when an upload works or fails.<\/li>\n<li>Add uploaded images to the gallery without refreshing the page.<\/li>\n<li>Display clean, optimized images from Cloudinary.<\/li>\n<\/ul>\n<p>To achieve this, use the <a href=\"https:\/\/github.com\/cloudinary-devs\/create-cloudinary-react\">create-cloudinary-react starter kit<\/a>, which provides a React environment where Cloudinary is already wired in, allowing you to skip the tedious configuration and jump straight into building your feature.<\/p>\n<h2>Project Setup<\/h2>\n<p>Start by creating a new React project with <code>create-cloudinary-react<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-cloudinary-react react-travel-gallery \n<\/code><\/span><\/pre>\n<p>This command creates a Vite, React, and TypeScript project with Cloudinary setup included.<\/p>\n<p>During setup, you\u2019ll be asked for:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Prompt<\/th>\n<th>What to Add<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Project name<\/td>\n<td><code>react-travel-gallery<\/code><\/td>\n<\/tr>\n<tr>\n<td>Cloud name<\/td>\n<td>Your Cloudinary cloud name<\/td>\n<\/tr>\n<tr>\n<td>Upload preset<\/td>\n<td>Your unsigned upload preset<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>You can find your cloud name in your <a href=\"https:\/\/cloudinary.com\/users\/login\">Cloudinary dashboard<\/a>.<\/p>\n<p>For the upload preset, go to your Cloudinary settings and create an unsigned upload preset. This lets the browser upload images directly to Cloudinary without using a backend.<\/p>\n<p>After setup, move into the project and start it:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">cd react-travel-gallery\nnpm run dev\n<\/code><\/span><\/pre>\n<p>You should now have a working React app ready for the travel gallery.<\/p>\n<h2>Add the Upload Widget Script<\/h2>\n<p>The Cloudinary Upload Widget needs a script before React can open it.<\/p>\n<p>In this starter, the script is added to <code>index.html<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>\n  <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/upload-widget.cloudinary.com\/latest\/global\/all.js\"<\/span>\n  <span class=\"hljs-attr\">async<\/span>\n&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/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\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This loads the widget in the browser.<\/p>\n<p>Since the script uses <code>async<\/code>, it may load after React starts. That\u2019s why the starter checks if the widget is ready before opening it.<\/p>\n<p>Once it\u2019s ready, React can call the widget from a button click.<\/p>\n<p>You don\u2019t need to build the upload modal, progress bar, or file picker yourself. Cloudinary provides that UI for you.<\/p>\n<h2>Create the Upload Widget Component<\/h2>\n<p>Next, create a reusable upload button.<\/p>\n<p>This component will open the Cloudinary Upload Widget when the user clicks it.<\/p>\n<p>The key idea is simple:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">UploadWidget<\/span>\n  <span class=\"hljs-attr\">onUploadSuccess<\/span>=<span class=\"hljs-string\">{handleUploadSuccess}<\/span>\n  <span class=\"hljs-attr\">onUploadError<\/span>=<span class=\"hljs-string\">{handleUploadError}<\/span>\n  <span class=\"hljs-attr\">buttonText<\/span>=<span class=\"hljs-string\">\"Upload Travel Photos\"<\/span>\n\/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Inside the component, Cloudinary creates the widget with your cloud name and upload preset.<\/p>\n<p>You can also control where users upload from:<\/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\">sources: &#91;<span class=\"hljs-string\">'local'<\/span>, <span class=\"hljs-string\">'camera'<\/span>, <span class=\"hljs-string\">'url'<\/span>, <span class=\"hljs-string\">'google_drive'<\/span>, <span class=\"hljs-string\">'dropbox'<\/span>],\n<span class=\"hljs-attr\">multiple<\/span>: <span class=\"hljs-literal\">true<\/span>,\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>So users can upload from their device, camera, a URL, Google Drive, or Dropbox. The <code>multiple: true<\/code> option allows users to upload more than one travel photo at a time. This gives you a better upload flow without building drag-and-drop, progress bars, or file source options yourself.<\/p>\n<h2>Handle Upload Success and Failure<\/h2>\n<p>Now you\u2019ll need to respond after each upload.<\/p>\n<p>The Upload Widget gives us callbacks for upload results. You can use them to update the gallery and show feedback.<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleUploadSuccess<\/span>(<span class=\"hljs-params\">result: CloudinaryUploadResult<\/span>) <\/span>{\n  dispatch({ <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">\"add\"<\/span>, <span class=\"hljs-attr\">image<\/span>: result });\n  toast.success(<span class=\"hljs-string\">\"Travel photo added!\"<\/span>);\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleUploadError<\/span>(<span class=\"hljs-params\">error: Error<\/span>) <\/span>{\n  toast.error(<span class=\"hljs-string\">`Upload failed: <span class=\"hljs-subst\">${error.message}<\/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>When <strong>the upload works<\/strong>, you\u2019ll add the new image to the gallery state. When <strong>it fails<\/strong>, show a clear error message.<\/p>\n<p>This is a small detail, but it improves the user experience. Users should know right away if their upload worked or failed.<\/p>\n<h2>Display Uploaded Images in the Gallery<\/h2>\n<p>After an upload works, Cloudinary returns details about the image.<\/p>\n<p>The most important value is the <code>public_id<\/code>. Think of the <code>public_id<\/code> as the image name Cloudinary uses to find and deliver the asset. Instead of saving a full image URL, you can store the <code>public_id<\/code> and build the image URL when you render the gallery.<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">buildThumbnail<\/span>(<span class=\"hljs-params\">publicId: string<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> cld\n    .image(publicId)\n    .resize(thumbnail().width(<span class=\"hljs-number\">400<\/span>).height(<span class=\"hljs-number\">400<\/span>))\n    .delivery(format(auto()))\n    .delivery(quality(autoQuality()));\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>Then render the image with Cloudinary\u2019s React SDK:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">AdvancedImage<\/span> <span class=\"hljs-attr\">cldImg<\/span>=<span class=\"hljs-string\">{buildThumbnail(image.public_id)}<\/span> \/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Now each uploaded travel photo will appear in the gallery without a page refresh. React will update the page, Cloudinary will deliver the image.<\/p>\n<h2>Optimize Images With Cloudinary<\/h2>\n<p>A travel gallery should load fast. Large images can slow down the page, especially when users upload photos from phones or cameras. Cloudinary helps by transforming images through the delivery URL.<\/p>\n<p>For example:<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">buildThumbnail<\/span>(<span class=\"hljs-params\">publicId: string<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> cld\n    .image(publicId)\n    .resize(thumbnail().width(<span class=\"hljs-number\">400<\/span>).height(<span class=\"hljs-number\">400<\/span>))\n    .delivery(format(auto()))\n    .delivery(quality(autoQuality()));\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>This does three useful things:<\/p>\n<ul>\n<li>Creates a clean square thumbnail.<\/li>\n<li>Sends the best image format for the browser.<\/li>\n<li>Balances image quality and file size.<\/li>\n<\/ul>\n<p>You can also add lazy loading and a blur placeholder:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">AdvancedImage<\/span>\n  <span class=\"hljs-attr\">cldImg<\/span>=<span class=\"hljs-string\">{buildThumbnail(image.public_id)}<\/span>\n  <span class=\"hljs-attr\">plugins<\/span>=<span class=\"hljs-string\">{&#91;<\/span>\n    <span class=\"hljs-attr\">placeholder<\/span>({ <span class=\"hljs-attr\">mode:<\/span> \"<span class=\"hljs-attr\">blur<\/span>\" }),\n    <span class=\"hljs-attr\">lazyload<\/span>(),\n  ]}\n\/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This makes the gallery feel smoother while images load.<\/p>\n<h2>Improve the User Experience<\/h2>\n<p>Good upload flows give users clear feedback. When someone uploads a travel photo, they should know what happened right away.<\/p>\n<p>Use toast messages for this:<\/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\">toast.success(<span class=\"hljs-string\">\"Travel photo added!\"<\/span>);\ntoast.error(<span class=\"hljs-string\">\"Upload failed. Please try again.\"<\/span>);\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>You can also improve the gallery by adding:<\/p>\n<ul>\n<li>A loading state while images load.<\/li>\n<li>A clear upload button label.<\/li>\n<li>A short empty state when no photos exist.<\/li>\n<li>A preview before opening the full image.<\/li>\n<li>A success message after each upload.<\/li>\n<\/ul>\n<p>These small details make the app feel more complete.<\/p>\n<h2>What Cloudinary Handles So You Don\u2019t Have To<\/h2>\n<p>When you build a custom uploader, you\u2019re responsible for every moving part. By using the widget, you offload the complexity so you can focus on your React application.<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>The Feature<\/strong><\/th>\n<th><strong>Building It Custom<\/strong><\/th>\n<th><strong>With Cloudinary Widget<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Upload UI<\/strong><\/td>\n<td>Design and build file picker<\/td>\n<td>Ready-made, polished modal<\/td>\n<\/tr>\n<tr>\n<td><strong>Interactions<\/strong><\/td>\n<td>Write drag-and-drop logic<\/td>\n<td>Included natively<\/td>\n<\/tr>\n<tr>\n<td><strong>User Progress<\/strong><\/td>\n<td>Track and sync progress bars<\/td>\n<td>Included natively<\/td>\n<\/tr>\n<tr>\n<td><strong>File Sources<\/strong><\/td>\n<td>Restricted to local files<\/td>\n<td>Camera, URL, and social imports<\/td>\n<\/tr>\n<tr>\n<td><strong>Infrastructure<\/strong><\/td>\n<td>Build storage and delivery<\/td>\n<td>Handled by Cloudinary\u2019s CDN<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>The result is a travel gallery UI. Cloudinary handles the entire upload flow, image storage, and high-performance delivery.<\/p>\n<h2>Final Demo Recap<\/h2>\n<p>At this point, the travel gallery has a complete upload flow. Users can click one button, open the Cloudinary Upload Widget, and upload travel photos from different sources.<\/p>\n<p>After upload, the app can:<\/p>\n<ul>\n<li>Show a success or error toast.<\/li>\n<li>Add the new image to the gallery.<\/li>\n<li>Display optimized thumbnails.<\/li>\n<li>Load images with better performance.<\/li>\n<li>Avoid page refreshes.<\/li>\n<\/ul>\n<p>You can explore the full project here:<\/p>\n<ul>\n<li>\n<strong>GitHub repo:<\/strong> <a href=\"https:\/\/github.com\/musebe\/react-travel-gallery\">https:\/\/github.com\/musebe\/react-travel-gallery<\/a>\n<\/li>\n<li>\n<strong>Live demo:<\/strong> <a href=\"https:\/\/react-travel-gallery.vercel.app\/\">https:\/\/react-travel-gallery.vercel.app<\/a>\n<\/li>\n<\/ul>\n<p>No adding extra upload logic from scratch. React handles the app state and gallery UI. Cloudinary handles the upload flow, image storage, and image delivery.<\/p>\n<p>Ready to start your own projects with Cloudinary? <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up<\/a> for a free account today.<\/p>\n<style>\n    .faqs {padding: 30px 60px; margin-top: 40px;background: var(--color-background-offset);border-radius: 20px;}\n    #frequently_asked_questions {margin-bottom: 20px;}\n    .question {margin-bottom: 20px;}\n<\/style>\n<div class=\"faqs\">\n<h2>Frequently Asked Questions<\/h2>\n<div class=\"question\">\n<p><b>Why should I use the Cloudinary Upload Widget instead of a custom file input?<\/b><\/p>\nThe widget manages complex UI tasks like drag and drop, progress bars, and retries natively. This allows you to focus on building your React gallery features instead of debugging tedious file upload logic.\n<\/div>\n<div class=\"question\">\n<p><b>What is create-cloudinary-react and how does it help?<\/b><\/p>\nIt is a starter kit that provides a pre-configured Vite and React environment. This tool helps you skip the initial configuration and jump straight into building media-rich applications with Cloudinary features.\n<\/div>\n<div class=\"question\">\n<p><b>How does React handle upload results from the widget?<\/b><\/p>\nYou use callback functions like onUploadSuccess to capture the result. These functions receive the image data from Cloudinary, allowing you to update your React state instantly and display success notifications to the user.\n<\/div>\n<div class=\"question\">\n<p><b>Can I upload images from sources other than my local device?<\/b><\/p>\nYes. The widget supports many external sources including your camera, Google Drive, Dropbox, and direct URLs. You can enable these additional sources by adding them to the widget configuration array.\n<\/div>\n<div class=\"question\">\n<p><b>How do I optimize gallery performance in a React application?<\/b><\/p>\nYou should use the Cloudinary React SDK to apply automatic format and quality transformations. Adding plugins for lazy loading and blur placeholders ensures your gallery remains fast even as you add more high-resolution images.\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":87,"featured_media":40057,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[246,373],"class_list":["post-40056","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-react","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>Build a React Travel Gallery: Cloudinary Upload Widget Guide<\/title>\n<meta name=\"description\" content=\"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.\" \/>\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\/travel-gallery-react-upload-widget\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget\" \/>\n<meta property=\"og:description\" content=\"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-21T14:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget\",\"datePublished\":\"2026-05-21T14:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\"},\"wordCount\":12,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA\",\"keywords\":[\"React\",\"Upload\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\",\"url\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\",\"name\":\"Build a React Travel Gallery: Cloudinary Upload Widget Guide\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA\",\"datePublished\":\"2026-05-21T14:00:00+00:00\",\"description\":\"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build a React Travel Gallery: Cloudinary Upload Widget Guide","description":"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.","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\/travel-gallery-react-upload-widget","og_locale":"en_US","og_type":"article","og_title":"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget","og_description":"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.","og_url":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","og_site_name":"Cloudinary Blog","article_published_time":"2026-05-21T14:00:00+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget","datePublished":"2026-05-21T14:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget"},"wordCount":12,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","keywords":["React","Upload"],"inLanguage":"en-US","copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","url":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","name":"Build a React Travel Gallery: Cloudinary Upload Widget Guide","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","datePublished":"2026-05-21T14:00:00+00:00","description":"Learn how to build a responsive travel gallery in React using the Cloudinary Upload Widget and create-cloudinary-react. Simplify your upload UI with drag and drop and progress tracking.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"parsely":{"version":"1.1.0","canonical_url":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","smart_links":{"inbound":0,"outbound":0},"traffic_boost_suggestions_count":0,"meta":{"@context":"https:\/\/schema.org","@type":"NewsArticle","headline":"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget","url":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget","mainEntityOfPage":{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA&w=150&h=150&crop=1","image":{"@type":"ImageObject","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA"},"articleSection":"Uncategorized","author":[{"@type":"Person","name":"melindapham"}],"creator":["melindapham"],"publisher":{"@type":"Organization","name":"Cloudinary Blog","logo":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA"},"keywords":["react","upload"],"dateCreated":"2026-05-21T14:00:00Z","datePublished":"2026-05-21T14:00:00Z","dateModified":"2026-05-21T14:00:00Z"},"rendered":"<meta name=\"parsely-title\" content=\"Build a React Travel Gallery With create-cloudinary-react and the Cloudinary Upload Widget\" \/>\n<meta name=\"parsely-link\" content=\"https:\/\/cloudinary.com\/blog\/travel-gallery-react-upload-widget\" \/>\n<meta name=\"parsely-type\" content=\"post\" \/>\n<meta name=\"parsely-image-url\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA&w=150&amp;h=150&amp;crop=1\" \/>\n<meta name=\"parsely-pub-date\" content=\"2026-05-21T14:00:00Z\" \/>\n<meta name=\"parsely-section\" content=\"Uncategorized\" \/>\n<meta name=\"parsely-tags\" content=\"react,upload\" \/>\n<meta name=\"parsely-author\" content=\"melindapham\" \/>","tracker_url":"https:\/\/cdn.parsely.com\/keys\/cloudinary.com\/p.js"},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1778863769\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget\/Blog_Build_a_React_Travel_Gallery_With_create-cloudinary-react_and_the_Cloudinary_Upload_Widget.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=40056"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40056\/revisions"}],"predecessor-version":[{"id":40058,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/40056\/revisions\/40058"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/40057"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=40056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=40056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=40056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}