{"id":28389,"date":"2022-05-05T08:37:36","date_gmt":"2022-05-05T08:37:36","guid":{"rendered":"http:\/\/create-an-optimized-image-gallery-in-next.js"},"modified":"2025-03-02T10:04:02","modified_gmt":"2025-03-02T18:04:02","slug":"create-an-optimized-image-gallery-in-next-js","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/","title":{"rendered":"Create an Optimized Image Gallery in Next.js"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>High-fidelity product image galleries are a critical component of successful e-commerce campaigns.<\/p>\n<p>In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary\u2019s Product Gallery widget.<\/p>\n<h2>Sandbox<\/h2>\n<p>The completed project is on <a href=\"https:\/\/codesandbox.io\/s\/cloudinary-widget-image-gallery-xdf7c6\">CodeSandbox<\/a>. Fork it and run the code.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;Codesandbox id=&quot;cloudinary-widget-image-gallery-xdf7c6&quot; title=&quot;cloudinary-widget-image-gallery&quot; \/&gt;\n<\/code><\/pre>\n<p>The source code is also available on <a href=\"https:\/\/github.com\/nefejames\/hackmamba-cloudinary-product-widget\">GitHub<\/a>.<\/p>\n<h2>Prerequisites<\/h2>\n<p>Knowledge of React and Next.js, as well as a <a href=\"https:\/\/cloudinary.com\/console\">Cloudinary account<\/a>, are required to get the most out of this article.<\/p>\n<h2>Getting started<\/h2>\n<p>Create a Next.js project by running the command below in our terminal.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-next-app robust-product-image-gallery\n<\/code><\/span><\/pre>\n<p>Next, navigate into the project directory and run the application.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">cd airbnb-cards-demo\n<\/code><\/span><\/pre>\n<p>Then, run the command below to start the application.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\"> npm run dev\n<\/code><\/span><\/pre>\n<h2>Setting Up Cloudinary<\/h2>\n<p>Navigate to the Media Library section of the Cloudinary dashboard, and there, create a new folder called <code>image-gallery<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649618599017_rsz_screenshot_822.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"724\" height=\"474\"\/><\/p>\n<p>Upload some images into the <code>image-gallery<\/code> folder.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649618967294_rsz_1screenshot_832.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1115\" height=\"551\"\/><\/p>\n<h2>Cloudinary\u2019s Product Gallery Widget<\/h2>\n<p>With <a href=\"https:\/\/cloudinary.com\/documentation\/product_gallery\">Cloudinary\u2019s Product Gallery widget<\/a>, we can dynamically display images, videos, 3D models, and 360 degree animations on our websites with ease.<\/p>\n<p>To integrate the widget into our application, the following steps are required:<\/p>\n<ul>\n<li>Tag the media assets so that the widget can easily retrieve them.<\/li>\n<li>Provide access to client-side resource lists.<\/li>\n<\/ul>\n<p>To add tags to images, click on an image, and then a sidebar will appear on the right side of the dashboard.<\/p>\n<p>Click on the \u201cmetadata\u201d setting in the sidebar, set the tag to \u201cclothes,\u201d and then save that tag. We\u2019ll do this for all the images we want the widget to track.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649618432904_rsz_screenshot_823.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"804\" height=\"393\"\/><\/p>\n<p>Cloudinary supports listing resources from the client side by their tags. However, the resource list is restricted by default, so we need to enable it on our account\u2019s <a href=\"https:\/\/cloudinary.com\/console\/settings\/security\">security settings page<\/a>.<\/p>\n<p>On the security settings page, scroll down to \u2018Restricted media types.\u2019 There, uncheck \u2018Resource List,\u2019 then save.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649618294137_rsz_screenshot_825.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"674\" height=\"327\"\/><\/p>\n<h2>Initializing the Product Gallery Widget in Our Application<\/h2>\n<p>Update the <code>index.js<\/code> file with the code below.<\/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> { useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/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  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> productGallery = cloudinary.galleryWidget({\n      <span class=\"hljs-attr\">container<\/span>: <span class=\"hljs-string\">\"#image-gallery\"<\/span>,\n      <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">\"nefejames\"<\/span>,\n      <span class=\"hljs-attr\">mediaAssets<\/span>: &#91;{ <span class=\"hljs-attr\">tag<\/span>: <span class=\"hljs-string\">\"clothes\"<\/span> }],\n    });\n\n    productGallery.render();\n  }, &#91;]);\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Robust Image Gallery<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-container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"image-gallery\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/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>In the file above, we do the following:<\/p>\n<ul>\n<li>\n<p>Import <code>useEffect<\/code> from React, and from there, initialize the widget.<\/p>\n<\/li>\n<li>\n<p>Set up a <code>div<\/code> with an ID of <code>image-gallery<\/code>. This is the element where we will render the Product Gallery.<\/p>\n<\/li>\n<\/ul>\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-keyword\">const<\/span> productGallery = cloudinary.galleryWidget({\n   <span class=\"hljs-attr\">container<\/span>: <span class=\"hljs-string\">\"#image-gallery\"<\/span>,\n   <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">\"nefejames\"<\/span>,\n   <span class=\"hljs-attr\">mediaAssets<\/span>: &#91;{ <span class=\"hljs-attr\">tag<\/span>: <span class=\"hljs-string\">\"clothes\"<\/span> }],  \n });\n \n productGallery.render();\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>Let\u2019s break down the code above that initializes the widget.<\/p>\n<ul>\n<li>\n<p><code>cloudinary.galleryWidget(options)<\/code>: initializes the widget. It takes in <code>container<\/code>, <code>cloudName<\/code>, and <code>mediaAsset<\/code> as required parameters.<\/p>\n<\/li>\n<li>\n<p><code>container<\/code>: references the <code>div<\/code> with the ID of <code>image-gallery<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>cloudName<\/code>: the cloud name of our Cloudinary account.<\/p>\n<\/li>\n<li>\n<p><code>mediaAssets<\/code>: an array of the media assets we want to display.<\/p>\n<\/li>\n<li>\n<p><code>productGallery.render()<\/code>: renders the product gallery widget.<\/p>\n<\/li>\n<\/ul>\n<p><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/script\">Next.js provides a <code>Script<\/code> component<\/a> that we can use to load third-party scripts in our application. We need the <code>Script<\/code> component to load the Product Gallery widget\u2019s script.<\/p>\n<p>Next, we\u2019ll import Script into the <code>app.js<\/code> file and load the cloudinary gallery there.<\/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> <span class=\"hljs-string\">\"..\/styles\/globals.css\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Script <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/script\"<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MyApp<\/span>(<span class=\"hljs-params\">{ Component, pageProps }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Script<\/span>\n        <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/product-gallery.cloudinary.com\/all.js\"<\/span>\n        <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\/javascript\"<\/span>\n      \/&gt;<\/span><span class=\"handlebars\"><span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span><\/span><\/span>\n  );\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> MyApp;\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>If we run our code, we get an error: \u201ccloudinary is not defined.\u201d<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649619459468_rsz_screenshot_833.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1005\" height=\"503\"\/><\/p>\n<p>This is because the widget is a client-side tool, and Next.js renders our application on the server. To fix this, we need to change the strategy of the <code>Script<\/code>.<\/p>\n<p>Thus, update the <code>app.js<\/code> file and set the <code>Script<\/code>\u2019s <code>strategy<\/code> <code>beforeInteractive<\/code>.<\/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-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MyApp<\/span>(<span class=\"hljs-params\">{ Component, pageProps }<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Script<\/span>\n        <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/product-gallery.cloudinary.com\/all.js\"<\/span>\n        <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\/javascript\"<\/span>\n        <span class=\"hljs-attr\">strategy<\/span>=<span class=\"hljs-string\">\"beforeInteractive\"<\/span> \/\/<span class=\"hljs-attr\">this<\/span> <span class=\"hljs-attr\">has<\/span> <span class=\"hljs-attr\">to<\/span> <span class=\"hljs-attr\">be<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">strategy<\/span>\n      \/&gt;<\/span><span class=\"handlebars\"><span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span><\/span><\/span>\n  );\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> MyApp;\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>The <code>beforeInteractive<\/code> strategy loads scripts before a page becomes interactive. Use this strategy for critical scripts that must be fetched and executed before the page is interactive.<\/p>\n<p>Next.js ensures that such scripts are injected into the initial HTML on the server and executed before other self-bundled JavaScript.<\/p>\n<p>If we rerun our code, we see the product gallery display properly.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_8421F0144513C15AA2174EC50E1B3A34EDD091173DDE163FA8235FBA9019409C_1649618018927_rsz_screenshot_830.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"816\" height=\"643\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>This article taught us how to build a robust image gallery with Next.js and Cloudinary\u2019s Product Gallery widget.<\/p>\n<h2>Resources<\/h2>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/product_gallery\">Cloudinary\u2019s Product Gallery Documentation<\/a>\n<a href=\"https:\/\/cloudinary.com\/documentation\/product_gallery_reference\"><\/a>&#8211; <a href=\"https:\/\/cloudinary.com\/documentation\/product_gallery_reference\">Cloudinary\u2019s Product Gallery API Reference<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/nextjs.org\/docs\/basic-features\/script\">Next Script Documentation<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28390,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,212,371],"class_list":["post-28389","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-next-js","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Create an Optimized Image Gallery in Next.js<\/title>\n<meta name=\"description\" content=\"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary&#039;s Product Gallery widget.\" \/>\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\/create-an-optimized-image-gallery-in-next-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create an Optimized Image Gallery in Next.js\" \/>\n<meta property=\"og:description\" content=\"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary&#039;s Product Gallery widget.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-05T08:37:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-02T18:04:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"4608\" \/>\n\t<meta property=\"og:image:height\" content=\"3456\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\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\/create-an-optimized-image-gallery-in-next-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Create an Optimized Image Gallery in Next.js\",\"datePublished\":\"2022-05-05T08:37:36+00:00\",\"dateModified\":\"2025-03-02T18:04:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Next.js\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\",\"name\":\"Create an Optimized Image Gallery in Next.js\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA\",\"datePublished\":\"2022-05-05T08:37:36+00:00\",\"dateModified\":\"2025-03-02T18:04:02+00:00\",\"description\":\"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary's Product Gallery widget.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA\",\"width\":4608,\"height\":3456},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create an Optimized Image Gallery in Next.js\"}]},{\"@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":"Create an Optimized Image Gallery in Next.js","description":"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary's Product Gallery widget.","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\/create-an-optimized-image-gallery-in-next-js\/","og_locale":"en_US","og_type":"article","og_title":"Create an Optimized Image Gallery in Next.js","og_description":"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary's Product Gallery widget.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-05-05T08:37:36+00:00","article_modified_time":"2025-03-02T18:04:02+00:00","og_image":[{"width":4608,"height":3456,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/"},"author":{"name":"","@id":""},"headline":"Create an Optimized Image Gallery in Next.js","datePublished":"2022-05-05T08:37:36+00:00","dateModified":"2025-03-02T18:04:02+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA","keywords":["Guest Post","Image","Next.js","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/","name":"Create an Optimized Image Gallery in Next.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA","datePublished":"2022-05-05T08:37:36+00:00","dateModified":"2025-03-02T18:04:02+00:00","description":"In this article, we will build a fully optimized and robust image gallery with Next.js and Cloudinary's Product Gallery widget.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA","width":4608,"height":3456},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-an-optimized-image-gallery-in-next-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create an Optimized Image Gallery in Next.js"}]},{"@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\/v1681928552\/Web_Assets\/blog\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47\/7ee6304f7552a9b80853c514524aadb6522a55d2-4608x3456-1_283908bb47.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28389","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=28389"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28389\/revisions"}],"predecessor-version":[{"id":37082,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28389\/revisions\/37082"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28390"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}