{"id":28451,"date":"2021-05-18T22:01:13","date_gmt":"2021-05-18T22:01:13","guid":{"rendered":"http:\/\/How-To-Upload-Images-in-Sapper-With-Drag-and-Drop"},"modified":"2021-05-18T22:01:13","modified_gmt":"2021-05-18T22:01:13","slug":"how-to-upload-images-in-sapper-with-drag-and-drop","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/","title":{"rendered":"How To Upload Images in Sapper With Drag and Drop"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.<\/p>\n<p>If you want to jump right into the code, check out the <a href=\"https:\/\/github.com\/lelouchB\/sapper-cloudinary-upload\">GitHub Repo here<\/a>.<\/p>\n<h2>Sandbox<\/h2>\n<p>Before we get started, I wanted to point out that you can play around with the code described in this Jam on <a href=\"https:\/\/codesandbox.io\/s\/sapper-cloudinary-upload-qkd2b?file=\/src\/routes\/index.svelte\">CodeSandbox<\/a>, and you can find the live version <a href=\"https:\/\/qkd2b-3000.sse.codesandbox.io\/\">here<\/a>.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/sapper-cloudinary-upload-qkd2b?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=\"sapper-cloudinary-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  <div class=\"wp-block-cloudinary-markdown \"><h2>How To Setup and Install a Sapper Project<\/h2>\n<p>In your project\u2019s root directory, run the following commands in the terminal to quickly set up the initial Sapper project using the <code>sapper-template<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">npx degit <span class=\"hljs-string\">\"sveltejs\/sapper-template#webpack\"<\/span> sapper-cloudinary-example\ncd sapper-cloudinary-example\nnpm install\nnpm run dev\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 last command will start the Sapper development server on <a href=\"http:\/\/localhost:3000\/\">http:\/\/localhost:3000\/<\/a>.<\/p>\n<p>Head over to your Cloudinary dashboard and copy the API keys.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1621239219\/e-603fc45fe6c0b4006873802f\/evhdnpjtzqivu9aqzxbf.png\" alt=\"Cloudinary Dashboard API Keys\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1330\" height=\"385\"\/><\/p>\n<p>Create a new file named <code>.env<\/code> in your project\u2019s root directory and paste the API keys in it, as shown below.<\/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\">CLOUDINARY_CLOUD=<span class=\"hljs-string\">''<\/span>\nCLOUDINARY_KEY= <span class=\"hljs-string\">''<\/span>\nCLOUDINARY_SECRET=<span class=\"hljs-string\">''<\/span> \n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">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>To use these environment variables, you will also need to install the <code>dotenv<\/code> package.<\/p>\n<p>Run the following command to install <code>dotenv<\/code> and <code>cloudinary<\/code> libraries where <code>cloudinary<\/code> is the Node.js\/server-side SDK you will use to upload the images to Cloudinary.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm i dotenv cloudinary\n<\/code><\/span><\/pre>\n<h2>How To Display Images on the App<\/h2>\n<p>The first step is to build the image gallery where you will display all the uploaded images. Create a new file named <code>index.json.js<\/code> inside the <code>src<\/code> directory, where you will create the <a href=\"https:\/\/sapper.svelte.dev\/docs#Server_routes\">server route<\/a> to fetch the images from Cloudinary.<\/p>\n<p>Server routes in Sapper are used to create JSON API, which exports functions,  having HTTP <code>request<\/code> and <code>response<\/code> objects as arguments, corresponding to HTTP methods like <code>GET<\/code>, <code>POST<\/code>, etc.<\/p>\n<p>You can create both the <code>GET<\/code> method to fetch the images and the <code>POST<\/code> method to upload the image inside the same <code>index.json.js<\/code> file, and Sapper will differentiate between them based on the type of request made.<\/p>\n<p>Run the following command to create the <code>index.json.js<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">touch src\/routes\/index.json.js\n<\/code><\/span><\/pre>\n<p>Add the following code to <code>index.json.js<\/code>.<\/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-built_in\">require<\/span>(<span class=\"hljs-string\">\"dotenv\"<\/span>).config();\n<span class=\"hljs-keyword\">const<\/span> cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\n\ncloudinary.config({\n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUDINARY_CLOUD,\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.CLOUDINARY_KEY,\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.CLOUDINARY_SECRET,\n});\n\n<span class=\"hljs-keyword\">export<\/span>  <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">get<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  res.writeHead(<span class=\"hljs-number\">200<\/span>, {\n    <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n  });\n\n  <span class=\"hljs-keyword\">let<\/span> secureUrls;\n\n   cloudinary.api.resources({<span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'upload'<\/span>}, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">error, result<\/span>) <\/span>{\n    secureUrls = <span class=\"hljs-built_in\">JSON<\/span>.stringify(\n      result.resources.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">pic<\/span>) =&gt;<\/span> {\n        <span class=\"hljs-keyword\">return<\/span> { <span class=\"hljs-attr\">secureUrl<\/span>: pic.secure_url };\n      })\n    );\n\n    res.end(secureUrls);\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>In the above code, you first access the environment variables using <code>require(&quot;dotenv&quot;).config();<\/code> and pass them to <code>cloudinary<\/code>. Then, you create and export the <code>get<\/code> function where the images are fetched from Cloudinary using <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#get_resources\">Cloudinary\u2019s Admin API<\/a>.<\/p>\n<p>The image URLs are sent as a JSON response to the <code>GET<\/code> request. These URLs are then used within the <code>src<\/code> attribute of the <code>img<\/code> tag to display the images on the app.<\/p>\n<p>Update the <code>src\/routes\/index.svelte<\/code> file 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\">script<\/span> <span class=\"hljs-attr\">context<\/span>=<span class=\"hljs-string\">\"module\"<\/span>&gt;<\/span><span class=\"javascript\">\n\t<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">preload<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">this<\/span>.fetch(<span class=\"hljs-string\">`\/index.json`<\/span>)\n\t\t.then(<span class=\"hljs-function\">(<span class=\"hljs-params\">r<\/span>) =&gt;<\/span> r.json())\n\t\t.then(<span class=\"hljs-function\">(<span class=\"hljs-params\">images<\/span>) =&gt;<\/span> {\n\t\t  <span class=\"hljs-keyword\">return<\/span> { images };\n\t\t});\n\t}\n  <\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n  \n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n\t<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">let<\/span> images;\n  <\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n  \n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">svelte:head<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Sapper Cloudinary Example<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">svelte:head<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>Sapper Image Gallery<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n\t{#each images as image (image.secureUrl)}\n\t  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"image\"<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{image.secureUrl}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{image.secureUrl}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"400px\"<\/span> \/&gt;<\/span>\n\t  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n\t{\/each}\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\">style<\/span>&gt;<\/span><span class=\"css\">\n\t<span class=\"hljs-selector-tag\">h2<\/span> {\n\t  <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">2.4em<\/span>;\n\t  <span class=\"hljs-attribute\">text-transform<\/span>: uppercase;\n\t  <span class=\"hljs-attribute\">font-weight<\/span>: <span class=\"hljs-number\">400<\/span>;\n\t  <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0.5em<\/span> <span class=\"hljs-number\">0<\/span>;\n\t  <span class=\"hljs-attribute\">text-align<\/span>: center;\n\t}\n\n<span class=\"hljs-selector-class\">.container<\/span> {\n    <span class=\"hljs-attribute\">column-count<\/span>: <span class=\"hljs-number\">3<\/span>;\n    <span class=\"hljs-attribute\">column-gap<\/span>: <span class=\"hljs-number\">20px<\/span>;\n  }\n  <span class=\"hljs-selector-tag\">section<\/span> &gt; <span class=\"hljs-selector-tag\">img<\/span> {\n    <span class=\"hljs-attribute\">flex<\/span>: <span class=\"hljs-number\">100%<\/span>;\n    <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n    <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n    <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">10px<\/span>;\n  }\n  <span class=\"hljs-selector-class\">.image<\/span> {\n    <span class=\"hljs-attribute\">margin-bottom<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n  }\n\n  <span class=\"hljs-keyword\">@media<\/span> <span class=\"hljs-keyword\">only<\/span> screen <span class=\"hljs-keyword\">and<\/span> (<span class=\"hljs-attribute\">max-width:<\/span> <span class=\"hljs-number\">600px<\/span>) {\n    <span class=\"hljs-selector-class\">.container<\/span> {\n      <span class=\"hljs-attribute\">column-count<\/span>: <span class=\"hljs-number\">1<\/span>;\n    }\n  }\n  <\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/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>You use <a href=\"https:\/\/sapper.svelte.dev\/docs#Preloading\">Sapper\u2019s preload()<\/a> function to fetch the images using <code>this.fetch()<\/code> method. This <code>preload()<\/code> function runs before the component is created and loads the data, i.e., images required by the gallery before the page is loaded.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">context<\/span>=<span class=\"hljs-string\">\"module\"<\/span>&gt;<\/span><span class=\"javascript\">\n  <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">preload<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">this<\/span>.fetch(<span class=\"hljs-string\">`\/index.json`<\/span>)\n      .then(<span class=\"hljs-function\">(<span class=\"hljs-params\">r<\/span>) =&gt;<\/span> r.json())\n      .then(<span class=\"hljs-function\">(<span class=\"hljs-params\">images<\/span>) =&gt;<\/span> {\n        <span class=\"hljs-keyword\">return<\/span> { images };\n      });\n  }\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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>To display the images, you iterate over the <code>images<\/code> array, exported from the <code>script<\/code> tag, using the <code>each<\/code> block. You can read more about <code>each<\/code> block <a href=\"https:\/\/svelte.dev\/docs#each\">here<\/a>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">{#each images as image (image.secureUrl)}\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"image\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"{image.secureUrl}\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"{image.secureUrl}\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"400px\"<\/span> \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n{\/each}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>Here is how this <strong>Sapper Image Gallery<\/strong> looks like.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1621239300\/e-603fc45fe6c0b4006873802f\/onjk3hxkycaunx7djy2b.png\" alt=\"Sapper Image Gallery\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1536\" height=\"727\"\/><\/p>\n<h2>How To Upload Images to Cloudinary<\/h2>\n<p>In this section, we will write the code to upload the image to Cloudinary and then show it in the Image Gallery created in the last section.<\/p>\n<p>Update the <code>script<\/code> tag in <code>index.svelte<\/code> file like this.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n  <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">let<\/span> images;\n  <span class=\"hljs-keyword\">let<\/span> preview, fileinput;\n\n  <span class=\"hljs-keyword\">const<\/span> onFileSelected = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">let<\/span> image = e.files&#91;<span class=\"hljs-number\">0<\/span>];\n    <span class=\"hljs-keyword\">let<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n    reader.readAsDataURL(image);\n    reader.onload = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n      preview = e.target.result;\n    };\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> uploadImage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    uploadImageToCloudinary(preview);\n  };\n\n  <span class=\"hljs-keyword\">const<\/span> uploadImageToCloudinary = <span class=\"hljs-keyword\">async<\/span> (imageDataUrl) =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">\"\/index.json\"<\/span>, {\n      <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n      },\n      <span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({ imageDataUrl }),\n    });\n    <span class=\"hljs-keyword\">const<\/span> json = <span class=\"hljs-keyword\">await<\/span> res.json();\n    <span class=\"hljs-keyword\">if<\/span> (json.imageUrl) {\n      <span class=\"hljs-built_in\">window<\/span>.location.reload();\n    }\n  };\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Before uploading the image to Cloudinary, the web application needs to read the selected picture; this is done with the help of <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileReader\">FileReader Web API<\/a>.<\/p>\n<p>The <code>files<\/code> object containing the selected file, obtained either from the <code>FileList<\/code> object when the user selects a file using the <code>&lt;input&gt;<\/code> element or drag and drop operations\u2019 <code>DataTransfer<\/code> object is passed to the <code>FileReader<\/code> Web API. In this project, you will use both the <code>&lt;input&gt;<\/code> element and drag and drop operation.<\/p>\n<p>The <code>FileReader<\/code> Web API reads the user\u2019s selected file and then converts it to a <code>data:<\/code> URL using the <code>.readAsDataURL()<\/code> method. You can read more about this method <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileReader\/readAsDataURL\">here<\/a>.<\/p>\n<p>Using the <code>.onload()<\/code> method of <code>FileReader,<\/code> triggered each time the reading operation is successfully completed, the <code>data:<\/code> URL is stored inside the <code>preview<\/code> variable.<\/p>\n<p>You have created another function named <code>uploadImageToCloudinary ()<\/code> which takes the data URL as an argument and makes a <code>POST<\/code> request to <code>\/index.json<\/code> using the <code>fetch<\/code> API. The data URL is sent to the server route as a JSON object.<\/p>\n<p>Once the image has been uploaded, and a successful response is returned from the POST request, the entire page is reloaded to trigger the Sapper\u2019s <code>preload()<\/code> function to update the Image Gallery with the newly uploaded image.<\/p>\n<p>Add the code for the Upload component before the code for Image Gallery in the <code>index.svelte<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" 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\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"app\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>Upload Image<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>\n    <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"dropzone\"<\/span>\n    <span class=\"hljs-attr\">on:click<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n      fileinput.click();\n    }}\n    on:drop={(e) =&gt; {\n      e.preventDefault();\n      onFileSelected(e.dataTransfer);\n    }}\n    on:dragenter={(e) =&gt; {\n      e.preventDefault();\n    }}\n    on:dragleave={(e) =&gt; {\n      e.preventDefault();\n    }}\n    on:dragover={(e) =&gt; {\n      e.preventDefault();\n    }}\n  &gt;\n    {#if preview}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"preview\"<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{preview}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"preview\"<\/span> \/&gt;<\/span>\n    {\/if}\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span>\n      <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"upload-icon\"<\/span>\n      <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/static.thenounproject.com\/png\/625182-200.png\"<\/span>\n      <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\"<\/span>\n      <span class=\"hljs-attr\">on:click<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n        fileinput.click();\n      }}\n    \/&gt;\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n      <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"display:none\"<\/span>\n      <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span>\n      <span class=\"hljs-attr\">accept<\/span>=<span class=\"hljs-string\">\".jpg, .jpeg, .png\"<\/span>\n      <span class=\"hljs-attr\">on:change<\/span>=<span class=\"hljs-string\">{(e)<\/span> =&gt;<\/span> onFileSelected(e.target)}\n      bind:this={fileinput}\n    \/&gt;\n    {#if !preview}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>\n        <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"chan\"<\/span>\n        <span class=\"hljs-attr\">on:click<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n          fileinput.click();\n        }}\n      &gt;\n        Drag N Drop Images or Click on Upload.\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    {\/if}\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  {#if preview}\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n      <span class=\"hljs-attr\">on:click<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> {\n        uploadImage();\n      }}&gt;Upload Image<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>\n    &gt;<\/span>\n  {\/if}\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>You can refer to the code to style the Upload component <a href=\"https:\/\/github.com\/lelouchB\/sapper-cloudinary-upload\/blob\/4207d0cbdf28f5b620f676b5d57e0ee6db97000a\/src\/routes\/index.svelte#L119\">here<\/a>.<\/p>\n<p>In the above code, you create a <code>div<\/code> element with <code>class=&quot;app&quot;<\/code>. In this <code>div<\/code> element, you add the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/DragEvent\">event handlers<\/a> required for the drag and drop operation. The <code>on:dragenter<\/code>, <code>on:dragover<\/code>, and <code>on:dragover<\/code> event just the page from reloading. The <code>on:drop()<\/code> event, triggered when the file is dropped on the <code>div<\/code>,  passes the <code>DataTransfer<\/code> object to the <code>onSelectedFile()<\/code> function.<\/p>\n<p>You bind the <code>fileinput<\/code> variable to the <code>input<\/code> element to get a reference to the <code>input<\/code> element. This <code>input<\/code> element only accepts <code>.jpg, .jpeg, .png<\/code> image types. You can change the accepted image types according to your application needs.<\/p>\n<p>When the upload icon is clicked, the <code>on:click()<\/code> event is triggered, which runs the <code>fileinput.click()<\/code> function and the user is prompted to select the image.<\/p>\n<p>After the user has selected the image, the <code>on:change()<\/code> event of the <code>input<\/code> element is triggered, which passes the <code>FileList<\/code> object to the <code>onSelectedFile()<\/code> function.<\/p>\n<p>Whether an image is selected or not, either the Upload button is displayed or the text <code>Drag N Drop Images or Click on Upload.<\/code> is shown using the <code>if<\/code> block and <code>preview<\/code> variable.<\/p>\n<p>Here is how the Upload Component looks when no file is selected.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1621239336\/e-603fc45fe6c0b4006873802f\/xuksmzncadhbbjxb1pgj.png\" alt=\"No File Selected\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1898\" height=\"908\"\/><\/p>\n<p>Here is how the Upload Component changes if an image is selected.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1621239374\/e-603fc45fe6c0b4006873802f\/nigapymgkefkldxwr0g9.png\" alt=\"File Selected\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1898\" height=\"908\"\/><\/p>\n<p>When the upload button is clicked, the <code>uploadImage()<\/code> function sends the POST request to the <code>\/index.json<\/code> server route with the data URL of the image in the request body, and the image is uploaded to Cloudinary.<\/p>\n<p>In the above code, you are sending the image data URL as a JSON request body.  To parse this JSON request body in the <code>POST<\/code> request, you will need to install the <code>body-parser<\/code> package. You can read more about this library <a href=\"https:\/\/www.npmjs.com\/package\/body-parser\">here<\/a>.<\/p>\n<p>Run the following command in your terminal to install <code>body-parser<\/code>.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install body-parser\n<\/code><\/span><\/pre>\n<p>You will also need to update the <code>src\/server.js<\/code> file to include the <code>body-parser<\/code> library.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" 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> sirv <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"sirv\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> polka <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"polka\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> compression <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"compression\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> * <span class=\"hljs-keyword\">as<\/span> sapper <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@sapper\/server\"<\/span>;\n<span class=\"hljs-keyword\">const<\/span> bodyParser = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"body-parser\"<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> { PORT, NODE_ENV } = process.env;\n<span class=\"hljs-keyword\">const<\/span> dev = NODE_ENV === <span class=\"hljs-string\">\"development\"<\/span>;\n\npolka() <span class=\"hljs-comment\">\/\/ You can also use Express<\/span>\n  .use(\n    bodyParser.json({\n      <span class=\"hljs-attr\">limit<\/span>: <span class=\"hljs-string\">\"50mb\"<\/span>,\n      <span class=\"hljs-attr\">extended<\/span>: <span class=\"hljs-literal\">true<\/span>,\n    }),\n    bodyParser.urlencoded({\n      <span class=\"hljs-attr\">limit<\/span>: <span class=\"hljs-string\">\"50mb\"<\/span>,\n      <span class=\"hljs-attr\">extended<\/span>: <span class=\"hljs-literal\">true<\/span>,\n    }),\n\n    compression({ <span class=\"hljs-attr\">threshold<\/span>: <span class=\"hljs-number\">0<\/span> }),\n    sirv(<span class=\"hljs-string\">\"static\"<\/span>, { dev }),\n    sapper.middleware()\n  )\n  .listen(PORT, (err) =&gt; {\n    <span class=\"hljs-keyword\">if<\/span> (err) <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"error\"<\/span>, err);\n  });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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 last step is to create the <code>POST<\/code> method in the <code>index.json.js<\/code> file or the <code>\/index.json<\/code> server route.<\/p>\n<p>Add the following code for the <code>POST<\/code> method in the <code>index.json.js<\/code>  file.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">post<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> image = req.body.imageDataUrl;\n\n  res.writeHead(<span class=\"hljs-number\">200<\/span>, {\n    <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n  });\n\n  cloudinary.uploader.upload(image).then(<span class=\"hljs-function\">(<span class=\"hljs-params\">response<\/span>) =&gt;<\/span> {\n    res.end(<span class=\"hljs-built_in\">JSON<\/span>.stringify({ <span class=\"hljs-attr\">imageUrl<\/span>: response.secure_url }));\n  });\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above code uses <a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference\">Cloudinary\u2019s Upload API<\/a> to upload the image to Cloudinary. After a successful response, the Cloudinary URL of the image is returned as a JSON response.<\/p>\n<p>You can also pass additional and optional parameters to the Upload API like the <code>upload_preset<\/code>, <code>signature<\/code>, <code>folder<\/code>, etc.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1621239430\/e-603fc45fe6c0b4006873802f\/nuynimvucco95ofl6quk.gif\" alt=\"Demo Uploading Image GIF\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1280\" height=\"720\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>In this Media Jam, we discussed how to build an Image Gallery in Sapper with images being fetched from Cloudinary. We also saw how to upload images to Cloudinary using both the <code>&lt;input&gt;<\/code> element and drag and drop operation.<\/p>\n<p>Here are some additional resources that can be helpful:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/sapper.svelte.dev\/docs#Introduction\">Sapper Official Docs<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference\">Cloudinary Docs<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTML_Drag_and_Drop_API\">HTML Drag and Drop API<\/a>\n<\/li>\n<\/ul>\n<p>Happy coding!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28452,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,376,371,373],"class_list":["post-28451","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-svelte","tag-under-review","tag-upload"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How To Upload Images in Sapper With Drag and Drop<\/title>\n<meta name=\"description\" content=\"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.\" \/>\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\/how-to-upload-images-in-sapper-with-drag-and-drop\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How To Upload Images in Sapper With Drag and Drop\" \/>\n<meta property=\"og:description\" content=\"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-05-18T22:01:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\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\/how-to-upload-images-in-sapper-with-drag-and-drop\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How To Upload Images in Sapper With Drag and Drop\",\"datePublished\":\"2021-05-18T22:01:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\"},\"wordCount\":10,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Svelte\",\"Under Review\",\"Upload\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\",\"name\":\"How To Upload Images in Sapper With Drag and Drop\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA\",\"datePublished\":\"2021-05-18T22:01:13+00:00\",\"description\":\"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA\",\"width\":1920,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How To Upload Images in Sapper With Drag and Drop\"}]},{\"@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":"How To Upload Images in Sapper With Drag and Drop","description":"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.","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\/how-to-upload-images-in-sapper-with-drag-and-drop\/","og_locale":"en_US","og_type":"article","og_title":"How To Upload Images in Sapper With Drag and Drop","og_description":"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-05-18T22:01:13+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.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\/how-to-upload-images-in-sapper-with-drag-and-drop\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/"},"author":{"name":"","@id":""},"headline":"How To Upload Images in Sapper With Drag and Drop","datePublished":"2021-05-18T22:01:13+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/"},"wordCount":10,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA","keywords":["Guest Post","Image","Svelte","Under Review","Upload"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/","name":"How To Upload Images in Sapper With Drag and Drop","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA","datePublished":"2021-05-18T22:01:13+00:00","description":"In this Media Jam, we will discuss how to build an Image Gallery in Sapper with Cloudinary and upload images to Cloudinary with drag and drop operation.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA","width":1920,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-upload-images-in-sapper-with-drag-and-drop\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How To Upload Images in Sapper With Drag and Drop"}]},{"@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\/v1681924502\/Web_Assets\/blog\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876\/b5276ff4e39188e195230dc9b4fc4dd8f9a1ae47-1920x1080-1_2845273876.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28451","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=28451"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28451\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28452"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28451"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28451"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}