{"id":27932,"date":"2021-05-18T22:02:25","date_gmt":"2021-05-18T22:02:25","guid":{"rendered":"http:\/\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary"},"modified":"2025-02-16T08:19:15","modified_gmt":"2025-02-16T16:19:15","slug":"photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/","title":{"rendered":"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.<\/p>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/photo-gallery-auto-thumbs-react-cloudinary-lin29?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=%2Fsrc%2FApp.js&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary\"\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>Upload your assets to Cloudinary.<\/h2>\n<p>First, we need to get all of our images uploaded to Cloudinary. The fastest way to do this is using the <a href=\"https:\/\/cloudinary.com\/console?ap=lwj\">Cloudinary console<\/a>.<\/p>\n<p>For this tutorial, we\u2019ll use four images:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/tokyo.jpg\">https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/tokyo.jpg<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/react-india.jpg\">https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/react-india.jpg<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/puppies.jpg\">https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/puppies.jpg<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/barcelona.jpg\">https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/mediajams\/barcelona.jpg<\/a>\n<\/li>\n<\/ul>\n<p>With these photos uploaded, we can create a photo gallery in React!<\/p>\n<h2>Create a function to generate Cloudinary URLs<\/h2>\n<p>To display images, we\u2019ll need to generate Cloudinary URLs for both full-size and <a href=\"https:\/\/cloudinary.com\/glossary\/thumbnails\">thumbnail images<\/a>. Since this will be essentially the same except for the transformations we apply, let\u2019s write a utility function to avoid duplicating our code.<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getImageUrl<\/span>(<span class=\"hljs-params\">{ cloudName, publicId, transformations }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">`https:\/\/res.cloudinary.com\/<span class=\"hljs-subst\">${cloudName}<\/span>\/image\/upload\/<span class=\"hljs-subst\">${transformations}<\/span>\/<span class=\"hljs-subst\">${publicId}<\/span>.jpg`<\/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>This function accepts a config object with three properties: <code>cloudName<\/code>, <code>publicId<\/code>, and <code>transformations<\/code>.<\/p>\n<p>The <code>cloudName<\/code> should contain our Cloudinary cloud name, which is displayed at the top-right of the console.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jlengstorf\/image\/upload\/q_auto,f_auto,w_600\/c_limit,w_2000\/f_auto\/q_auto\/v1617499746\/mediajams\/cloud-name.png\" alt=\"The Cloudinary console with an arrow pointing to the location of the cloud name.\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"413\"\/><\/p>\n<p>The <code>publicId<\/code> will contain the public ID of the image to display. For example, if we wanted to show one of our images listed above, we could pass in <code>mediajams\/tokyo<\/code>.<\/p>\n<p>Finally, the <code>transformations<\/code> will contain a string of <a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations?ap=lwj\">image transformations<\/a> that allow us to do things including resizing and cropping the image. This is what makes automatic thumbnail creation possible!<\/p>\n<h2>Create a React component to display full-size images<\/h2>\n<p>Using the <code>getImageUrl()<\/code> utility, we can define a React component to display our full-size images.<\/p>\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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Image<\/span>(<span class=\"hljs-params\">{ cloudName, publicId, alt }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> imageSource = getImageUrl({\n    cloudName,\n    publicId,\n    <span class=\"hljs-attr\">transformations<\/span>: <span class=\"hljs-string\">\"q_auto,f_auto,c_fill,g_face,w_400,ar_1\"<\/span>\n  });\n\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{imageSource}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span> \/&gt;<\/span><\/span>;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This applies the following transformations:<\/p>\n<ul>\n<li>Automatic <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#q_auto\">quality<\/a> and <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#f_auto\">format<\/a> optimizations to reduce image sizes for performance<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#c_fill\">Fill cropping<\/a> to make sure all the images are the same size<\/li>\n<li>Centering the cropped image on the subject using <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#g_special_position\">face detection in the gravity transformation<\/a>\n<\/li>\n<li>Resizing the <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#w_width_value\">width<\/a> to 400px<\/li>\n<li>Setting the <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#ar_aspect_ratio\">aspect ratio<\/a> to square (1:1)<\/li>\n<\/ul>\n<p>The result will be an optimized, square image, 400px wide, with the subject\u2019s face centered in the cropped image.<\/p>\n<h2>Create a React component to display a thumbnail image<\/h2>\n<p>To display thumbnails, we can use almost exactly the same setup as the <code>Image<\/code> component, but we make a couple small adjustments to the transformations:<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Thumb<\/span>(<span class=\"hljs-params\">{ cloudName, publicId, alt }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> imageSource = getImageUrl({\n    cloudName,\n    publicId,\n    <span class=\"hljs-attr\">transformations<\/span>: <span class=\"hljs-string\">\"q_auto,f_auto,c_thumb,g_face,w_50,ar_1\"<\/span>\n  });\n\n  <span class=\"hljs-comment\">\/\/ add the full URL to a standard HTML5 video element<\/span>\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{imageSource}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span> \/&gt;<\/span><\/span>;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We resize to 50px and switch over to <a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference?ap=lwj#c_thumb\">thumb cropping<\/a>, which will zoom in on the face found in the photo for a more interesting thumbnail.<\/p>\n<h2>Bring it all together to create a React-powered photo gallery<\/h2>\n<p>Now that we can generate both images and thumbnails, we can combine them to create a photo gallery!<\/p>\n<p>First, we set up an array with our image data:<\/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> photoArray = &#91;\n  { <span class=\"hljs-attr\">publicId<\/span>: <span class=\"hljs-string\">\"mediajams\/tokyo\"<\/span>, <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"Jason on a train platform in Tokyo\"<\/span> },\n  {\n    <span class=\"hljs-attr\">publicId<\/span>: <span class=\"hljs-string\">\"mediajams\/react-india\"<\/span>,\n    <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"Jason talking to someone at React India\"<\/span>\n  },\n  { <span class=\"hljs-attr\">publicId<\/span>: <span class=\"hljs-string\">\"mediajams\/puppies\"<\/span>, <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"Jason holding two puppies\"<\/span> },\n  {\n    <span class=\"hljs-attr\">publicId<\/span>: <span class=\"hljs-string\">\"mediajams\/barcelona\"<\/span>,\n    <span class=\"hljs-attr\">alt<\/span>: <span class=\"hljs-string\">\"Jason walking along an alley in Barcelona\"<\/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>Then, we can create a component to display them!<\/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\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;selected, setSelected] = React.useState(photoArray&#91;<span class=\"hljs-number\">0<\/span>]);\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/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\">\"gallery\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span>\n          <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"jlengstorf\"<\/span>\n          <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{selected.publicId}<\/span>\n          <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{selected.alt}<\/span>\n        \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"thumbnails\"<\/span>&gt;<\/span>\n          {photoArray.map((photo) =&gt; (\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n              <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setSelected(photo)}\n              className={selected.publicId === photo.publicId ? \"selected\" : \"\"}\n            &gt;\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Thumb<\/span>\n                <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"jlengstorf\"<\/span>\n                <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{photo.publicId}<\/span>\n                <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{photo.alt}<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n          ))}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\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><\/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>With React state, we can keep track of which image is selected, and use that to set the full-size image.<\/p>\n<p>For each image, we want to create a thumbnail wrapped in a button so we can change which image is displayed full size. On click, we call the <code>setSelected<\/code> function to update the currently selected image.<\/p>\n<p>Once this is rendered on the page, we can see a fully functional image gallery with auto-generated, interesting thumbnails!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27933,"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,246,371],"class_list":["post-27932","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-react","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>Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary<\/title>\n<meta name=\"description\" content=\"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.\" \/>\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\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary\" \/>\n<meta property=\"og:description\" content=\"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-05-18T22:02:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-16T16:19:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1588\" \/>\n\t<meta property=\"og:image:height\" content=\"1018\" \/>\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\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary\",\"datePublished\":\"2021-05-18T22:02:25+00:00\",\"dateModified\":\"2025-02-16T16:19:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"React\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\",\"name\":\"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA\",\"datePublished\":\"2021-05-18T22:02:25+00:00\",\"dateModified\":\"2025-02-16T16:19:15+00:00\",\"description\":\"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA\",\"width\":1588,\"height\":1018},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Photo Gallery With Automatic Thumbnails Using React &amp; 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":"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary","description":"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.","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\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/","og_locale":"en_US","og_type":"article","og_title":"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary","og_description":"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-05-18T22:02:25+00:00","article_modified_time":"2025-02-16T16:19:15+00:00","og_image":[{"width":1588,"height":1018,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35-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\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/"},"author":{"name":"","@id":""},"headline":"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary","datePublished":"2021-05-18T22:02:25+00:00","dateModified":"2025-02-16T16:19:15+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA","keywords":["Guest Post","Image","React","Under Review"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/","name":"Photo Gallery With Automatic Thumbnails Using React &amp; Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA","datePublished":"2021-05-18T22:02:25+00:00","dateModified":"2025-02-16T16:19:15+00:00","description":"Generating thumbnails for a photo gallery can feel tedious if you have to do it all by hand. With Cloudinary, we can automatically generate thumbnails from our full-size images that focus in on faces. In this tutorial, we\u2019ll learn how to automatically generate both full-sized and thumbnail images for a React-powered photo gallery.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA","width":1588,"height":1018},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/photo-gallery-with-automatic-thumbnails-using-react-and-cloudinary\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Photo Gallery With Automatic Thumbnails Using React &amp; 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\/v1681924089\/Web_Assets\/blog\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35\/f859b42aa9a3628af4b6213384ae9a09108bbfe0-1588x1018-1_2793345a35.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27932","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=27932"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27932\/revisions"}],"predecessor-version":[{"id":36841,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27932\/revisions\/36841"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27933"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}