{"id":36406,"date":"2024-12-06T07:00:00","date_gmt":"2024-12-06T15:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=36406"},"modified":"2025-10-23T10:14:19","modified_gmt":"2025-10-23T17:14:19","slug":"build-masonry-gallery-next-js-cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary","title":{"rendered":"How to Build a Masonry Gallery in Next.js With Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>A Masonry gallery layout is an elegant way to display images. Each item is arranged in a staggered grid, allowing for more creative space utilization. I\u2019ve always found this layout to be a great choice, especially for smaller collections of images because it makes the most of available space while keeping the presentation visually interesting.<\/p>\n<p>In this blog post, I\u2019ll show you how to create a simple Masonry gallery using Masonry js react in Next.js and Cloudinary to host and optimize the images.<\/p>\n<p>If you don\u2019t already have one, you can <a href=\"https:\/\/cloudinary.com\/users\/register_free\">get a free-for-life Cloudinary account<\/a>. Cloudinary makes building a Masonry gallery super fast and easy (and lots more).<\/p>\n<p>We\u2019ll also use Tailwind CSS to handle the styling quickly and efficiently, keeping things simple but effective. By the end, you\u2019ll have a neat and responsive gallery layout that looks great with minimal effort.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1733440585\/Web_Assets\/blog\/blog-How-to-Build-a-Masonry-Gallery-in-Next.js-With-Cloudinary-1\/blog-How-to-Build-a-Masonry-Gallery-in-Next-js-With-Cloudinary-1-png?_i=AA\" alt=\"Image showing a next js masonry layout of pictures of a woman laughing, mountains, food, people playing basketball, and a shoe to be used in the masonry js react project\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"838\" height=\"341\"\/><\/p>\n<h2>Setting Up the Project<\/h2>\n<p>To get started, I used the command <code>npx create-next-app@latest<\/code> and followed the prompts. One of the nice things about this setup is that it already offers an option to include Tailwind CSS during the installation, so no need to set that up separately.<\/p>\n<p>Once the project was ready, I added the next-cloudinary package by running:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install next-cloudinary\n<\/code><\/span><\/pre>\n<p>After that, I set the <code>NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME<\/code> environment variable in my <code>.env.local<\/code> file so Cloudinary could adequately handle the image hosting. With that in place, I was ready to start building the Masonry gallery.<\/p>\n<h2>Creating the Masonry Gallery Components<\/h2>\n<p>Now that the project setup is complete let\u2019s dive into building the components for the Masonry gallery. The gallery will consist of two main parts: <code>MasonryGallery<\/code> and <code>MasonryItem<\/code>, with a custom <code>CldImage<\/code> component for optimized image delivery using Cloudinary.<\/p>\n<p>First, we\u2019ll create the <code>MasonryGallery<\/code> and <code>MasonryItem<\/code> components, here\u2019s the code for both in the Next.js React environment:<\/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-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\".\/index.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> CustomImage <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@\/components\/cloudinary-image\/CustomImage.client\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MasonryGallery<\/span>(<span class=\"hljs-params\">{ children }: { children: React.ReactNode }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"masonry-gallery my-4\"<\/span>&gt;<\/span>{children}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>;\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MasonryItem<\/span>(<span class=\"hljs-params\">{ src, alt }: { src: string; alt: string }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"masonry-item\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CustomImage<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{src}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"rounded-lg\"<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-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>The <code>MasonryGallery<\/code> component wraps the gallery layout with simple styling using the <code>masonry-gallery<\/code> class. The <code>MasonryItem<\/code> component receives the image source and alt text as props and passes them to the <code>CustomImage<\/code> component.<\/p>\n<p>Speaking of <code>CustomImage<\/code>, this is where we use Cloudinary to optimize the image delivery:<\/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-string\">\"use client\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { CldImage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next-cloudinary\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">CustomImage<\/span>(<span class=\"hljs-params\">{\n  src,\n  alt,\n  className = <span class=\"hljs-string\">\"\"<\/span>,\n}: {\n  src: string;\n  alt: string;\n  className?: string;\n}<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CldImage<\/span>\n      <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{src}<\/span>\n      <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span>\n      <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500\"<\/span>\n      <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"500\"<\/span>\n      <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">{{<\/span>\n        <span class=\"hljs-attr\">type:<\/span> \"<span class=\"hljs-attr\">auto<\/span>\",\n        <span class=\"hljs-attr\">source:<\/span> <span class=\"hljs-attr\">true<\/span>,\n      }}\n      <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{className}<\/span>\n    \/&gt;<\/span><\/span>\n  );\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 component leverages the <code>CldImage<\/code> from <code>next-cloudinary<\/code> to ensure images are delivered in the best format and quality for the user\u2019s device. I\u2019ve set the width and height to <code>500x500<\/code> for this example, and the <code>auto<\/code> cropping ensures Cloudinary optimizes the images on the fly.<\/p>\n<p>Next, apply the CSS Grid layout logic to get that Masonry look. Here\u2019s the CSS for the gallery:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">.masonry-gallery {\n  display: grid;\n  grid-template-columns: repeat(2, 1fr);\n  grid-auto-rows: 1fr;\n  gap: 1rem;\n\n  img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n  }\n}\n\n.masonry-item {\n  grid-row: span 1;\n}\n\n.masonry-item:nth-child(1),\n.masonry-item:nth-child(5) {\n  grid-row: span 2;\n}\n<\/code><\/span><\/pre>\n<p>The key here is using CSS Grid to define a 2-column layout and controlling the row span dynamically based on the order of the images. Using the <code>nth-child()<\/code> selector, I can make specific images take up more vertical space, giving the layout a staggered Masonry feel.<\/p>\n<h2>Putting It All Together on the Home Page<\/h2>\n<p>Now that we\u2019ve set up the gallery components, it\u2019s time to put everything together in the home page. For this example, I\u2019m using some sample public images from Cloudinary, but in a real-world scenario, you\u2019d replace these with images from your Cloudinary account.<\/p>\n<p>Here\u2019s the code for the home <code>page<\/code> component:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> {\n  MasonryGallery,\n  MasonryItem,\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@\/components\/masonry-gallery\/MasonryGallery\"<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"border-4 rounded-lg border-purple-500 p-8 max-w-screen-lg\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryGallery<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 1\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-2\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 2\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-3\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 3\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-4\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 4\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-5\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 5\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 1 again\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-2\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 2 again\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"cld-sample-3\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"sample image 3 again\"<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">MasonryGallery<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  );\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>I\u2019ve rendered the <code>MasonryGallery<\/code> component on the page and used multiple <code>MasonryItem<\/code> components, each pointing to a sample image from Cloudinary. The images are identified by their public IDs, such as <code>cld-sample<\/code>, <code>cld-sample-2<\/code>, and so on. These sample images are publicly available, but in an actual project, you\u2019d replace them with your image assets hosted on Cloudinary.<\/p>\n<p>You can customize the images by replacing the <code>src<\/code> value with the public ID of any image from your Cloudinary account. For example, if you\u2019ve uploaded an image named <code>my-awesome-image<\/code>, you\u2019d use it like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" 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\">MasonryItem<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"my-awesome-image\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"My awesome image\"<\/span> \/&gt;<\/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\">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 approach makes it easy to manage and optimize images hosted on Cloudinary, and they\u2019ll be delivered in the best possible format based on the user\u2019s device.<\/p>\n<h2>Making the Masonry Gallery Responsive<\/h2>\n<p>To ensure the Masonry gallery looks great across different screen sizes, we can add a couple of media queries to adjust the number of columns and the row spans for particular images. Here\u2019s the updated CSS:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-keyword\">@media<\/span> screen <span class=\"hljs-keyword\">and<\/span> (<span class=\"hljs-attribute\">min-width:<\/span> <span class=\"hljs-number\">640px<\/span>) {\n  <span class=\"hljs-selector-class\">.masonry-gallery<\/span> {\n    <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-built_in\">repeat<\/span>(<span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">1<\/span>fr);\n  }\n\n  <span class=\"hljs-selector-class\">.masonry-item<\/span><span class=\"hljs-selector-pseudo\">:nth-child(6)<\/span>,\n  <span class=\"hljs-selector-class\">.masonry-item<\/span><span class=\"hljs-selector-pseudo\">:nth-child(7)<\/span> {\n    <span class=\"hljs-attribute\">grid-row<\/span>: span <span class=\"hljs-number\">2<\/span>;\n  }\n}\n\n<span class=\"hljs-keyword\">@media<\/span> screen <span class=\"hljs-keyword\">and<\/span> (<span class=\"hljs-attribute\">min-width:<\/span> <span class=\"hljs-number\">1024px<\/span>) {\n  <span class=\"hljs-selector-class\">.masonry-gallery<\/span> {\n    <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-built_in\">repeat<\/span>(<span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">1<\/span>fr);\n  }\n\n  <span class=\"hljs-selector-class\">.masonry-item<\/span><span class=\"hljs-selector-pseudo\">:nth-child(6)<\/span>,\n  <span class=\"hljs-selector-class\">.masonry-item<\/span><span class=\"hljs-selector-pseudo\">:nth-child(7)<\/span> {\n    <span class=\"hljs-attribute\">grid-row<\/span>: span <span class=\"hljs-number\">1<\/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\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>With this simple addition, the gallery will adapt to different screen sizes.<\/p>\n<h3>Phone View (Under 640px)<\/h3>\n<p>On small screens (less than 640px wide), the gallery will stack images in two columns.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1733440581\/Web_Assets\/blog\/blog-How-to-Build-a-Masonry-Gallery-in-Next.js-With-Cloudinary-2\/blog-How-to-Build-a-Masonry-Gallery-in-Next-js-With-Cloudinary-2-png?_i=AA\" alt=\"Image showing  the results of the masonry js react work displayed in format for mobile phone including pictures of a woman laughing, mountains, food, people playing basketball, and a shoe to be used in them\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"374\" height=\"929\"\/><\/p>\n<h3>Tablet View (640px to 1024px)<\/h3>\n<p>On medium screens (640px to 1024px wide), it will display four columns, with the last two images taking up more vertical space.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1733440577\/Web_Assets\/blog\/blog-How-to-Build-a-Masonry-Gallery-in-Next.js-With-Cloudinary-3\/blog-How-to-Build-a-Masonry-Gallery-in-Next-js-With-Cloudinary-3-png?_i=AA\" alt=\"Image showing  the results of the masonry js react work displayed in format for tablet including pictures of a woman laughing, mountains, food, people playing basketball, and a shoe to be used in them\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"710\" height=\"533\"\/><\/p>\n<h3>Desktop View (1024px and above)<\/h3>\n<p>On large screens (1024px and above), it will display five columns, with the last two images back to their normal span.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1733440585\/Web_Assets\/blog\/blog-How-to-Build-a-Masonry-Gallery-in-Next.js-With-Cloudinary-1\/blog-How-to-Build-a-Masonry-Gallery-in-Next-js-With-Cloudinary-1-png?_i=AA\" alt=\"Image showing  the results of the masonry js react work displayed in format for desktop computer including pictures of a woman laughing, mountains, food, people playing basketball, and a shoe to be used in them\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"838\" height=\"341\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>And that\u2019s it! We\u2019ve built a responsive Masonry js React gallery using Next.js, Cloudinary, and Tailwind CSS in just a few steps. This layout is a creative way to display a small collection of images and maximize space.<\/p>\n<p>By leveraging <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> for image optimization and delivery, we ensure that our gallery performs well across different devices. Adding some simple responsive styles with Tailwind ensures the gallery adapts perfectly to any screen size.<\/p>\n<p>Feel free to take this example and tweak it to fit your needs \u2013 whether you decide to change the number of columns, using your Cloudinary images, or adding more custom styles. I hope this has inspired you to try out Masonry layouts in your projects and take advantage of how simple it can be to create one with these tools!<\/p>\n<p>If you found this blog post helpful and want to discuss it in more detail, head over to the <a href=\"https:\/\/community.cloudinary.com\/\">Cloudinary Community forum<\/a> and its associated <a href=\"https:\/\/community.cloudinary.com\/\">Discord<\/a>.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":87,"featured_media":36411,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[370,212],"class_list":["post-36406","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-image","tag-next-js"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Build a Masonry Gallery in Next.js With Cloudinary for Free<\/title>\n<meta name=\"description\" content=\"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.\" \/>\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\/build-masonry-gallery-next-js-cloudinary\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Build a Masonry Gallery in Next.js With Cloudinary\" \/>\n<meta property=\"og:description\" content=\"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-12-06T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-23T17:14:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.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\/build-masonry-gallery-next-js-cloudinary#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"How to Build a Masonry Gallery in Next.js With Cloudinary\",\"datePublished\":\"2024-12-06T15:00:00+00:00\",\"dateModified\":\"2025-10-23T17:14:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\"},\"wordCount\":11,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA\",\"keywords\":[\"Image\",\"Next.js\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\",\"url\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\",\"name\":\"How to Build a Masonry Gallery in Next.js With Cloudinary for Free\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA\",\"datePublished\":\"2024-12-06T15:00:00+00:00\",\"dateModified\":\"2025-10-23T17:14:19+00:00\",\"description\":\"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA\",\"width\":2000,\"height\":1100,\"caption\":\"Image showing a next js masonry layout of pictures of coffee, coffee beans and coffee makers to be used in the masonry js react project\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Build a Masonry Gallery in Next.js With 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\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Build a Masonry Gallery in Next.js With Cloudinary for Free","description":"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.","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\/build-masonry-gallery-next-js-cloudinary","og_locale":"en_US","og_type":"article","og_title":"How to Build a Masonry Gallery in Next.js With Cloudinary","og_description":"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.","og_url":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary","og_site_name":"Cloudinary Blog","article_published_time":"2024-12-06T15:00:00+00:00","article_modified_time":"2025-10-23T17:14:19+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.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\/build-masonry-gallery-next-js-cloudinary#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"How to Build a Masonry Gallery in Next.js With Cloudinary","datePublished":"2024-12-06T15:00:00+00:00","dateModified":"2025-10-23T17:14:19+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary"},"wordCount":11,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA","keywords":["Image","Next.js"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary","url":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary","name":"How to Build a Masonry Gallery in Next.js With Cloudinary for Free","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA","datePublished":"2024-12-06T15:00:00+00:00","dateModified":"2025-10-23T17:14:19+00:00","description":"Learn how easy it is to create a Masonry gallery using Masonry js React in Next js with Cloudinary\u2019s free for life access.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA","width":2000,"height":1100,"caption":"Image showing a next js masonry layout of pictures of coffee, coffee beans and coffee makers to be used in the masonry js react project"},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/build-masonry-gallery-next-js-cloudinary#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Build a Masonry Gallery in Next.js With 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":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1733182234\/Masonry_Gallery_in_NextJS\/Masonry_Gallery_in_NextJS.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36406","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=36406"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36406\/revisions"}],"predecessor-version":[{"id":38988,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36406\/revisions\/38988"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/36411"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=36406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=36406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=36406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}