{"id":28007,"date":"2022-03-23T22:36:51","date_gmt":"2022-03-23T22:36:51","guid":{"rendered":"http:\/\/Edit-green-screen-videos-using-cloudinary-and-Sveltekit"},"modified":"2022-03-23T22:36:51","modified_gmt":"2022-03-23T22:36:51","slug":"edit-green-screen-videos-using-cloudinary-and-sveltekit","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/","title":{"rendered":"Edit Green Screen Videos"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><h2>Introduction<\/h2>\n<p>Have you ever watched one of those programming videos where the person\u2019s face is overlayed over their computer screen? That\u2019s made possible using green screens. They\u2019re widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won\u2019t go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out <a href=\"https:\/\/www.youtube.com\/watch?v=DAT3epRBNVI&amp;t=231s\">this video<\/a> or <a href=\"https:\/\/www.youtube.com\/watch?v=ava4Z3sJMLk&amp;t=153s\">this one<\/a>. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial we\u2019ll be using <a href=\"https:\/\/cloudinary.com\/?ap=em\">Cloudinary<\/a> and <a href=\"https:\/\/kit.svelte.dev\/\">SvelteKit<\/a>. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.<\/p>\n<h2>Codesandbox<\/h2>\n<p>The final project can be viewed on <a href=\"https:\/\/codesandbox.io\/s\/green-screen-videos-with-cloudinary-4h9tt\">Codesandbox<\/a>.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/green-screen-videos-with-cloudinary-4h9tt?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=\"green-screen-videos-with-cloudinary\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><p>You can find the full source code on my <a href=\"https:\/\/github.com\/musebe\/Green-Screen-Videos-With-Cloudinary.git\">Github<\/a> repository.<\/p>\n<h2>Prerequisites and setup<\/h2>\n<p>Before moving on further, it\u2019s important to note that working knowledge of Javascript is required for this tutorial. In addition to that, familiarity with <a href=\"https:\/\/svelte.dev\/\">Svelte<\/a> and <a href=\"https:\/\/kit.svelte.dev\/\">SvelteKit<\/a> is recommended although not necessary. You can easily pick up the concepts. You also need to have Node.js and NPM installed on your development environment<\/p>\n<blockquote>\n<p>DISCLAIMER: Svelte and more specifically SvelteKit, is at a very early stage and a few features are missing or require workarounds. Some notable features include file upload and loading environment variables during SSR or in the endpoint routes. You can check out <a href=\"https:\/\/github.com\/sveltejs\/kit\/issues\/70\">this<\/a> and <a href=\"https:\/\/github.com\/vitejs\/vite\/issues\/3176\">this<\/a> issues for more information and insight.<\/p>\n<\/blockquote>\n<p>Let\u2019s first create a new [SvelteKit] project. Run the following command in your terminal<\/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\">npm init svelte@next green-screen-videos-<span class=\"hljs-keyword\">with<\/span>-cloudinary\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>You\u2019ll be prompted for a few more options and then the CLI will scaffold a SvelteKit starter project for you. If you want to use the same options that I did, choose <strong>Skeleton project<\/strong> template, <strong>No<\/strong> for typescript, <strong>Yes<\/strong> for ESLint, <strong>Yes<\/strong> for Prettier. Follow the steps on the terminal to change the directory into your new project and install dependencies. Finally, open the project in your favorite code editor.<\/p>\n<h3>Cloudinary API Keys<\/h3>\n<p>Cloudinary offers APIs for upload of media, optimization, transformation, and delivery of uploaded media. We need API keys to communicate with their API. Luckily, you can easily get started with a free account. Please note that resources for a free account are limited, so use the API sparingly. Create a new <a href=\"https:\/\/cloudinary.com\/?ap=em\">cloudinary<\/a> account if you do not already have one and log in. Navigate to the <a href=\"https:\/\/cloudinary.com\/console?ap=em\">console page<\/a>. Here you\u2019ll find the <code>Cloud name<\/code>, <code>API Key<\/code>, and <code>API Secret<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/hackit-africa\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1623006780\/cloudinary-dashboard.png\" alt=\"Cloudinary Dashboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1537\" height=\"255\"\/><\/p>\n<p>Create a new file named <code>.env.local<\/code> at the root of your project and paste the following code inside.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">VITE_CLOUDINARY_CLOUD_NAME=YOUR_CLOUD_NAME\nVITE_CLOUDINARY_API_KEY=YOUR_API_KEY\nVITE_CLOUDINARY_API_SECRET=YOUR_API_SECRET\n<\/code><\/span><\/pre>\n<p>Replace <code>YOUR_CLOUD_NAME<\/code> <code>YOUR_API_KEY<\/code> and <code>YOUR_API_SECRET<\/code> with the <code>Cloud name<\/code>, <code>API Key<\/code> and <code>API Secret<\/code> values from the <a href=\"https:\/\/cloudinary.com\/console?ap=em\">console page<\/a>.<\/p>\n<p>Yes, these are environment variables. Now I know I mentioned that SvelteKit did not have full support for environment variables. Have a look at <a href=\"https:\/\/github.com\/vitejs\/vite\/issues\/3176\">this Github issue<\/a> to understand what I meant. It\u2019s more of an issue with <a href=\"https:\/\/vitejs.dev\/\">Vite.js<\/a>, a build tool that Svelte uses, than with SvelteKit. I\u2019d also highly recommend you <a href=\"https:\/\/kit.svelte.dev\/faq#env-vars\">read this FAQ<\/a> and <a href=\"https:\/\/dev.to\/danawoodman\/storing-environment-variables-in-sveltekit-2of3#security-note\">this blog post<\/a> before proceeding any further.<\/p>\n<p>To finish up the setup, let\u2019s install the dependencies<\/p>\n<h3>Dependencies\/Libraries used<\/h3>\n<p>Run the following command to install the required dependencies.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm run install cloudinary\n<\/code><\/span><\/pre>\n<h3>Sample videos for upload<\/h3>\n<p>Since SvelteKit doesn\u2019t directly support file upload yet, we\u2019re going to be using static files that we have pre-downloaded. I downloaded <a href=\"https:\/\/pixabay.com\/videos\/man-wave-hand-waving-hello-80696\/\">this<\/a> video for the foreground then just got a random video for the background. You can find these videos <a href=\"https:\/\/github.com\/musebe\/Green-Screen-Videos-With-Cloudinary\/tree\/main\/static\/videos\">in the GitHub repo<\/a>.<\/p>\n<h2>Getting started<\/h2>\n<p>Create a new folder called <code>lib<\/code> under the <code>src<\/code> folder and create a new file called <code>cloudinary.js<\/code> inside <code>src\/lib<\/code>. Paste the following code inside <code>src\/lib\/cloudinary.js<\/code>.<\/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\">\/\/ src\/lib\/cloudinary.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'cloudinary'<\/span>;\n\ncloudinary.config({\n\t<span class=\"hljs-attr\">cloud_name<\/span>: <span class=\"hljs-keyword\">import<\/span>.meta.env.VITE_CLOUDINARY_CLOUD_NAME,\n\t<span class=\"hljs-attr\">api_key<\/span>: <span class=\"hljs-keyword\">import<\/span>.meta.env.VITE_CLOUDINARY_API_KEY,\n\t<span class=\"hljs-attr\">api_secret<\/span>: <span class=\"hljs-keyword\">import<\/span>.meta.env.VITE_CLOUDINARY_API_SECRET\n});\n\n<span class=\"hljs-keyword\">const<\/span> CLOUDINARY_FOLDER_NAME = <span class=\"hljs-string\">'green-screen-videos\/'<\/span>;\n\n<span class=\"hljs-comment\">\/**\n * Get cloudinary upload\n *\n * @param {string} id\n * @returns {Promise}\n *\/<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> handleGetCloudinaryUpload = <span class=\"hljs-function\">(<span class=\"hljs-params\">id<\/span>) =&gt;<\/span> {\n\t<span class=\"hljs-keyword\">return<\/span> cloudinary.api.resource(id, {\n\t\t<span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'upload'<\/span>,\n\t\t<span class=\"hljs-attr\">prefix<\/span>: CLOUDINARY_FOLDER_NAME,\n\t\t<span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'video'<\/span>\n\t});\n};\n\n<span class=\"hljs-comment\">\/**\n * Get cloudinary uploads\n * @returns {Promise}\n *\/<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> handleGetCloudinaryUploads = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\t<span class=\"hljs-keyword\">return<\/span> cloudinary.api.resources({\n\t\t<span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">'upload'<\/span>,\n\t\t<span class=\"hljs-attr\">prefix<\/span>: CLOUDINARY_FOLDER_NAME,\n\t\t<span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'video'<\/span>\n\t});\n};\n\n<span class=\"hljs-comment\">\/**\n * Uploads a video to cloudinary and returns the upload result\n *\n * @param {{path: string; transformation?:TransformationOptions;publicId?: string; folder?: boolean; }} resource\n *\/<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> handleCloudinaryUpload = <span class=\"hljs-function\">(<span class=\"hljs-params\">resource<\/span>) =&gt;<\/span> {\n\t<span class=\"hljs-keyword\">return<\/span> cloudinary.uploader.upload(resource.path, {\n\t\t<span class=\"hljs-comment\">\/\/ Folder to store video in<\/span>\n\t\t<span class=\"hljs-attr\">folder<\/span>: resource.folder ? CLOUDINARY_FOLDER_NAME : <span class=\"hljs-literal\">null<\/span>,\n\t\t<span class=\"hljs-comment\">\/\/ Public id of video.<\/span>\n\t\t<span class=\"hljs-attr\">public_id<\/span>: resource.publicId,\n\t\t<span class=\"hljs-comment\">\/\/ Type of resource<\/span>\n\t\t<span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'auto'<\/span>,\n\t\t<span class=\"hljs-comment\">\/\/ Transformation to apply to the video<\/span>\n\t\t<span class=\"hljs-attr\">transformation<\/span>: resource.transformation\n\t});\n};\n\n<span class=\"hljs-comment\">\/**\n * Deletes resources from cloudinary. Takes in an array of public ids\n * @param {string&#91;]} ids\n *\/<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> handleCloudinaryDelete = <span class=\"hljs-function\">(<span class=\"hljs-params\">ids<\/span>) =&gt;<\/span> {\n\t<span class=\"hljs-keyword\">return<\/span> cloudinary.api.delete_resources(ids, {\n\t\t<span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'video'<\/span>\n\t});\n};\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>At the top, we import the v2 API from the cloudinary SDK and rename it to <code>cloudinary<\/code>. We then call the <code>.config<\/code> method to initialize it with our API credentials. Note how we import the environment variables. Read <a href=\"https:\/\/vitejs.dev\/guide\/env-and-mode.html#env-variables\">this<\/a> for more information on that.<\/p>\n<p><code>CLOUDINARY_FOLDER_NAME<\/code> is the name of the cloudinary folder where we want to store all our uploaded videos. Storing all our similar uploads to one folder will make it easier for us to fetch all resources in a particular folder.<\/p>\n<p><code>handleGetCloudinaryUpload<\/code> and <code>handleGetCloudinaryUploads<\/code> call the <code>api.resource<\/code> and the <code>api.resources<\/code> methods respectively. These are usually for getting either a single resource using its public id, or getting all resources in a folder. You can find more information on the two APIs in the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#get_resources\">official docs<\/a>.<\/p>\n<p><code>handleCloudinaryUpload<\/code> calls the <code>uploader.upload<\/code> method on the SDK to upload a file, in this case, a video. It takes in an object that contains the path to the file and a transformation array. Read the <a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference\">upload api reference<\/a> for more information on the options you can pass.<\/p>\n<p><code>handleCloudinaryDelete<\/code> deletes resources from cloudinary by passing an array of public IDs to the <code>api.delete_resources<\/code> method. Read more about it in the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#delete_resources\">official docs<\/a>.<\/p>\n<p>Next, we need some API endpoints. SvelteKit uses a file-based routing system. Any file ending in a <code>.js<\/code> or a <code>.ts<\/code> extension in the <code>src\/routes<\/code> folder becomes an endpoint. Read about this in the <a href=\"https:\/\/kit.svelte.dev\/docs#routing-endpoints\">SvelteKit docs<\/a>.<\/p>\n<p>We want all our APIs to have the <code>\/api\/<\/code> prefix so let\u2019s create a new folder called <code>api<\/code> under <code>src\/routes<\/code>. Inside of <code>src\/routes\/api<\/code> create a folder called <code>videos<\/code>. Create two files inside <code>src\/routes\/api\/videos<\/code>, one called <code>[...id].js<\/code> and another called <code>index.js<\/code>. The files will map to the endpoints <code>\/api\/videos\/<\/code> and <code>\/api\/videos\/:id<\/code>.<\/p>\n<p>Paste the following inside <code>src\/routes\/api\/videos\/index.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-comment\">\/\/ src\/routes\/api\/videos\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> {\n\thandleCloudinaryDelete,\n\thandleCloudinaryUpload,\n\thandleGetCloudinaryUploads\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'$lib\/cloudinary'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">get<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t<span class=\"hljs-keyword\">const<\/span> uploads = <span class=\"hljs-keyword\">await<\/span> handleGetCloudinaryUploads();\n\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-number\">200<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\t<span class=\"hljs-attr\">result<\/span>: uploads\n\t\t\t}\n\t\t};\n\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: error?.statusCode ?? <span class=\"hljs-number\">400<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\terror\n\t\t\t}\n\t\t};\n\t}\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">post<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t<span class=\"hljs-comment\">\/\/ Path to the foreground video. This is the video with the solid background color<\/span>\n\t\t<span class=\"hljs-keyword\">const<\/span> foregroundVideoPath = <span class=\"hljs-string\">'static\/videos\/foreground.mp4'<\/span>;\n\n\t\t<span class=\"hljs-comment\">\/\/ The solid background color of the foreground video<\/span>\n\t\t<span class=\"hljs-keyword\">const<\/span> foregroundChromaKeyColor = <span class=\"hljs-string\">'#6adb47'<\/span>;\n\n\t\t<span class=\"hljs-comment\">\/\/ Upload the foreground video to Cloudinary<\/span>\n\t\t<span class=\"hljs-keyword\">const<\/span> foregroundUploadResponse = <span class=\"hljs-keyword\">await<\/span> handleCloudinaryUpload({\n\t\t\t<span class=\"hljs-attr\">path<\/span>: foregroundVideoPath,\n\t\t\t<span class=\"hljs-attr\">folder<\/span>: <span class=\"hljs-literal\">false<\/span>\n\t\t});\n\n\t\t<span class=\"hljs-comment\">\/\/ Path to the background video. This is the video that will be placed in the background<\/span>\n\t\t<span class=\"hljs-keyword\">const<\/span> backgroundVideoPath = <span class=\"hljs-string\">'static\/videos\/background.mp4'<\/span>;\n\n\t\t<span class=\"hljs-comment\">\/\/ Upload the background video to Cloudinary<\/span>\n\t\t<span class=\"hljs-keyword\">const<\/span> backgroundUploadResponse = <span class=\"hljs-keyword\">await<\/span> handleCloudinaryUpload({\n\t\t\t<span class=\"hljs-attr\">path<\/span>: backgroundVideoPath,\n\t\t\t<span class=\"hljs-attr\">folder<\/span>: <span class=\"hljs-literal\">true<\/span>,\n\t\t\t<span class=\"hljs-attr\">transformation<\/span>: &#91;\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">500<\/span>,\n\t\t\t\t\t<span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">'scale'<\/span>\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">overlay<\/span>: <span class=\"hljs-string\">`video:<span class=\"hljs-subst\">${foregroundUploadResponse.public_id}<\/span>`<\/span>\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">flags<\/span>: <span class=\"hljs-string\">'relative'<\/span>,\n\t\t\t\t\t<span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-string\">'0.6'<\/span>,\n\t\t\t\t\t<span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">'scale'<\/span>\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">color<\/span>: foregroundChromaKeyColor,\n\t\t\t\t\t<span class=\"hljs-attr\">effect<\/span>: <span class=\"hljs-string\">'make_transparent:20'<\/span>\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">flags<\/span>: <span class=\"hljs-string\">'layer_apply'<\/span>,\n\t\t\t\t\t<span class=\"hljs-attr\">gravity<\/span>: <span class=\"hljs-string\">'north'<\/span>\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t<span class=\"hljs-attr\">duration<\/span>: <span class=\"hljs-string\">'15.0'<\/span>\n\t\t\t\t}\n\t\t\t]\n\t\t});\n\n\t\t<span class=\"hljs-comment\">\/\/ Delete the foreground video from Cloudinary, We don't need it anymore<\/span>\n\t\t<span class=\"hljs-keyword\">await<\/span> handleCloudinaryDelete(&#91;foregroundUploadResponse.public_id]);\n\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-number\">200<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\t<span class=\"hljs-attr\">result<\/span>: backgroundUploadResponse\n\t\t\t}\n\t\t};\n\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: error?.statusCode ?? <span class=\"hljs-number\">400<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\terror\n\t\t\t}\n\t\t};\n\t}\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>To handle requests of a particular verb\/type we need to export a function corresponding to the HTTP verb. For example, to handle GET requests we export a function called <code>get<\/code>. The only exception is the DELETE verb where we use <code>del<\/code> instead since delete is a reserved keyword. This is all covered in the <a href=\"https:\/\/kit.svelte.dev\/docs#routing-endpoints\">docs<\/a>.<\/p>\n<p><code>get<\/code> calls <code>handleGetCloudinaryUploads<\/code> to get all the resources that have been uploaded to our folder in cloudinary.<\/p>\n<p><code>post<\/code> is where the magic happens. We first need the path to both the foreground video and the background video. You can download these videos from [here](<a href=\"https:\/\/res.cloudinary.com\/hackit-africa\/video\/upload\/v1637232264\/videos-svelte\/background.mp4\">https:\/\/res.cloudinary.com\/hackit-africa\/video\/upload\/v1637232264\/videos-svelte\/background.mp4<\/a> and <a href=\"%5Bhttps:\/\/res.cloudinary.com\/hackit-africa\/video\/upload\/v1637232241\/videos-svelte\/foreground.mp4%5D(https:\/\/res.cloudinary.com\/hackit-africa\/video\/upload\/v1637232241\/videos-svelte\/foreground.mp4)\">Here<\/a> then save them inside <code>static\/videos<\/code> folder. The foreground video is the green screen video(the video whose background we want to make transparent). We also define the background color that\u2019s in the foreground video in the <code>foregroundChromaKeyColor<\/code> variable. We then upload the foreground video to cloudinary then followed by the background video. We then use Cloudinary\u2019s transformation to overlay the previously uploaded foreground video over the background video and also make the green background transparent. There\u2019s a guide showing how to make a video transparent using cloudinary. <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery#apply_video_transparency\">Here\u2019s the link<\/a>. Finally we delete the foreground video from cloudinary since we don\u2019t need it anymore.<\/p>\n<p>Paste the following code inside <code>src\/routes\/api\/videos\/[...id].js<\/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-comment\">\/\/ src\/routes\/api\/videos\/&#91;...id].js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { handleCloudinaryDelete, handleGetCloudinaryUpload } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'$lib\/cloudinary'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">get<\/span>(<span class=\"hljs-params\">{ params }<\/span>) <\/span>{\n\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t<span class=\"hljs-keyword\">const<\/span> result = <span class=\"hljs-keyword\">await<\/span> handleGetCloudinaryUpload(params.id);\n\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-number\">200<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\tresult\n\t\t\t}\n\t\t};\n\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: error?.statusCode ?? <span class=\"hljs-number\">400<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\terror\n\t\t\t}\n\t\t};\n\t}\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">del<\/span>(<span class=\"hljs-params\">{ params }<\/span>) <\/span>{\n\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t<span class=\"hljs-keyword\">const<\/span> result = <span class=\"hljs-keyword\">await<\/span> handleCloudinaryDelete(&#91;params.id]);\n\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-number\">200<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\tresult\n\t\t\t}\n\t\t};\n\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t<span class=\"hljs-attr\">status<\/span>: error?.statusCode ?? <span class=\"hljs-number\">400<\/span>,\n\t\t\t<span class=\"hljs-attr\">body<\/span>: {\n\t\t\t\terror\n\t\t\t}\n\t\t};\n\t}\n}\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We\u2019re just handling two HTTP verbs here, i.e. get and delete.<\/p>\n<p><code>get<\/code> calls <code>handleGetCloudinaryUpload<\/code> to get a specific resource using its public ID.<\/p>\n<p><code>del<\/code> passes a public id to <code>handleCloudinaryDelete<\/code> and deletes the resource with that public ID.<\/p>\n<p>To understand why we named our file <code>[...id].js<\/code> instead of <code>[id].js<\/code>, have a look at the <a href=\"https:\/\/kit.svelte.dev\/docs#routing-advanced-rest-parameters\">rest parameters docs<\/a>. These allow us to match all paths following the <code>api\/videos\/:id<\/code> instead of just <code>api\/videos\/:id<\/code>. For example, say we have an endpoint <code>\/api\/videos\/folder\/videoid<\/code>, if we just use <code>[id].js<\/code> it will only match to <code>\/api\/videos\/folder<\/code>.<\/p>\n<p>Let\u2019s move on to the front end. For the frontend, SvelteKit also uses file-based routing. Files that are inside the <code>src\/routes<\/code> directory and end in the extension <code>.svelte<\/code> are treated as pages\/components. Check out <a href=\"https:\/\/kit.svelte.dev\/docs#routing-pages\">this<\/a> documentation on page routing.<\/p>\n<p>Open <code>src\/app.html<\/code> and add the following to the head.<\/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\">style<\/span>&gt;<\/span><span class=\"css\">\n    <span class=\"hljs-selector-tag\">body<\/span> {\n        <span class=\"hljs-attribute\">font-family<\/span>: sans-serif;\n        <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n        <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n    }\n\n    * {\n        <span class=\"hljs-attribute\">box-sizing<\/span>: border-box;\n        <span class=\"hljs-attribute\">--color-primary<\/span>: <span class=\"hljs-number\">#0070f3<\/span>;\n    }\n\n    <span class=\"hljs-selector-tag\">button<\/span> {\n        <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">20px<\/span>;\n        <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">50px<\/span>;\n        <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-number\">#ccc<\/span>;\n        <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#ffffff<\/span>;\n        <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">1.2rem<\/span>;\n        <span class=\"hljs-attribute\">font-weight<\/span>: bold;\n        <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n    }\n\n    <span class=\"hljs-selector-tag\">button<\/span><span class=\"hljs-selector-pseudo\">:disabled<\/span> {\n        <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#cfcfcf<\/span>;\n    }\n\n    <span class=\"hljs-selector-tag\">button<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span><span class=\"hljs-selector-pseudo\">:not(<\/span><span class=\"hljs-selector-attr\">&#91;disabled]<\/span>) {\n        <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#ffffff<\/span>;\n        <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-primary);\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-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>It\u2019s just some simple styles that we want to have globally. Next, create a new folder under <code>src<\/code> and call it <code>components<\/code>. This folder will hold all of our shared components. Create a new file under <code>src\/components<\/code> and name it <code>Layout.svelte<\/code>. Paste the following code inside of <code>src\/components\/Layout.svelte<\/code>.<\/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\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/\"<\/span>&gt;<\/span>Home<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/videos\"<\/span>&gt;<\/span>Videos<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">slot<\/span> \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/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\">nav<\/span> {\n\t\t<span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#333333<\/span>;\n\t\t<span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#fff<\/span>;\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100px<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">nav<\/span> <span class=\"hljs-selector-tag\">ul<\/span> {\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">flex<\/span>: <span class=\"hljs-number\">1<\/span>;\n\t\t<span class=\"hljs-attribute\">justify-content<\/span>: center;\n\t\t<span class=\"hljs-attribute\">align-items<\/span>: center;\n\t\t<span class=\"hljs-attribute\">list-style<\/span>: none;\n\t\t<span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">8px<\/span>;\n\t\t<span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n\t\t<span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">nav<\/span> <span class=\"hljs-selector-tag\">ul<\/span> <span class=\"hljs-selector-tag\">li<\/span> <span class=\"hljs-selector-tag\">a<\/span> {\n\t\t<span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">10px<\/span> <span class=\"hljs-number\">20px<\/span>;\n\t\t<span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#000000<\/span>;\n\t\t<span class=\"hljs-attribute\">display<\/span>: block;\n\t\t<span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#ffffff<\/span>;\n\t\t<span class=\"hljs-attribute\">text-decoration<\/span>: none;\n\t\t<span class=\"hljs-attribute\">font-weight<\/span>: bold;\n\t}\n\n\t<span class=\"hljs-selector-tag\">nav<\/span> <span class=\"hljs-selector-tag\">ul<\/span> <span class=\"hljs-selector-tag\">li<\/span> <span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span> {\n\t\t<span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#ffffff<\/span>;\n\t\t<span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-primary);\n\t}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\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 we just have a nav at the top and the main element where the body of our pages will go. If you\u2019re not familiar with svelte slots and component composition, check out <a href=\"https:\/\/svelte.dev\/tutorial\/slots\">this tutorial<\/a> from the svelte website.<\/p>\n<p>Paste the following code inside <code>src\/routes\/index.svelte<\/code>.<\/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\t<span class=\"hljs-keyword\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/components\/Layout.svelte'<\/span>;\n\t<span class=\"hljs-keyword\">import<\/span> { goto } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'$app\/navigation'<\/span>;\n\n\t<span class=\"hljs-keyword\">let<\/span> isLoading = <span class=\"hljs-literal\">false<\/span>;\n\n\t<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">onGenerate<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">true<\/span>;\n\n\t\t\t<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">'\/api\/videos'<\/span>, {\n\t\t\t\t<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'post'<\/span>\n\t\t\t});\n\t\t\t<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n\t\t\t<span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n\t\t\t\t<span class=\"hljs-keyword\">throw<\/span> data;\n\t\t\t}\n\n\t\t\tgoto(<span class=\"hljs-string\">'\/videos\/'<\/span>, { <span class=\"hljs-attr\">replaceState<\/span>: <span class=\"hljs-literal\">false<\/span> });\n\t\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t\t<span class=\"hljs-built_in\">console<\/span>.error(error);\n\t\t} <span class=\"hljs-keyword\">finally<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">false<\/span>;\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\">Layout<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"wrapper\"<\/span>&gt;<\/span>\n\t\t{#if isLoading}\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"loading\"<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span>&gt;<\/span>Loading. Please be patient.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">hr<\/span> \/&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t{\/if}\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Make green screen videos transparent using Cloudinary + Svelte<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\t\t\tWhile we're referring to them as green screen videos, you can really do this with any video\n\t\t\tthat has a solid background color.\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\t\t\tYou can change the background and foreground videos by editing the videos inside\n\t\t\t\/static\/videos\/\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Tap on the button below to edit the files in \/static\/videos\/<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">on:click<\/span>|<span class=\"hljs-attr\">preventDefault<\/span>=<span class=\"hljs-string\">{onGenerate}<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{isLoading}<\/span>&gt;<\/span>GENERATE VIDEO<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">br<\/span> \/&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>or<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">br<\/span> \/&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/videos\"<\/span>&gt;<\/span>View generated videos<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/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\">div<\/span><span class=\"hljs-selector-class\">.loading<\/span> {\n\t\t<span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-primary);\n\t}\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> {\n\t\t<span class=\"hljs-attribute\">min-height<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n\t\t<span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">flex-flow<\/span>: column;\n\t\t<span class=\"hljs-attribute\">justify-content<\/span>: center;\n\t\t<span class=\"hljs-attribute\">align-items<\/span>: center;\n\t\t<span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#ffffff<\/span>;\n\t}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\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>When the user taps on the button, the <code>onGenerate<\/code> function makes a POST request to the <code>\/api\/videos<\/code> endpoint that we created earlier. This uploads the two videos then navigate to the videos page that we\u2019ll create shortly. I won\u2019t go much into the syntax of svelte components since that\u2019s something you can easily grasp from the svelte documentation and other tutorials.<\/p>\n<p>Next, we need pages to display all videos and specific videos. Create a new folder called <code>videos<\/code> under <code>src\/routes<\/code>. <strong>Please note that this is a different videos folder from the one inside the api folder.<\/strong> Then create two files under <code>src\/routes\/videos<\/code>, one called <code>index.svelte<\/code> and another <code>[...id].svelte<\/code>.<\/p>\n<p>Paste the following code inside of <code>src\/routes\/videos\/index.svelte<\/code><\/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\">script<\/span>&gt;<\/span><span class=\"javascript\">\n\t<span class=\"hljs-keyword\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/..\/components\/Layout.svelte'<\/span>;\n\t<span class=\"hljs-keyword\">import<\/span> { onMount } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'svelte'<\/span>;\n\n\t<span class=\"hljs-keyword\">let<\/span> isLoading = <span class=\"hljs-literal\">false<\/span>;\n\t<span class=\"hljs-keyword\">let<\/span> videos = &#91;];\n\n\tonMount(<span class=\"hljs-keyword\">async<\/span> () =&gt; {\n\t\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">true<\/span>;\n\n\t\t\t<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">'\/api\/videos'<\/span>, {\n\t\t\t\t<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'GET'<\/span>\n\t\t\t});\n\n\t\t\t<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\t\t\t<span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n\t\t\t\t<span class=\"hljs-keyword\">throw<\/span> data;\n\t\t\t}\n\n\t\t\tvideos = data.result.resources;\n\t\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t\t<span class=\"hljs-built_in\">console<\/span>.error(error);\n\t\t} <span class=\"hljs-keyword\">finally<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">false<\/span>;\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\">Layout<\/span>&gt;<\/span>\n\t{#if videos.length &gt; 0}\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"wrapper\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"videos\"<\/span>&gt;<\/span>\n\t\t\t\t{#each videos as video (video.public_id)}\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"video\"<\/span>&gt;<\/span>\n\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"thumbnail\"<\/span>&gt;<\/span>\n\t\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{video.secure_url.replace(<\/span>'<span class=\"hljs-attr\">.mp4<\/span>', '<span class=\"hljs-attr\">.jpg<\/span>')} <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{video.secure_url}<\/span> \/&gt;<\/span>\n\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"actions\"<\/span>&gt;<\/span>\n\t\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">{<\/span>`\/<span class=\"hljs-attr\">videos<\/span>\/${<span class=\"hljs-attr\">video.public_id<\/span>}`}&gt;<\/span>Open Video<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\t\t\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t\t{\/each}\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t{:else}\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"no-videos\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>No videos yet<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">br<\/span> \/&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/\"<\/span>&gt;<\/span>Generate video<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t{\/if}\n\n\t{#if isLoading &amp;&amp; videos.length === 0}\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"loading\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>Loading...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t{\/if}\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/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\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.videos<\/span> {\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">flex-flow<\/span>: row wrap;\n\t\t<span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">20px<\/span>;\n\t\t<span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">20px<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.videos<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> {\n\t\t<span class=\"hljs-attribute\">flex<\/span>: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">1<\/span> <span class=\"hljs-number\">400px<\/span>;\n\t\t<span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">#ccc<\/span> <span class=\"hljs-number\">1px<\/span> solid;\n\t\t<span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">5px<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.videos<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.thumbnail<\/span> {\n\t\t<span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.videos<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.thumbnail<\/span> <span class=\"hljs-selector-tag\">img<\/span> {\n\t\t<span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.videos<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.actions<\/span> {\n\t\t<span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">10px<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.loading<\/span>,\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.no-videos<\/span> {\n\t\t<span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">100vh<\/span> - <span class=\"hljs-number\">100px<\/span>);\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">flex-flow<\/span>: column;\n\t\t<span class=\"hljs-attribute\">align-items<\/span>: center;\n\t\t<span class=\"hljs-attribute\">justify-content<\/span>: center;\n\t}\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-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>Here we\u2019re using <code>onMount<\/code> to make a GET request to the <code>\/api\/videos<\/code> endpoint when the component mounts. Read about <code>onMount<\/code> <a href=\"https:\/\/svelte.dev\/docs#onMount\">here<\/a>. For the video thumbnails, all we have to do is replace the .mp4 extension with .jpg and Cloudinary automatically gives us a thumbnail of that video. Clicking on a video takes you to the <code>\/videos\/:id<\/code> page that we\u2019ll be creating next.<\/p>\n<p>Paste the following code inside <code>src\/routes\/videos\/[...id].svelte<\/code><\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" 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-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">load<\/span>(<span class=\"hljs-params\">{ page, fetch }<\/span>) <\/span>{\n\t\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t\t<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">`\/api\/videos\/<span class=\"hljs-subst\">${page.params.id}<\/span>`<\/span>, {\n\t\t\t\t<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'GET'<\/span>\n\t\t\t});\n\n\t\t\t<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\t\t\t<span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n\t\t\t\t<span class=\"hljs-keyword\">throw<\/span> data;\n\t\t\t}\n\n\t\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t\t<span class=\"hljs-attr\">props<\/span>: {\n\t\t\t\t\t<span class=\"hljs-attr\">video<\/span>: data.result\n\t\t\t\t}\n\t\t\t};\n\t\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t\t<span class=\"hljs-keyword\">return<\/span> {\n\t\t\t\t<span class=\"hljs-attr\">status<\/span>: error?.statusCode ?? <span class=\"hljs-number\">400<\/span>,\n\t\t\t\t<span class=\"hljs-attr\">error<\/span>: error?.message ?? <span class=\"hljs-string\">'Something went wrong'<\/span>\n\t\t\t};\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\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/..\/components\/Layout.svelte'<\/span>;\n\t<span class=\"hljs-keyword\">import<\/span> { goto } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'$app\/navigation'<\/span>;\n\n\t<span class=\"hljs-keyword\">let<\/span> isLoading = <span class=\"hljs-literal\">false<\/span>;\n\t<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">let<\/span> video;\n\n\t<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">deleteVideo<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t\t<span class=\"hljs-keyword\">try<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">true<\/span>;\n\t\t\t<span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> fetch(<span class=\"hljs-string\">`\/api\/videos\/<span class=\"hljs-subst\">${video.public_id}<\/span>`<\/span>, {\n\t\t\t\t<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'DELETE'<\/span>\n\t\t\t});\n\n\t\t\t<span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-keyword\">await<\/span> response.json();\n\n\t\t\t<span class=\"hljs-keyword\">if<\/span> (!response.ok) {\n\t\t\t\t<span class=\"hljs-keyword\">throw<\/span> data;\n\t\t\t}\n\n\t\t\tgoto(<span class=\"hljs-string\">'\/videos'<\/span>, { <span class=\"hljs-attr\">replaceState<\/span>: <span class=\"hljs-literal\">true<\/span> });\n\t\t} <span class=\"hljs-keyword\">catch<\/span> (error) {\n\t\t\t<span class=\"hljs-built_in\">console<\/span>.error(error);\n\t\t} <span class=\"hljs-keyword\">finally<\/span> {\n\t\t\tisLoading = <span class=\"hljs-literal\">false<\/span>;\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\">Layout<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"wrapper\"<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"video\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{video.secure_url}<\/span> <span class=\"hljs-attr\">controls<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">track<\/span> <span class=\"hljs-attr\">kind<\/span>=<span class=\"hljs-string\">\"captions\"<\/span> \/&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"actions\"<\/span>&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">on:click<\/span>|<span class=\"hljs-attr\">preventDefault<\/span>=<span class=\"hljs-string\">{deleteVideo}<\/span> <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{isLoading}<\/span>&gt;<\/span>Delete<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/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\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> {\n\t\t<span class=\"hljs-attribute\">min-width<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">justify-content<\/span>: center;\n\t\t<span class=\"hljs-attribute\">align-items<\/span>: center;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> {\n\t\t<span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">80%<\/span>;\n\t}\n\n\t<span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.wrapper<\/span> <span class=\"hljs-selector-tag\">div<\/span><span class=\"hljs-selector-class\">.video<\/span> <span class=\"hljs-selector-tag\">video<\/span> {\n\t\t<span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\t\t<span class=\"hljs-attribute\">object-fit<\/span>: fill;\n\t}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\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\">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>If you\u2019ve used Next.js before, you probably know about <code>getStaticProps<\/code> or <code>getServerSideProps<\/code>. The <code>load<\/code> function that we\u2019ve used here is similar to those. In SvelteKit, however, the load method is called on both Server Side Rendering and Client-Side Rendering. There are a few things you should be wary of when using load. I highly recommend you have a read of <a href=\"https:\/\/kit.svelte.dev\/docs#loading\">these docs<\/a>.<\/p>\n<p>In this case, we use load to make GET a call to the <code>\/api\/videos\/:id<\/code> endpoint to get the video with that specific ID. That\u2019s about it for the front end. We need one more thing, a custom error page.<\/p>\n<p>Create a file called <code>__error.svelte<\/code> under <code>src\/routes<\/code> and paste the following code inside.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" 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\t<span class=\"hljs-keyword\">import<\/span> Layout <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/components\/Layout.svelte'<\/span>;\n\n\t<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">tryAgain<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t\t<span class=\"hljs-built_in\">window<\/span>.location.reload();\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\">Layout<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"wrapper\"<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>Something went wrong<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">br<\/span> \/&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">on:click<\/span>|<span class=\"hljs-attr\">preventDefault<\/span>=<span class=\"hljs-string\">{tryAgain}<\/span>&gt;<\/span>Try Again<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/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-class\">.wrapper<\/span> {\n\t\t<span class=\"hljs-attribute\">display<\/span>: flex;\n\t\t<span class=\"hljs-attribute\">flex-direction<\/span>: column;\n\t\t<span class=\"hljs-attribute\">align-items<\/span>: center;\n\t\t<span class=\"hljs-attribute\">justify-content<\/span>: center;\n\t\t<span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">100vh<\/span> - <span class=\"hljs-number\">100px<\/span>);\n\t}\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-10\"><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>And that\u2019s it for this tutorial. You can run your app by running the following in your terminal.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm run dev -- --open   \n<\/code><\/span><\/pre>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28008,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,175,376,371,303],"class_list":["post-28007","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-jamstack","tag-svelte","tag-under-review","tag-video"],"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>Edit Green Screen Videos<\/title>\n<meta name=\"description\" content=\"Have you ever watched one of those programming videos where the person&#039;s face is overlayed over their computer screen? That&#039;s made possible using green screens. They&#039;re widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won&#039;t go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we&#039;ll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.\" \/>\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\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Edit Green Screen Videos\" \/>\n<meta property=\"og:description\" content=\"Have you ever watched one of those programming videos where the person&#039;s face is overlayed over their computer screen? That&#039;s made possible using green screens. They&#039;re widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won&#039;t go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we&#039;ll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-23T22:36:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"636\" \/>\n\t<meta property=\"og:image:height\" content=\"278\" \/>\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\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Edit Green Screen Videos\",\"datePublished\":\"2022-03-23T22:36:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\"},\"wordCount\":4,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA\",\"keywords\":[\"Guest Post\",\"JAMStack\",\"Svelte\",\"Under Review\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\",\"name\":\"Edit Green Screen Videos\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA\",\"datePublished\":\"2022-03-23T22:36:51+00:00\",\"description\":\"Have you ever watched one of those programming videos where the person's face is overlayed over their computer screen? That's made possible using green screens. They're widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won't go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we'll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA\",\"width\":636,\"height\":278},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Edit Green Screen Videos\"}]},{\"@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":"Edit Green Screen Videos","description":"Have you ever watched one of those programming videos where the person's face is overlayed over their computer screen? That's made possible using green screens. They're widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won't go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we'll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.","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\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/","og_locale":"en_US","og_type":"article","og_title":"Edit Green Screen Videos","og_description":"Have you ever watched one of those programming videos where the person's face is overlayed over their computer screen? That's made possible using green screens. They're widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won't go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we'll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-23T22:36:51+00:00","og_image":[{"width":636,"height":278,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.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\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/"},"author":{"name":"","@id":""},"headline":"Edit Green Screen Videos","datePublished":"2022-03-23T22:36:51+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/"},"wordCount":4,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA","keywords":["Guest Post","JAMStack","Svelte","Under Review","Video"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/","name":"Edit Green Screen Videos","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA","datePublished":"2022-03-23T22:36:51+00:00","description":"Have you ever watched one of those programming videos where the person's face is overlayed over their computer screen? That's made possible using green screens. They're widely used especially in the media and filming industries. Even though green screens are preferred more, you can achieve the same using any solid color. I won't go over why green is more suitable compared to say blue or some other color. There are tons of youtube videos explaining that. You can check out this video or this one. That said, even though the title of this tutorial focuses on green screens, you can do the same for any video with a contrasting solid background color. In this tutorial, we'll be using Cloudinary and SvelteKit. SvelteKit is to Svelte.js just as Next.js is to React.js or Nuxt.js to Vue.js.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA","width":636,"height":278},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/edit-green-screen-videos-using-cloudinary-and-sveltekit\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Edit Green Screen Videos"}]},{"@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\/v1681925694\/Web_Assets\/blog\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741\/f5734e77f849cbe87ac242bb08a64edaedc000bc-636x278-1_2800844741.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28007","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=28007"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28007\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28008"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28007"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28007"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}