{"id":27799,"date":"2022-06-29T08:51:42","date_gmt":"2022-06-29T08:51:42","guid":{"rendered":"http:\/\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary"},"modified":"2022-06-29T08:51:42","modified_gmt":"2022-06-29T08:51:42","slug":"dynamic-blog-thumbnails-wt-netlify-and-cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","title":{"rendered":"Dynamic Blog Thumbnails with Netlify and Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>If you own a personal blog or maintain your company\u2019s blog, you will often find yourself creating OG images, thumbnails, and graphics for publishing every new blog post. This is very routine and very repetitive. Hence, it can be automated.<\/p>\n<p>In this post, we\u2019ll show you how to automatically generate your blog post images and thumbnails from Cloudinary when you supply the post title and author to a Netlify function.<\/p>\n<h3>Technologies<\/h3>\n<p><strong>Netlify Functions<\/strong> allow us to deploy server-side code that works as API endpoints, runs automatically in response to events, or processes more complex jobs in the background. Very recently, Netlify functions offering has grown with the addition of new features like functions scheduling (CRON) and Edge functions which we\u2019ll talk about in a later post.<\/p>\n<p><strong><a href=\"http:\/\/cloudinary.com\">Cloudinary<\/a><\/strong> allows us to transform images and videos to load faster with no visual degradation. With Cloudinary, you can automatically generate image and video variants, and deliver high-quality responsive experiences to increase conversions.<\/p>\n<h2>Sandbox<\/h2>\n<p>If you\u2019d like to get a headstart by looking at the finished demo, I\u2019ve got it set up here on Codesandbox for you!<\/p>\n<p>We completed this project in a <a href=\"https:\/\/codesandbox.io\/embed\/serverless-thumbnail-generator-xkklgt\">CodeSandbox<\/a>. Fork and run it to quickly get started.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/serverless-thumbnail-generator-xkklgt?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=\"Generating dynamic blog thumbnails\"\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>This post requires the following:<\/p>\n<ul>\n<li>Experience with JavaScript and React.js<\/li>\n<li>Installation of Node.js<\/li>\n<li>Next.js<\/li>\n<li>A Cloudinary account. <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Signup<\/a>\n<\/li>\n<\/ul>\n<h2>Setup and Installations<\/h2>\n<p>First, we will create a Next.js boilerplate with the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-next-app blog-thumbnail\n<\/code><\/span><\/pre>\n<p>Next, we\u2019ll navigate into the project directory and install <a href=\"https:\/\/yarnpkg.com\/package\/netlify-cli\">netlify-cli<\/a> with the following command:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">cd blog-thumbnail\nyarn add netlify-cli -g <span class=\"hljs-comment\"># installs Netlify CLI globally<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, let\u2019s also install the following yarn packages:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/yarnpkg.com\/package\/cloudinary\">Cloudinary<\/a> &#8211; So we can interact with the Cloudinary APIs.<\/li>\n<li>\n<a href=\"https:\/\/yarnpkg.com\/package\/bootstrap\">Bootstrap<\/a> \u2013 To handle our project styling.<\/li>\n<li>\n<a href=\"https:\/\/yarnpkg.com\/package\/file-saver\">File-saver<\/a> &#8211; Help save the generated thumbnail.<\/li>\n<\/ul>\n<p>The following command installs the above packages:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">yarn add cloudinary bootstrap file-saver\n<\/code><\/span><\/pre>\n<h2>Generating thumbnails via Netlify function<\/h2>\n<p>Next, create a <code>netlify.toml<\/code> file in the root directory and add the snippet below to read form input and generate the post thumbnail. For a start, update the <code>toml<\/code> file with this snippet:<\/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\">&#91;build]\n    functions = <span class=\"hljs-string\">\"functions\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The above snippet tells Netlify where our functions will be located. In the terminal, run the following command to start the dev server:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">netlify dev\n<\/code><\/span><\/pre>\n<p>Netlify will start a live dev server at <code>http:\/\/localhost:8888<\/code> and we should see the project on that address in the browser.<\/p>\n<p>Next, let\u2019s create a <code>functions<\/code> folder in the root directory with a <code>thumbnail.js<\/code> file and add the following snippet:<\/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\">\/\/ functions\/thumbnail.js<\/span>\n<span class=\"hljs-keyword\">const<\/span> Cloudinary = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"cloudinary\"<\/span>).v2;\n<span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">\"dotenv\"<\/span>).config();\n    \n<span class=\"hljs-keyword\">const<\/span> handler = <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> { title, author } = <span class=\"hljs-built_in\">JSON<\/span>.parse(event.body);\n    \n  <span class=\"hljs-keyword\">let<\/span> today = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>();\n  <span class=\"hljs-keyword\">let<\/span> date =\n    today.getFullYear() + <span class=\"hljs-string\">\"-\"<\/span> + (today.getMonth() + <span class=\"hljs-number\">1<\/span>) + <span class=\"hljs-string\">\"-\"<\/span> + today.getDate();\n    \n  <span class=\"hljs-keyword\">try<\/span> {\n    Cloudinary.config({\n      <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUD_NAME,\n      <span class=\"hljs-attr\">api_key<\/span>: process.env.API_KEY,\n      <span class=\"hljs-attr\">api_secret<\/span>: process.env.API_SECRET,\n      <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span>\n    });\n    \n    <span class=\"hljs-keyword\">const<\/span> imageTransform = Cloudinary.url(<span class=\"hljs-string\">\"banners\/banner.png\"<\/span>, {\n      <span class=\"hljs-attr\">transformation<\/span>: &#91;\n         <span class=\"hljs-comment\">\/\/ base image resize<\/span>\n        {\n          <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">720<\/span>,\n          <span class=\"hljs-attr\">height<\/span>: <span class=\"hljs-number\">360<\/span>,\n          <span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">\"scale\"<\/span>\n        },\n        <span class=\"hljs-comment\">\/\/ Post Title overlay<\/span>\n        {\n          <span class=\"hljs-attr\">overlay<\/span>: {\n            <span class=\"hljs-attr\">font_family<\/span>: <span class=\"hljs-string\">\"Neucha\"<\/span>,\n            <span class=\"hljs-attr\">font_size<\/span>: <span class=\"hljs-number\">40<\/span>,\n            <span class=\"hljs-attr\">font_weight<\/span>: <span class=\"hljs-string\">\"bold\"<\/span>,\n            <span class=\"hljs-attr\">text<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${title}<\/span>`<\/span>\n          },\n          <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">400<\/span>,\n          <span class=\"hljs-attr\">height<\/span>: <span class=\"hljs-number\">200<\/span>,\n          <span class=\"hljs-attr\">opacity<\/span>: <span class=\"hljs-number\">100<\/span>,\n          <span class=\"hljs-attr\">gravity<\/span>: <span class=\"hljs-string\">\"center\"<\/span>,\n          <span class=\"hljs-attr\">x<\/span>: <span class=\"hljs-number\">35<\/span>,\n          <span class=\"hljs-attr\">color<\/span>: <span class=\"hljs-string\">\"#00000098\"<\/span>,\n          <span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">\"fit\"<\/span>\n        },\n          <span class=\"hljs-comment\">\/\/ Post Author Overlay<\/span>\n        {\n          <span class=\"hljs-attr\">overlay<\/span>: {\n            <span class=\"hljs-attr\">font_family<\/span>: <span class=\"hljs-string\">\"Roboto\"<\/span>,\n            <span class=\"hljs-attr\">font_size<\/span>: <span class=\"hljs-number\">14<\/span>,\n            <span class=\"hljs-attr\">font_weight<\/span>: <span class=\"hljs-string\">\"bold\"<\/span>,\n            <span class=\"hljs-attr\">text<\/span>: <span class=\"hljs-string\">`<span class=\"hljs-subst\">${author}<\/span>`<\/span>,\n            <span class=\"hljs-attr\">text_decoration<\/span>: <span class=\"hljs-string\">\"underline\"<\/span>\n          },\n          <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">400<\/span>,\n          <span class=\"hljs-attr\">height<\/span>: <span class=\"hljs-number\">200<\/span>,\n          <span class=\"hljs-attr\">opacity<\/span>: <span class=\"hljs-number\">100<\/span>,\n          <span class=\"hljs-attr\">gravity<\/span>: <span class=\"hljs-string\">\"south_west\"<\/span>,\n          <span class=\"hljs-attr\">x<\/span>: <span class=\"hljs-number\">20<\/span>,\n          <span class=\"hljs-attr\">y<\/span>: <span class=\"hljs-number\">18<\/span>,\n          <span class=\"hljs-attr\">color<\/span>: <span class=\"hljs-string\">\"#fff\"<\/span>,\n          <span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">\"fit\"<\/span>\n        },\n         <span class=\"hljs-comment\">\/\/ Date of creation<\/span>\n        {\n          <span class=\"hljs-attr\">overlay<\/span>: {\n            <span class=\"hljs-attr\">font_family<\/span>: <span class=\"hljs-string\">\"Roboto\"<\/span>,\n            <span class=\"hljs-attr\">font_size<\/span>: <span class=\"hljs-number\">14<\/span>,\n            <span class=\"hljs-attr\">font_weight<\/span>: <span class=\"hljs-string\">\"bold\"<\/span>,\n            <span class=\"hljs-attr\">text<\/span>: <span class=\"hljs-string\">`created at:%250A<span class=\"hljs-subst\">${date}<\/span>`<\/span>,\n            <span class=\"hljs-attr\">text_decoration<\/span>: <span class=\"hljs-string\">\"underline\"<\/span>\n          },\n          <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">400<\/span>,\n          <span class=\"hljs-attr\">height<\/span>: <span class=\"hljs-number\">200<\/span>,\n          <span class=\"hljs-attr\">opacity<\/span>: <span class=\"hljs-number\">100<\/span>,\n          <span class=\"hljs-attr\">gravity<\/span>: <span class=\"hljs-string\">\"south_east\"<\/span>,\n          <span class=\"hljs-attr\">x<\/span>: <span class=\"hljs-number\">20<\/span>,\n          <span class=\"hljs-attr\">y<\/span>: <span class=\"hljs-number\">10<\/span>,\n          <span class=\"hljs-attr\">color<\/span>: <span class=\"hljs-string\">\"#fff\"<\/span>,\n          <span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">\"fit\"<\/span>\n        }\n      ]\n    });\n    \n    <span class=\"hljs-keyword\">return<\/span> {\n      <span class=\"hljs-attr\">statusCode<\/span>: <span class=\"hljs-number\">200<\/span>,\n      <span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({ <span class=\"hljs-attr\">data<\/span>: imageTransform })\n    };\n  } <span class=\"hljs-keyword\">catch<\/span> (error) {\n    <span class=\"hljs-built_in\">console<\/span>.log(error);\n  }\n};\n    \n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the snippet above, we:<\/p>\n<ul>\n<li>Import the Cloudinary package, using the NodeJS require method.<\/li>\n<li>Import the <code>dotenv<\/code> package to handle our environment variables.<\/li>\n<li>Create a handler function that takes in an <em>event<\/em> argument.<\/li>\n<li>Destructure the <code>post author<\/code> and <code>post title<\/code> from the <code>event.body<\/code> object, then  <code>JSON.parse<\/code> it.<\/li>\n<li>Configure our Cloudinary instance with credentials from the Cloudinary dashboard.<\/li>\n<li>Initiate the Cloudinary URL function, which takes in an image path and an array of transformations to be carried out on the base image. In our case, we want to overlay our <code>post title<\/code> and <code>post author<\/code> on the base image.<\/li>\n<\/ul>\n<p>After successfully performing these transformations, Cloudinary returns a URL of the transformed image, which we then store in the <code>imageTransform<\/code> variable.<\/p>\n<h2>Fetch transformed Image<\/h2>\n<p>Next, we need to fetch the returned URL of the transformed image and display it in the browser. To achieve this, lets update the <code>pages\/index.js<\/code> file. The final updates to the file should look like the snippet below:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { saveAs } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"file-saver\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"bootstrap\/dist\/css\/bootstrap.css\"<\/span>;\n    \n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">IndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/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;download, setDownload] = useState(<span class=\"hljs-literal\">false<\/span>);\n    \n  <span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-keyword\">async<\/span> (e) =&gt; {\n    e.preventDefault();\n    \n    <span class=\"hljs-keyword\">const<\/span> userInput = {\n      <span class=\"hljs-attr\">title<\/span>: e.target.title.value,\n      <span class=\"hljs-attr\">author<\/span>: e.target.author.value\n    };\n    \n    <span class=\"hljs-keyword\">const<\/span> body = <span class=\"hljs-built_in\">JSON<\/span>.stringify(userInput);\n    <span class=\"hljs-keyword\">const<\/span> config = {\n      <span class=\"hljs-attr\">headers<\/span>: {\n        <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>\n      }\n    };\n    \n    <span class=\"hljs-keyword\">try<\/span> {\n      <span class=\"hljs-keyword\">if<\/span> (body) {\n        <span class=\"hljs-keyword\">const<\/span> response = <span class=\"hljs-keyword\">await<\/span> axios.post(\n          <span class=\"hljs-string\">\"\/.netlify\/functions\/thumbnail\"<\/span>,\n          body,\n          config\n        );\n        <span class=\"hljs-keyword\">const<\/span> { data } = <span class=\"hljs-keyword\">await<\/span> response.data;\n        setUrl(data);\n        &#91;e.target.name].value = <span class=\"hljs-string\">\"\"<\/span>;\n      }\n    } <span class=\"hljs-keyword\">catch<\/span> (error) {\n      <span class=\"hljs-built_in\">console<\/span>.error(error);\n    }\n  };\n    \n  <span class=\"hljs-keyword\">const<\/span> handleDownload = <span class=\"hljs-keyword\">async<\/span> (e) =&gt; {\n    saveAs(url, <span class=\"hljs-string\">\"thumbnail\"<\/span>);\n    setDownload(<span class=\"hljs-literal\">true<\/span>);\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\">\"\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"navbar navbar-expand-sm navbar-white bg-white\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container align-contents-center p-2\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span>\n            <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"thumbnail-info\"<\/span>\n            <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"row g-3\"<\/span>\n            <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{handleSubmit}<\/span>\n          &gt;<\/span>\n    \n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"title\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"form-label\"<\/span>&gt;<\/span>\n                Post Title\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"title\"<\/span>\n                <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"title\"<\/span>\n                <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span>\n                <span class=\"hljs-attr\">required<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    \n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"author\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"form-label\"<\/span>&gt;<\/span>\n                Author's Name\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n                <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"author\"<\/span>\n                <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"author\"<\/span>\n                <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span>\n                <span class=\"hljs-attr\">required<\/span>\n              \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    \n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"col-12\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn btn-primary btn-lg\"<\/span>&gt;<\/span>\n                Create thumbnail\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\">form<\/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\">nav<\/span>&gt;<\/span>\n    \n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n        {url ? (\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span>\n              <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{url}<\/span>\n              <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"img-thumbnail align-contents-center\"<\/span>\n              <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"transformed banner\"<\/span>\n            \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n                <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{handleDownload}<\/span>\n                <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{download<\/span> ? \"<span class=\"hljs-attr\">btn<\/span> <span class=\"hljs-attr\">btn-success<\/span>\" <span class=\"hljs-attr\">:<\/span> \"<span class=\"hljs-attr\">btn<\/span> <span class=\"hljs-attr\">btn-primary<\/span>\"}\n                <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{download<\/span> ? <span class=\"hljs-attr\">true<\/span> <span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">false<\/span>}\n              &gt;<\/span>\n                {download ? \"Downloaded\" : \"Download\"}\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>\n        ) : (\n          \"\"\n        )}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/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\">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<\/p>\n<ul>\n<li>Import the necessary packages<\/li>\n<li>Create and export our page function.<\/li>\n<li>Return a JSX form containing inputs for the post title, author and a submit button<\/li>\n<li>Create a <code>handleSubmit<\/code> function to handle our form submission logic.<\/li>\n<li>Pass the user data (post title &amp; post author) in a <code>POST<\/code> request using Axios.<\/li>\n<li>Use the <code>useState<\/code> hook to create a state variable called <code>url<\/code> to store our transformed image URL.<\/li>\n<li>Check if the transformed image <code>url<\/code> exists, if it does, we render the image.<\/li>\n<li>Render a <strong>download<\/strong> button to call our <code>handleDownload<\/code> function which in turn downloads the generated thumbnail to our device using the <code>saveAs<\/code> package.<\/li>\n<li>Finally, we used a condition to ensure that the download button is only visible when our function returns <em>URL<\/em> data.<\/li>\n<\/ul>\n<p>When we have the above completed, you should see the following on your browser<\/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_57B1DA5033BC1B020374BC9F50459B514B0D16E820CC1CA9CF2BE21FE6F9EB70_1653081586542_Screenshot+118.png\" alt=\"browser screen\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1022\" height=\"665\"\/><\/p>\n<h2>Conclusion<\/h2>\n<p>Imagine being able to generate thumbnails for all your blog posts just by providing the title of your post and clicking a button. We\u2019ve made that possible in this post as we\u2019ve walked through the process of creating a Next.js application that does just that. Feel free to deploy this project on Netlify or any other deployment platforms of your choice and use it as you see fit.<\/p>\n<h2>Next steps<\/h2>\n<ul>\n<li>Replace the base image with your preferred image<\/li>\n<li>Generate all your thumbnails with ease<\/li>\n<li>Here are some links to learn more about <a href=\"https:\/\/cloudinary.com\/documentation\">Cloudinary<\/a> and <a href=\"https:\/\/www.netlify.com\/products\/functions\/\">Netlify functions<\/a>.<\/li>\n<li>The base image used for this post can be found <a href=\"https:\/\/res.cloudinary.com\/jilis\/image\/upload\/v1650585224\/banners\/banner.png\">here<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27800,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,385,212,371],"class_list":["post-27799","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-netlify","tag-next-js","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Dynamic Blog Thumbnails with Netlify and Cloudinary<\/title>\n<meta name=\"description\" content=\"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.\" \/>\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\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Dynamic Blog Thumbnails with Netlify and Cloudinary\" \/>\n<meta property=\"og:description\" content=\"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-29T08:51:42+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Dynamic Blog Thumbnails with Netlify and Cloudinary\",\"datePublished\":\"2022-06-29T08:51:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Netlify\",\"Next.js\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\",\"name\":\"Dynamic Blog Thumbnails with Netlify and Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA\",\"datePublished\":\"2022-06-29T08:51:42+00:00\",\"description\":\"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA\",\"width\":6000,\"height\":4000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dynamic Blog Thumbnails with Netlify and Cloudinary\"}]},{\"@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":"Dynamic Blog Thumbnails with Netlify and Cloudinary","description":"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.","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\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","og_locale":"en_US","og_type":"article","og_title":"Dynamic Blog Thumbnails with Netlify and Cloudinary","og_description":"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-06-29T08:51:42+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/"},"author":{"name":"","@id":""},"headline":"Dynamic Blog Thumbnails with Netlify and Cloudinary","datePublished":"2022-06-29T08:51:42+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","keywords":["Guest Post","Netlify","Next.js","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","name":"Dynamic Blog Thumbnails with Netlify and Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","datePublished":"2022-06-29T08:51:42+00:00","description":"Learn how to automatically generate blog post OG images and thumbnails from Cloudinary by supplying the post title and description to a Netlify function.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","width":6000,"height":4000},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Dynamic Blog Thumbnails with Netlify and Cloudinary"}]},{"@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":""}]}},"parsely":{"version":"1.1.0","canonical_url":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","smart_links":{"inbound":0,"outbound":0},"traffic_boost_suggestions_count":0,"meta":{"@context":"https:\/\/schema.org","@type":"NewsArticle","headline":"Dynamic Blog Thumbnails with Netlify and Cloudinary","url":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/","mainEntityOfPage":{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA&w=150&h=150&crop=1","image":{"@type":"ImageObject","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA"},"articleSection":"Uncategorized","author":[],"creator":[],"publisher":{"@type":"Organization","name":"Cloudinary Blog","logo":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA"},"keywords":["guest post","netlify","next.js","under review"],"dateCreated":"2022-06-29T08:51:42Z","datePublished":"2022-06-29T08:51:42Z","dateModified":"2022-06-29T08:51:42Z"},"rendered":"<meta name=\"parsely-title\" content=\"Dynamic Blog Thumbnails with Netlify and Cloudinary\" \/>\n<meta name=\"parsely-link\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/dynamic-blog-thumbnails-wt-netlify-and-cloudinary\/\" \/>\n<meta name=\"parsely-type\" content=\"post\" \/>\n<meta name=\"parsely-image-url\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA&w=150&amp;h=150&amp;crop=1\" \/>\n<meta name=\"parsely-pub-date\" content=\"2022-06-29T08:51:42Z\" \/>\n<meta name=\"parsely-section\" content=\"Uncategorized\" \/>\n<meta name=\"parsely-tags\" content=\"guest post,netlify,next.js,under review\" \/>","tracker_url":"https:\/\/cdn.parsely.com\/keys\/cloudinary.com\/p.js"},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924005\/Web_Assets\/blog\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89\/c5ae294d3d8315c58d92552cefc8a49c0ae27d50-6000x4000-1_2780007c89.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27799","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=27799"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27799\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27800"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27799"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27799"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27799"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}