{"id":27959,"date":"2021-11-01T19:04:06","date_gmt":"2021-11-01T19:04:06","guid":{"rendered":"http:\/\/Create-a-Holiday-Card-Generator"},"modified":"2021-11-01T19:04:06","modified_gmt":"2021-11-01T19:04:06","slug":"create-a-holiday-card-generator","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/","title":{"rendered":"Create a Holiday Card Generator"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Greeting cards are pieces of stiff paper or thin cardboard with text, illustrations, or photos, given on special occasions such as birthdays, anniversaries, holidays, e.t.c.<\/p>\n<p>This post will discuss building a holiday card generator for the Harvest Month, Thanksgiving, and Diwali holidays using <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> and <a href=\"https:\/\/nextjs.org\/\">Next.js<\/a>. At the end of this tutorial, we will learn how to host images on Cloudinary and add transformations to the selected image.<\/p>\n<p>Cloudinary is a platform on which you can quickly and easily upload, store, manage, transform, and deliver images and videos for websites and apps. The platform also offers a vast collection of SDKs for frontend frameworks and libraries.<\/p>\n<p>Next.js is a React-based frontend development framework that enables functionalities like server-side rendering, static site generation, file-system routing (with no need to configure <code>react-router-dom<\/code> manually), and API endpoints for backend features.<\/p>\n<h2>Sandbox<\/h2>\n<p>We completed this project in <a href=\"https:\/\/codesandbox.io\/s\/competent-jones-xbknb?file=\/pages\/index.js\">a CodeSandbox<\/a>, and you can fork it to run the code.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/competent-jones-xbknb?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=\"competent-jones-xbknb\"\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>Prerequisites<\/h2>\n<p>The following steps in this post require JavaScript and React.js experience. Experience with Next.js isn\u2019t a requirement, but it\u2019s nice to have.<\/p>\n<p>We also need a <a href=\"https:\/\/cloudinary.com\/\">Cloudinary account<\/a> to store the media files. <a href=\"https:\/\/cloudinary.com\/users\/register\/free\"><strong>Signup<\/strong><\/a> <strong>is completely free<\/strong>.<\/p>\n<h2>Getting Started<\/h2>\n<p>We need to create a Next.js starter project by navigating to the desired directory and running the command below in our 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\">    npx create-next-app -e <span class=\"hljs-keyword\">with<\/span>-tailwindcss holiday_card &amp;&amp; cd holiday_card\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>This command creates a Next.js project with TailwindCSS setup called <code>holiday_card<\/code>, and navigates into the project directory.<\/p>\n<p><a href=\"https:\/\/tailwindcss.com\/\">TailwindCSS<\/a> is a utility-first CSS framework packed with classes to help us style our web page.<\/p>\n<p>We proceed to install the <a href=\"https:\/\/github.com\/cloudinary\/cloudinary-react#readme\">cloudinary-react<\/a> dependency with:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm install cloudinary-react\n<\/code><\/span><\/pre>\n<h2>Holiday Card generator with Cloudinary<\/h2>\n<p>With the project dependencies installed, we need to download sample images to create our holiday cards. To get started, navigate to the URLs below and download the photos from Unsplash.<\/p>\n<p><strong>Harvest Month Photos<\/strong><\/p>\n<ul>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/fjyAh0NLowI\">https:\/\/unsplash.com\/photos\/fjyAh0NLowI<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/yP19KADwhEI\">https:\/\/unsplash.com\/photos\/yP19KADwhEI<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/yuiJO6bvHi4\">https:\/\/unsplash.com\/photos\/yuiJO6bvHi4<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/6cC7WKiwcGs\">https:\/\/unsplash.com\/photos\/6cC7WKiwcGs<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/Nu4u9g7Sgdw\">https:\/\/unsplash.com\/photos\/Nu4u9g7Sgdw<\/a>\n<\/li>\n<\/ul>\n<p><strong>Thanksgiving Photos<\/strong><\/p>\n<ul>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/7BpuzmcxlHU\">https:\/\/unsplash.com\/photos\/7BpuzmcxlHU<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/NPBnWE1o07I\">https:\/\/unsplash.com\/photos\/NPBnWE1o07I<\/a>\n<\/li>\n<\/ul>\n<p><strong>Diwali Photos<\/strong><\/p>\n<ul>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/xisPXJqwQkA\">https:\/\/unsplash.com\/photos\/xisPXJqwQkA<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/unsplash.com\/photos\/o9e6ItFOIh0\">https:\/\/unsplash.com\/photos\/o9e6ItFOIh0<\/a>\n<\/li>\n<\/ul>\n<p>Next, we need to log into our <a href=\"https:\/\/cloudinary.com\/users\/login\">Cloudinary<\/a> dashboard. Click on the <strong>Media Library<\/strong> tab, then drag and drop the downloaded images. Cloudinary also supports other upload formats.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635104341304_Screenshot+2021-10-24+at+20.37.46.png\" alt=\"Cloudinary console and upload button for other formats of upload\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"275\"\/><\/p>\n<p>After uploading all the images, we will see them displayed on the console with the <code>publicId<\/code>. The <strong>ID<\/strong>s will come in handy when generating holiday cards.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635104691679_Screenshot+2021-10-24+at+20.43.31.png\" alt=\"Uploaded image with publicId highlighted\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"983\"\/><\/p>\n<h2>Setting up the image collection<\/h2>\n<p>With the images uploaded, we need to create a <code>utils<\/code> folder in the project root directory. In this folder, we create <code>harvest.json<\/code>, <code>thanksgiving.json<\/code>, and <code>diwali.json<\/code> files. These files contain data of the images for each type of card.<\/p>\n<p>Here are the JSON data for each file.<\/p>\n<p><strong>harvest.json<\/strong><\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">    &#91;\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">1<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">2<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">3<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">4<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">5<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        }\n    ]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Thanksgiving.json<\/strong><\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">    &#91;\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">1<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">2<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        }\n    ]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>diwali.json<\/strong><\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">    &#91;\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">1<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\n        },\n        {\n            <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">2<\/span>,\n            <span class=\"hljs-attr\">\"publicId\"<\/span>: <span class=\"hljs-string\">\"&lt;REPLACE THIS WITH YOUR IMAGE PUBLICID&gt;\"<\/span>\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\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h2>Creating the holiday card<\/h2>\n<p>Next, we need to modify the <code>index.js<\/code> file in the <code>pages<\/code>  folder:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/fbd7160578061f216fb3604a151cf57b\">https:\/\/gist.github.com\/Mr-Malomz\/fbd7160578061f216fb3604a151cf57b<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/fbd7160578061f216fb3604a151cf57b\">https:\/\/gist.github.com\/Mr-Malomz\/fbd7160578061f216fb3604a151cf57b<\/a><\/p>\n<p>The snippet above does the following:<\/p>\n<ul>\n<li>Import required dependencies and image collections<\/li>\n<li>Create state variables to manage active tabs, selected Image ID, form data, and display the Holiday card.<\/li>\n<li>A <code>handleChange<\/code> function to control form inputs<\/li>\n<li>Markups to conditionally display tabs<\/li>\n<li>Markups for form elements and conditionally render the list of Images using <code>cloudinary-react<\/code>. The list of images also has an <code>onClick<\/code> function that sets the current image <code>id<\/code> to show the active image, the form object, and the <code>showCard<\/code> property.<\/li>\n<\/ul>\n<p>With that done, we can start a development server using the command below:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm run dev\n<\/code><\/span><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635420381602_screencapture-localhost-3000-2021-10-28-12_25_21.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1002\"\/>\n<img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635420381639_screencapture-localhost-3000-2021-10-28-12_25_29.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"969\"\/><\/p>\n<p>With our application up and running, we need to create a <code>Card<\/code>  component to render the generated Holiday card. To do this, we need to create a <code>components<\/code> folder in the project root directory, and in this folder, create a <code>Card.js<\/code> file and add the code snippet below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" 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> { CloudinaryContext, Transformation, Image } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'cloudinary-react'<\/span>;\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ message, name, publicId }<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">'dtgbzmpca'<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span> <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{publicId}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{1000}<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">'fit'<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">'blur:100'<\/span> \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">'brightness_hsb:-50'<\/span> \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span>\n                <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">'#FFFFFF'<\/span>\n                <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{{<\/span>\n                  <span class=\"hljs-attr\">background:<\/span> '',\n                  <span class=\"hljs-attr\">fontFamily:<\/span> '<span class=\"hljs-attr\">Neucha<\/span>',\n                  <span class=\"hljs-attr\">fontSize:<\/span> <span class=\"hljs-attr\">100<\/span>,\n                  <span class=\"hljs-attr\">fontWeight:<\/span> '<span class=\"hljs-attr\">bold<\/span>',\n                  <span class=\"hljs-attr\">text:<\/span> <span class=\"hljs-attr\">message<\/span>,\n                  <span class=\"hljs-attr\">textAlign:<\/span> '<span class=\"hljs-attr\">center<\/span>',\n                }}\n                <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">'1300'<\/span>\n                <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">'fit'<\/span>\n              \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">flags<\/span>=<span class=\"hljs-string\">'layer_apply'<\/span> \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span>\n                <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">'#FFFFFF'<\/span>\n                <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{{<\/span>\n                  <span class=\"hljs-attr\">fontFamily:<\/span> '<span class=\"hljs-attr\">Dancing<\/span> <span class=\"hljs-attr\">Script<\/span>',\n                  <span class=\"hljs-attr\">fontSize:<\/span> <span class=\"hljs-attr\">50<\/span>,\n                  <span class=\"hljs-attr\">fontWeight:<\/span> '<span class=\"hljs-attr\">bold<\/span>',\n                  <span class=\"hljs-attr\">text:<\/span> `<span class=\"hljs-attr\">from<\/span> ${<span class=\"hljs-attr\">name<\/span>}`,\n                }}\n              \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span>\n                <span class=\"hljs-attr\">flags<\/span>=<span class=\"hljs-string\">'layer_apply'<\/span>\n                <span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">'center'<\/span>\n                <span class=\"hljs-attr\">x<\/span>=<span class=\"hljs-string\">'450'<\/span>\n                <span class=\"hljs-attr\">y<\/span>=<span class=\"hljs-string\">'350'<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Image<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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 snippet above does the following:<\/p>\n<ul>\n<li>Imports the required dependencies<\/li>\n<li>The <code>Card<\/code> component accepts <code>message<\/code>, <code>name<\/code>, and <code>publicId<\/code> props.<\/li>\n<li>Configure <code>CloudinaryContext<\/code>, <code>Image<\/code>, and <code>Transformation<\/code>s to render the image, message, and name.\nWe also leverage Cloudinary\u2019s support for multiple transformations to transform the image. We added the following transformations, <strong>cropping<\/strong>, <strong>blurring<\/strong>, <strong>brightening<\/strong>, adding overlays for <strong>text<\/strong>, <strong>text position<\/strong>**,** <strong>text properties<\/strong>, and <strong>flags<\/strong> to alter the positioning of the text.<\/li>\n<\/ul>\n<p>Then we need to update <code>index.js<\/code> by conditionally rendering the <code>Card.js<\/code> component as shown below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/imports here<\/span>\n    <span class=\"hljs-keyword\">import<\/span> { Card } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/components\/Card'<\/span>; <span class=\"hljs-comment\">\/\/add<\/span>\n    \n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n      <span class=\"hljs-comment\">\/\/states here<\/span>\n    \n      <span class=\"hljs-keyword\">const<\/span> handleChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n        <span class=\"hljs-comment\">\/\/handle change codes here<\/span>\n      };\n      \n      <span class=\"hljs-comment\">\/\/add<\/span>\n      <span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n        e.preventDefault();\n        <span class=\"hljs-keyword\">if<\/span> (imageId) {\n          setShowCard(<span class=\"hljs-literal\">true<\/span>);\n        } <span class=\"hljs-keyword\">else<\/span> {\n          setFormData({ ...formData, <span class=\"hljs-attr\">error<\/span>: <span class=\"hljs-literal\">true<\/span> });\n        }\n      };\n    \n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'p-10'<\/span>&gt;<\/span>\n          {\/* Head JSX comes here *\/}\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">''<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'text-3xl'<\/span>&gt;<\/span>Holiday Card Generator<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'flex border-b-2 mt-7 mb-7'<\/span>&gt;<\/span>\n              {\/* Header contents JSX comes here *\/}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{handleSubmit}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'lg:w-2\/5'<\/span>&gt;<\/span> {\/* add handleSubmit *\/}\n              {\/* Form contents JSX comes here *\/}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n    \n            {\/* Conditionally render card Components *\/}\n            {showCard &amp;&amp; (\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'mt-10'<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Card<\/span>\n                  <span class=\"hljs-attr\">message<\/span>=<span class=\"hljs-string\">{formData.message}<\/span>\n                  <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">{formData.name}<\/span>\n                  <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{formData.publicId}<\/span>\n                \/&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            )}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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 snippet above, we imported the <code>Card<\/code> component, created an <code>handleSubmit<\/code> function that checks if an image is selected, and then conditionally renders the <code>Card<\/code> component with necessary props.<\/p>\n<p><strong>Complete index.js<\/strong><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/736120f6f74832e3f1a3d1e21734529c\">https:\/\/gist.github.com\/Mr-Malomz\/736120f6f74832e3f1a3d1e21734529c<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/736120f6f74832e3f1a3d1e21734529c\">https:\/\/gist.github.com\/Mr-Malomz\/736120f6f74832e3f1a3d1e21734529c<\/a><\/p>\n<p>We can test our application by starting the development server and creating different holiday cards.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635421283900_screencapture-localhost-3000-2021-10-28-12_40_06.png\" alt=\"Working application\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"2015\"\/><\/p>\n<h2>Adding a shareable link support<\/h2>\n<p>Our card is incomplete if we can\u2019t share it with friends and family. To do this, we need to modify the <code>Card.js<\/code> file as shown below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/imports here<\/span>\n    \n    <span class=\"hljs-keyword\">import<\/span> { useEffect, useRef, useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>; <span class=\"hljs-comment\">\/\/add<\/span>\n    \n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> Card = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ message, name, publicId }<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> ref = useRef(<span class=\"hljs-literal\">null<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;url, setURL] = useState(<span class=\"hljs-string\">''<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;copy, setCopy] = useState(<span class=\"hljs-string\">'Copy File'<\/span>);\n    \n      useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        setURL(ref.current.element.current.src);\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {};\n      }, &#91;]);\n    \n      <span class=\"hljs-keyword\">const<\/span> handleCopyToClip = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        navigator.clipboard\n          .writeText(url)\n          .then(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> setCopy(<span class=\"hljs-string\">'Copied!'<\/span>))\n          .catch(<span class=\"hljs-function\">(<span class=\"hljs-params\">err<\/span>) =&gt;<\/span> <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'error copying to clipboard'<\/span>, err));\n      };\n    \n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">'dtgbzmpca'<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Image<\/span> <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{publicId}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{1000}<\/span> <span class=\"hljs-attr\">ref<\/span>=<span class=\"hljs-string\">{ref}<\/span>&gt;<\/span> {\/* add ref *\/}\n              {\/* Transformation JSX comes here *\/}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Image<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span>\n          \n          {\/* Shareable link below *\/}\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'mt-10'<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h5<\/span>&gt;<\/span>Shareable link<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h5<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">disabled<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{url}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'w-full lg:w-2\/5 h-10 border-&#91;#B7B3B3] border rounded-sm p-2 mr-4'<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'bg-gray-600 py-2 px-6 rounded-&#91;5px] text-white font-semibold'<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{handleCopyToClip}<\/span>&gt;<\/span>\n              {copy}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    };\n    \n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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 snippet above does the following:<\/p>\n<ul>\n<li>Imports required dependencies<\/li>\n<li>Create states and <code>ref<\/code> to access the Image DOM element<\/li>\n<li>Update the <code>url<\/code> by accessing the <code>src<\/code> property Cloudinary passed to the <code>Image<\/code> component on render.<\/li>\n<li>\n<code>handleCopyToClip<\/code> function that uses <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Clipboard\/writeText\">Clipboard API<\/a> to copy the returned URL on our device clipboard<\/li>\n<li>Add <code>ref<\/code> to the <code>Image<\/code> component and markups for sharing links<\/li>\n<\/ul>\n<p><strong>Complete Card.js<\/strong><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/87331d334f787cd75b6ce16d4b87e8f1\">https:\/\/gist.github.com\/Mr-Malomz\/87331d334f787cd75b6ce16d4b87e8f1<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Mr-Malomz\/87331d334f787cd75b6ce16d4b87e8f1\">https:\/\/gist.github.com\/Mr-Malomz\/87331d334f787cd75b6ce16d4b87e8f1<\/a><\/p>\n<p>The final output of our application should look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_09154C99BD025007588E7E863D13AB13FE936D0B55FA69EF06F32C362371F6D6_1635421382079_screencapture-localhost-3000-2021-10-28-12_40_22.png\" alt=\"Working application with shareable link\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1993\" height=\"2160\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>This post discussed how to build a holiday card generator using Cloudinary\u2019s image transformation and Next.js.<\/p>\n<p>You may find these resources helpful:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations\">Cloudinary Image Transformation<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/tailwindcss.com\/\">TailwindCSS<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Clipboard\/writeText\">Browser clipboard<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27960,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,212,246,371],"class_list":["post-27959","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-next-js","tag-react","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Create a Holiday Card Generator<\/title>\n<meta name=\"description\" content=\"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create a Holiday Card Generator\" \/>\n<meta property=\"og:description\" content=\"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-11-01T19:04:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"5331\" \/>\n\t<meta property=\"og:image:height\" content=\"3554\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Create a Holiday Card Generator\",\"datePublished\":\"2021-11-01T19:04:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\"},\"wordCount\":5,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"Next.js\",\"React\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\",\"name\":\"Create a Holiday Card Generator\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA\",\"datePublished\":\"2021-11-01T19:04:06+00:00\",\"description\":\"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA\",\"width\":5331,\"height\":3554},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create a Holiday Card Generator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Create a Holiday Card Generator","description":"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/","og_locale":"en_US","og_type":"article","og_title":"Create a Holiday Card Generator","og_description":"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-11-01T19:04:06+00:00","og_image":[{"width":5331,"height":3554,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/"},"author":{"name":"","@id":""},"headline":"Create a Holiday Card Generator","datePublished":"2021-11-01T19:04:06+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/"},"wordCount":5,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","keywords":["Guest Post","Image","Next.js","React","Under Review"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/","name":"Create a Holiday Card Generator","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","datePublished":"2021-11-01T19:04:06+00:00","description":"Build a holiday card generator for Harvest Season, Diwali and Thanksgiving.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","width":5331,"height":3554},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/create-a-holiday-card-generator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create a Holiday Card Generator"}]},{"@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\/v1681925810\/Web_Assets\/blog\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2\/052be250ad40a5a2eb606c0d7dc5619a7522ef91-5331x3554-1_27960a79d2.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27959","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=27959"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27959\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27960"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27959"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27959"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}