{"id":27733,"date":"2022-08-15T16:36:29","date_gmt":"2022-08-15T16:36:29","guid":{"rendered":"http:\/\/automatically-watermark-image-gallery-on-upload"},"modified":"2025-02-22T15:47:21","modified_gmt":"2025-02-22T23:47:21","slug":"automatically-watermark-image-gallery-on-upload","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/","title":{"rendered":"Automatically Watermark an Image Gallery on Upload"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><h1>Introduction<\/h1>\n<p>A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission.<\/p>\n<p>In this article, we will learn how to add <a href=\"https:\/\/cloudinary.com\/glossary\/image-watermarking\">watermarks<\/a> to our images using Cloudinary in our Next.js apps.<\/p>\n<h1>Sandbox<\/h1>\n<p>The completed project is on <a href=\"https:\/\/codesandbox.io\/s\/nextjs-watermark-images-kfzcmz\">CodeSandbox<\/a>. Fork it and run the code.<\/p>\n<\/div>\n\n\n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/nextjs-watermark-images-kfzcmz?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=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"Automatically watermark stock images gallery on upload\"\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 \"><h1>GitHub repository<\/h1>\n<p><a href=\"https:\/\/github.com\/folucode\/nextjs_watermark_images\">https:\/\/github.com\/folucode\/nextjs_watermark_images<\/a><\/p>\n<h1>Prerequisite<\/h1>\n<p>To follow through with this article, we need to have:<\/p>\n<ul>\n<li>An understanding of JavaScript and Next.js<\/li>\n<li>A Cloudinary account \u2014 sign up <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">here<\/a>.<\/li>\n<\/ul>\n<h1>Project Setup<\/h1>\n<p><a href=\"https:\/\/nodejs.org\/en\/\">Node<\/a> and its package manager, <a href=\"https:\/\/www.npmjs.com\/\">npm<\/a>, are required to initialize a new project.<\/p>\n<p>To install Node.js, we go to the <a href=\"https:\/\/nodejs.org\/en\/\">Node<\/a><a href=\"https:\/\/nodejs.org\/en\/\">.<\/a><a href=\"https:\/\/nodejs.org\/en\/\">js website<\/a> and follow the instructions. We verify Node.js\u2019 installation using the terminal command below:<\/p>\n<pre><code>node -v\nv16.10.0 \/\/node version installed\n<\/code><\/pre>\n<p>The result shows the version of Node.js we installed on our computer.<\/p>\n<p>We\u2019ll now create our Next.js app using <code>create-next-app<\/code>, which automatically sets up a boilerplate Next.js app. To create a new project, run:<\/p>\n<pre><code>npx create-next-app@latest &lt;app-name&gt;\n# or\nyarn create next-app &lt;app-name&gt;\n<\/code><\/pre>\n<p>After the installation is complete, change the directory to the app we just created:<\/p>\n<pre><code>cd &lt;app-name&gt;\n<\/code><\/pre>\n<p>Now we run <code>npm run dev<\/code> or <code>yarn dev<\/code> to start the development server on <code>http:\/\/localhost:3000<\/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_D6D02CF8B03C42412210DCFD6E1CDFF5C06A3DC4D7010024897EEBF1E682B292_1648074761781_nextjs-app.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1251\"\/><\/p>\n<h1>Installing Cloudinary<\/h1>\n<p><a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> provides a rich media management experience enabling users to upload, store, manage, manipulate, and deliver images and videos for websites and applications.<\/p>\n<p>The <code>@cloudinary\/url-gen<\/code> package provides transformation and optimization functionalities and we\u2019ll use it to transform our project\u2019s image. Install the package with the code below:<\/p>\n<pre><code>npm i @cloudinary\/url-gen\n<\/code><\/pre>\n<p>With installations completed, we\u2019ll start the next application using the command below:<\/p>\n<pre><code>npm run dev\n<\/code><\/pre>\n<p>Once run, the command spins up a local development server which we can access on <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a>.<\/p>\n<h1>Setting Up Configurations<\/h1>\n<p>To begin, we would do some basic setup in our app to help build our gallery. First, we replace the contents in the <code>Home.module.css<\/code> file in the styles folder with the content below. These are styles we would be using throughout our app.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\">    <span class=\"hljs-selector-class\">.container<\/span> {\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">2rem<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.main<\/span> {\n      <span class=\"hljs-attribute\">min-height<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">4rem<\/span> <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">flex<\/span>: <span class=\"hljs-number\">1<\/span>;\n      <span class=\"hljs-attribute\">display<\/span>: flex;\n      <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n      <span class=\"hljs-attribute\">justify-content<\/span>: center;\n      <span class=\"hljs-attribute\">align-items<\/span>: center;\n    }\n    <span class=\"hljs-selector-class\">.title<\/span> <span class=\"hljs-selector-tag\">a<\/span> {\n      <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#0070f3<\/span>;\n      <span class=\"hljs-attribute\">text-decoration<\/span>: none;\n    }\n    <span class=\"hljs-selector-class\">.title<\/span> <span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span>,\n    <span class=\"hljs-selector-class\">.title<\/span> <span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-pseudo\">:focus<\/span>,\n    <span class=\"hljs-selector-class\">.title<\/span> <span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-pseudo\">:active<\/span> {\n      <span class=\"hljs-attribute\">text-decoration<\/span>: underline;\n    }\n    <span class=\"hljs-selector-class\">.title<\/span> {\n      <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">line-height<\/span>: <span class=\"hljs-number\">1.15<\/span>;\n      <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">4rem<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.title<\/span>,\n    <span class=\"hljs-selector-class\">.description<\/span> {\n      <span class=\"hljs-attribute\">text-align<\/span>: center;\n    }\n    <span class=\"hljs-selector-class\">.description<\/span> {\n      <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">4rem<\/span> <span class=\"hljs-number\">0<\/span>;\n      <span class=\"hljs-attribute\">line-height<\/span>: <span class=\"hljs-number\">1.5<\/span>;\n      <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">1.5rem<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.grid<\/span> {\n      <span class=\"hljs-attribute\">display<\/span>: flex;\n      <span class=\"hljs-attribute\">align-items<\/span>: center;\n      <span class=\"hljs-attribute\">justify-content<\/span>: center;\n      <span class=\"hljs-attribute\">flex-wrap<\/span>: wrap;\n      <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">1000px<\/span>;\n      <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">30px<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.card<\/span> {\n      <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0.5rem<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.5rem<\/span>;\n      <span class=\"hljs-attribute\">text-align<\/span>: left;\n      <span class=\"hljs-attribute\">color<\/span>: inherit;\n      <span class=\"hljs-attribute\">text-decoration<\/span>: none;\n      <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-number\">#676767<\/span>;\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">10px<\/span>;\n      <span class=\"hljs-attribute\">transition<\/span>: color <span class=\"hljs-number\">0.15s<\/span> ease, border-color <span class=\"hljs-number\">0.15s<\/span> ease;\n      <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">300px<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.card<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span>,\n    <span class=\"hljs-selector-class\">.card<\/span><span class=\"hljs-selector-pseudo\">:focus<\/span>,\n    <span class=\"hljs-selector-class\">.card<\/span><span class=\"hljs-selector-pseudo\">:active<\/span> {\n      <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#0070f3<\/span>;\n      <span class=\"hljs-attribute\">border-color<\/span>: <span class=\"hljs-number\">#0070f3<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.file<\/span><span class=\"hljs-selector-pseudo\">::-webkit-file-upload-button<\/span> {\n      <span class=\"hljs-attribute\">visibility<\/span>: hidden;\n    }\n    <span class=\"hljs-selector-class\">.file<\/span><span class=\"hljs-selector-pseudo\">::before<\/span> {\n      <span class=\"hljs-attribute\">content<\/span>: <span class=\"hljs-string\">'Select some files'<\/span>;\n      <span class=\"hljs-attribute\">display<\/span>: inline-block;\n      <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">linear-gradient<\/span>(to bottom, #f9f9f9, #e3e3e3);\n      <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-number\">#999<\/span>;\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">3px<\/span>;\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">5px<\/span> <span class=\"hljs-number\">8px<\/span>;\n      <span class=\"hljs-attribute\">outline<\/span>: none;\n      <span class=\"hljs-attribute\">white-space<\/span>: nowrap;\n      <span class=\"hljs-attribute\">-webkit-user-select<\/span>: none;\n      <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n      <span class=\"hljs-attribute\">text-shadow<\/span>: <span class=\"hljs-number\">1px<\/span> <span class=\"hljs-number\">1px<\/span> <span class=\"hljs-number\">#fff<\/span>;\n      <span class=\"hljs-attribute\">font-weight<\/span>: <span class=\"hljs-number\">700<\/span>;\n      <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">10pt<\/span>;\n    }\n    <span class=\"hljs-selector-class\">.file<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span><span class=\"hljs-selector-pseudo\">::before<\/span> {\n      <span class=\"hljs-attribute\">border-color<\/span>: black;\n    }\n    <span class=\"hljs-selector-class\">.file<\/span><span class=\"hljs-selector-pseudo\">:active<\/span><span class=\"hljs-selector-pseudo\">::before<\/span> {\n      <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">-webkit-linear-gradient<\/span>(top, #e3e3e3, #f9f9f9);\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\">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>After that, in the <code>next.config.js<\/code> file, we need to add Cloudinary as a domain to access remote images using the <code>next\/image<\/code> component.<\/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-comment\">\/** <span class=\"hljs-doctag\">@type <span class=\"hljs-type\">{import('next').NextConfig}<\/span> <\/span>*\/<\/span>\n    <span class=\"hljs-keyword\">const<\/span> nextConfig = {\n      ...\n      images: {\n        <span class=\"hljs-attr\">domains<\/span>: &#91;<span class=\"hljs-string\">'res.cloudinary.com'<\/span>],\n      },\n    };\n    <span class=\"hljs-built_in\">module<\/span>.exports = nextConfig;\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<h1>Building the Gallery<\/h1>\n<p>Now in the <code>index.js<\/code> file in the <code>pages<\/code> folder, replace the contents of the file with the code below:<\/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> { Cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> Head <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next\/head'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/styles\/Home.module.css'<\/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\">const<\/span> cld = <span class=\"hljs-keyword\">new<\/span> Cloudinary({\n        <span class=\"hljs-attr\">cloud<\/span>: {\n          <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">'chukwutosin'<\/span>,\n        },\n      });\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\">{styles.container}<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Image Gallery<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">'description'<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"Tosin's image gallery\"<\/span> \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.main}<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>Welcome to Tosin<span class=\"hljs-symbol\">&amp;apos;<\/span>s 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>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.file}<\/span>\n                <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">'file'<\/span>\n                <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">'uploadImages'<\/span>\n                <span class=\"hljs-attr\">multiple<\/span>\n              \/&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>\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>We first import the <code>Cloudinary<\/code> component, Next.js <code>Head<\/code> component, and our <code>CSS<\/code> styles in this file.<\/p>\n<p>Then we create a Cloudinary instance with our <code>cloudName<\/code>, obtained from our Cloudinary <a href=\"https:\/\/cloudinary.com\/console\/c-44312a85dae383cdb3fedab809bc64\">dashboard<\/a>. We make a basic HTML setup with an input field to upload multiple images to our gallery.<\/p>\n<h2>Upload Images to Cloudinary<\/h2>\n<p>Before we can upload images to Cloudinary from our Next.js app, Cloudinary requires us to have an upload preset. The <code>upload_preset<\/code> allows us to define a set of asset upload choices centrally rather than providing them in each upload call.<\/p>\n<p>We can find our upload preset in the Upload tab of our Cloudinary settings page by clicking on the gear icon in the top right corner of the dashboard page.<\/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_4B2ADD3FEB8D8E1F33E2260860C62FB74C629B51D38EF19C3CBB685E1CC815E6_1658093368939_upload+preset+cloudinary.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"556\"\/><\/p>\n<p>By scrolling down to the bottom of the page to the upload presets section, we\u2019ll see our upload preset, or there will be an option to create one if we don\u2019t have any.<\/p>\n<p>Now that we have gotten our upload preset, we will create a function to handle image upload and transformation.<\/p>\n<h2>Handling Image Upload and Transformation<\/h2>\n<p>First, we will create a function called <code>handleOnSubmit<\/code> that would take in an <code>event<\/code>. We then take all the images from the event target and append our upload preset on each as we upload to Cloudinary.<\/p>\n<p>Cloudinary sends back a <code>public_id<\/code> to access the image after uploading each image. We then perform the watermark transformation. Our watermark text is \u201c<strong>This is my image.<\/strong>\u201d. When the image transformation is complete, the function returns the URL of the transformed image. Then we save the URL using <code>useState<\/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-keyword\">import<\/span> { Cloudinary, Transformation } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { opacity } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/actions\/adjust'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { source } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/actions\/overlay'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { Position } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/qualifiers'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { compass } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/qualifiers\/gravity'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { text } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/qualifiers\/source'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { TextStyle } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@cloudinary\/url-gen\/qualifiers\/textStyle'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> Head <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next\/head'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> Image <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next\/image'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/styles\/Home.module.css'<\/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\">const<\/span> &#91;imageSrc, setImageSrc] = useState(&#91;]);\n    \n      <span class=\"hljs-keyword\">const<\/span> cld = <span class=\"hljs-keyword\">new<\/span> Cloudinary({\n        <span class=\"hljs-attr\">cloud<\/span>: {\n          <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">'chukwutosin'<\/span>,\n        },\n      });\n    \n      <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleOnSubmit<\/span>(<span class=\"hljs-params\">event<\/span>) <\/span>{\n        event.preventDefault();\n    \n        <span class=\"hljs-keyword\">const<\/span> images = event.target.files;\n        <span class=\"hljs-keyword\">let<\/span> imgArray = &#91;];\n    \n        <span class=\"hljs-keyword\">if<\/span> (images) {\n          <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> image <span class=\"hljs-keyword\">of<\/span> images) {\n            <span class=\"hljs-keyword\">const<\/span> body = <span class=\"hljs-keyword\">new<\/span> FormData();\n            body.append(<span class=\"hljs-string\">'upload_preset'<\/span>, &lt;upload_preset&gt;);\n            body.append(<span class=\"hljs-string\">'file'<\/span>, image);\n            <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(\n              <span class=\"hljs-string\">'https:\/\/api.cloudinary.com\/v1_1\/&lt;cloud_name&gt;\/image\/upload'<\/span>,\n              {\n                <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'POST'<\/span>,\n                body,\n              }\n            ).then(<span class=\"hljs-function\">(<span class=\"hljs-params\">r<\/span>) =&gt;<\/span> r.json());\n    \n            <span class=\"hljs-keyword\">const<\/span> myImage = cld.image(response.public_id);\n    \n            myImage\n              .overlay(\n                source(\n                  text(<span class=\"hljs-string\">'This is my picture'<\/span>, <span class=\"hljs-keyword\">new<\/span> TextStyle(<span class=\"hljs-string\">'arial'<\/span>, <span class=\"hljs-number\">200<\/span>))\n                    .textColor(<span class=\"hljs-string\">'white'<\/span>)\n                    .transformation(<span class=\"hljs-keyword\">new<\/span> Transformation().adjust(opacity(<span class=\"hljs-number\">60<\/span>)))\n                ).position(<span class=\"hljs-keyword\">new<\/span> Position().gravity(compass(<span class=\"hljs-string\">'center'<\/span>)).offsetY(<span class=\"hljs-number\">20<\/span>))\n              )\n              .format(<span class=\"hljs-string\">'png'<\/span>);\n            <span class=\"hljs-keyword\">const<\/span> myUrl = myImage.toURL();\n            imgArray.push(myUrl);\n          }\n          setImageSrc(imgArray);\n        }\n      }\n      ...\n    }\n    \n<span class=\"hljs-string\">``<\/span><span class=\"hljs-string\">`js\n\n## Displaying the Images\n\nNow that we have the transformed images stored in our state variable, let\u2019s display them.\n\nFirst, let's add an `<\/span>onChange<span class=\"hljs-string\">` handler to the input field. This will automatically call `<\/span>handleOnSubmit<span class=\"hljs-string\">` when we select our images and upload them immediately. \n\nAfter that, we check if the `<\/span>imageSrc<span class=\"hljs-string\">` variable has a value to display the images or not. We use the Next.js `<\/span>Image<span class=\"hljs-string\">` component to display the images.\n\nUpdate the `<\/span><span class=\"hljs-keyword\">return<\/span><span class=\"hljs-string\">` statement in the `<\/span>index.js<span class=\"hljs-string\">` file with the code below.\n\n`<\/span><span class=\"hljs-string\">``<\/span>js\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\">{styles.container}<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Image Gallery<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">'description'<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"Tosin's image gallery\"<\/span> \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Head<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.main}<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>Welcome to Tosin<span class=\"hljs-symbol\">&amp;apos;<\/span>s 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>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.file}<\/span>\n                <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">'file'<\/span>\n                <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">'uploadImages'<\/span>\n                <span class=\"hljs-attr\">multiple<\/span>\n                <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{handleOnSubmit}<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    \n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.grid}<\/span>&gt;<\/span>\n              {imageSrc.length &gt; 0\n                ? imageSrc.map((img, i) =&gt; {\n                    return (\n                      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{i}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.card}<\/span>&gt;<\/span>\n                        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{img}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{img}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{300}<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{300}<\/span> \/&gt;<\/span>\n                      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                    );\n                  })\n                : ''}\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>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\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<h1>Running the App<\/h1>\n<p>Now that we have finished setup, we\u2019ll start up our app, and we should see our app like so:<\/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_4B2ADD3FEB8D8E1F33E2260860C62FB74C629B51D38EF19C3CBB685E1CC815E6_1658182384107_Screenshot+2022-07-18+at+23.11.10.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1250\"\/><\/p>\n<p>We\u2019ll click the button <code>'Select some file'<\/code> to upload our images, and then our gallery will pop up as so<\/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_4B2ADD3FEB8D8E1F33E2260860C62FB74C629B51D38EF19C3CBB685E1CC815E6_1658182504578_Screenshot+2022-07-18+at+00.02.19.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1250\"\/><\/p>\n<p><strong>Note:<\/strong> if nothing shows up immediately after the images are selected, wait a bit. The delay is because of the image upload and transformation. Depending on the image size, it might take a few seconds. In the real world, we should put a loader to show the user that their operation is processing.<\/p>\n<h1>Conclusion<\/h1>\n<p>This article taught us how to add watermark transformations to our images using Cloudinary.<\/p>\n<h1>Resources<\/h1>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations#landingpage\">Cloudinary Image transformation<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/layers\">Cloudinary layers documentation<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/nextjs.org\/docs\/getting-started\">Next.js documentation<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27734,"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-27733","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>Automatically Watermark an Image Gallery on Upload<\/title>\n<meta name=\"description\" content=\"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.\" \/>\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\/automatically-watermark-image-gallery-on-upload\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automatically Watermark an Image Gallery on Upload\" \/>\n<meta property=\"og:description\" content=\"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-15T16:36:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-22T23:47:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1-png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1440\" \/>\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\/automatically-watermark-image-gallery-on-upload\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Automatically Watermark an Image Gallery on Upload\",\"datePublished\":\"2022-08-15T16:36:29+00:00\",\"dateModified\":\"2025-02-22T23:47:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_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\/automatically-watermark-image-gallery-on-upload\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/\",\"name\":\"Automatically Watermark an Image Gallery on Upload\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA\",\"datePublished\":\"2022-08-15T16:36:29+00:00\",\"dateModified\":\"2025-02-22T23:47:21+00:00\",\"description\":\"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA\",\"width\":2560,\"height\":1440},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automatically Watermark an Image Gallery on Upload\"}]},{\"@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":"Automatically Watermark an Image Gallery on Upload","description":"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.","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\/automatically-watermark-image-gallery-on-upload\/","og_locale":"en_US","og_type":"article","og_title":"Automatically Watermark an Image Gallery on Upload","og_description":"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-08-15T16:36:29+00:00","article_modified_time":"2025-02-22T23:47:21+00:00","og_image":[{"width":2560,"height":1440,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1-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\/automatically-watermark-image-gallery-on-upload\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/"},"author":{"name":"","@id":""},"headline":"Automatically Watermark an Image Gallery on Upload","datePublished":"2022-08-15T16:36:29+00:00","dateModified":"2025-02-22T23:47:21+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_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\/automatically-watermark-image-gallery-on-upload\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/","name":"Automatically Watermark an Image Gallery on Upload","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA","datePublished":"2022-08-15T16:36:29+00:00","dateModified":"2025-02-22T23:47:21+00:00","description":"A watermark is a logo, text, or pattern intentionally put onto another image to prevent images from being copied or used without permission. In this article, we will learn how to add watermarks to our images using Cloudinary in our Next.js apps.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA","width":2560,"height":1440},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/automatically-watermark-image-gallery-on-upload\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Automatically Watermark an Image Gallery on Upload"}]},{"@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\/v1681921020\/Web_Assets\/blog\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1\/fad800ef341e8089a0bf700f64ad66556f4b7fbc-2560x1440-1_27734399c1.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27733","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=27733"}],"version-history":[{"count":4,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27733\/revisions"}],"predecessor-version":[{"id":36969,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27733\/revisions\/36969"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27734"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}