{"id":39760,"date":"2026-01-29T07:00:00","date_gmt":"2026-01-29T15:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=39760"},"modified":"2026-01-29T14:35:52","modified_gmt":"2026-01-29T22:35:52","slug":"demotivational-posters-tanstack-next-js","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js","title":{"rendered":"DRY January: Demotivational Posters With the TANStack or Next.js"},"content":{"rendered":"\n<p>January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more&#8230; more exercise, a more rigorous diet, even more mindfulness, doggone it! But what if we (and hear me out) instead thought about doing <em>less<\/em>? Less struggling against those 4 p.m. sugar cravings, less fighting against the after-lunch nap, less battling frozen driveways to back the car out so you can make it to pilates.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707523\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-1.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">I don&#8217;t know if this is creepy or inspiring, but let&#8217;s build it anyway.<\/figcaption><\/figure>\n\n\n\n<p>What if we embraced our inner zen and simply&#8230;did our best? After all, isn\u2019t all the productivity that AI is bestowing upon us freeing up our time to do less, rather than more? I\u2019m only half-kidding here.<\/p>\n\n\n\n<p>To encourage us to embrace a reductionist mentality, I did a little experiment to see if I could rethink some popular messaging that I\u2019m sure you encountered if you ever worked in an American corporate office in the early 2000s: motivational posters.<\/p>\n\n\n\n<p>These little gems were plastered on the walls to exhort us to &#8220;Bring Our Best Selves to Work, Achieve More, and Be Bold.&#8221; Here\u2019s an example from <a href=\"https:\/\/www.successories.com\/\">Successories<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707523\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-2.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>As you can see, they have a particular format of a black background, an inspiring photo, an uplifting word with a lot of kerning, and a blurb at the bottom to drive the message home. A <strong>Whole Vibe<\/strong> was created as you walked down a poster-adorned corridor to toss your bag lunch into the office fridge.<\/p>\n\n\n\n<p>I particularly like this wolf. This is me.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707523\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-3.png\" alt=\"\"\/><\/figure><\/div>\n\n\n<p>Even back in those days, people made fun of these posters, and I remember being employed in one company packed with sarcastic Eastern Europeans that was instead decorated with <em>demotivational<\/em> posters such as those crafted by the brilliant <a href=\"https:\/\/despair.com\/\">Despair.inc<\/a>. Here\u2019s a good one:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707523\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-4.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The problem with all of these posters is that, well, you have to buy them, and that\u2019s no fun. So let\u2019s see if we can build something like this ourselves, and actually make it a more surprising experience by connecting two APIs to generate shady messaging like this at random.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707524\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-5.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Not sure what &#8220;this&#8221; is, but you got it!<\/figcaption><\/figure>\n\n\n\n<p>Temporarily shelve that resolution against unproductive and negative thinking and let\u2019s see what we can build using:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Affirmations API.<\/li>\n\n\n\n<li>Unsplash API.<\/li>\n\n\n\n<li>TANStack for a web frontend.<\/li>\n\n\n\n<li>Cloudinary image storage to display the image so you can print off a PDF of your poster.<\/li>\n<\/ul>\n\n\n\n<p>You&#8217;ll need two API keys, one for the ever-useful affirmations.dev API and one for Unsplash images. You&#8217;ll also need a Cloudinary account, so <a href=\"https:\/\/cloudinary.com\/?utm_campaign=5266-&amp;utm_medium=employee_referral&amp;utm_source=dev-dot-to&amp;utm_content=dry-january\">create one for free here<\/a> if you aren&#8217;t already setup. You&#8217;ll then need to gather your Cloudinary API key, secret, and cloud name, and build an upload preset so that you can upload images neatly into Cloudinary. <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Learn how to get credentials <a href=\"https:\/\/cloudinary.com\/documentation\/developer_onboarding_faq_find_credentials?utm_campaign=5266-&amp;utm_medium=employee_referral&amp;utm_source=dev-dot-to&amp;utm_content=dry-january#banner\">here<\/a> and how to create an upload preset <a href=\"https:\/\/cloudinary.com\/documentation\/upload_presets?utm_campaign=5266-&amp;utm_medium=employee_referral&amp;utm_source=dev-dot-to&amp;utm_content=dry-january#creating_and_managing_upload_presets\">here<\/a>.<\/p>\n<\/blockquote>\n\n\n\n<p>We\u2019ll grab one of the pithy affirmations from the API, extract the longest word as the central message to display with plenty of kerning, and then send that word to Unsplash to find a match. Store the image returned in Cloudinary and display the lot a as a printable poster, as a stacked image, word, and affirmation on a black background, like this one:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707524\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-6.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">The miracle of survival.<\/figcaption><\/figure>\n\n\n\n<p>Continuing my tradition of building useless things to try new stacks, let\u2019s give <a href=\"https:\/\/tanstack.com\/\">TANStack<\/a> a whirl. TANStack is a React framework that&#8217;s pitched as a less &#8220;magical&#8221; alternative to Next.js. I also built this same app using Next.js, to compare the two codebases, for learning purposes.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Check out the GitHub repo with the two apps <a href=\"https:\/\/github.com\/jlooper\/affirmation-posters\">here<\/a>.<\/p>\n<\/blockquote>\n\n\n\n<p>Disclosure: I used Cursor to help build the two comparable apps in the demo repo. According to Cursor, the difference between the two boils down to your personal dev preference:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Next.js is a full-stack framework with conventions and a large ecosystem.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>TanStack Router\/Start is a type-safe, flexible routing solution that can be extended to full-stack.<\/li>\n<\/ul>\n\n\n\n<p>The choice often comes down to preferring conventions (Next.js) vs. flexibility and type safety (TanStack).<\/p>\n\n\n\n<p>Some differences between these two frameworks in the context of this app include:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Server-Side Data Fetching Architecture<\/h2>\n\n\n\n<p>Next.js:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uses Server Actions (&#8220;use server&#8221;) and async Server Components.<\/li>\n\n\n\n<li>Server actions in <code>actions.ts<\/code> are callable from both server and client TanStack.<\/li>\n\n\n\n<li>Uses route loaders and <code>createServerFn<\/code> for server functions.<\/li>\n\n\n\n<li>Data fetching happens in the route&#8217;s loader function.<\/li>\n\n\n\n<li>Loaders run on the server before the component renders.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Environment Variable Access<\/h2>\n\n\n\n<p>Next.js:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uses <code>process.env.*<\/code> for environment variables.<\/li>\n\n\n\n<li>Variables are available on the server by default TanStack.<\/li>\n\n\n\n<li>Uses <code>import.meta.env.VITE_*<\/code> (Vite convention).<\/li>\n\n\n\n<li>Only variables prefixed with <code>VITE_<\/code> are exposed to the client <code>buildCloudinaryUrl.ts<\/code>, because this app was built with Vite as its build tool.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Difference in Image Handling<\/h2>\n\n\n\n<p>Next.js:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Images are displayed using the built-in optimized component TanStack.<\/li>\n\n\n\n<li>TanStack doesn&#8217;t have such a component built-in, so you&#8217;ll need to make sure to optimize your images! This is consistent with its &#8220;magic-free&#8221; approach.<\/li>\n<\/ul>\n\n\n\n<p>Guess what! You can easily optimize your images in Cloudinary. While there are <a href=\"https:\/\/cloudinary.com\/blog\/how-to-build-a-tanstack-start-project-for-image-optimization-and-uploading?utm_campaign=5266-&amp;utm_medium=employee_referral&amp;utm_source=dev-dot-to&amp;utm_content=dry-january\">other ways to do this<\/a>, I decided to just add some URL transformations to the Cloudinary URL returned once the Unsplash image is uploaded:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">buildCloudinaryImageUrl<\/span>(<span class=\"hljs-params\">publicId: string<\/span>): <span class=\"hljs-title\">string<\/span> <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> cloudName = <span class=\"hljs-keyword\">import<\/span>.meta.env.VITE_CLOUDINARY_CLOUD_NAME\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (!cloudName) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">'Cloudinary cloud name not configured'<\/span>)\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> plainPublicId = publicId\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> transformations = &#91;\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-string\">`c_fill,w_1200,h_800`<\/span>, <span class=\"hljs-comment\">\/\/ Fill to 1200x800 for poster feel<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-string\">`f_auto`<\/span>, <span class=\"hljs-comment\">\/\/ Auto format<\/span>\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-string\">`q_auto`<\/span>, <span class=\"hljs-comment\">\/\/ Auto quality<\/span>\n\n\u00a0\u00a0].join(<span class=\"hljs-string\">'\/'<\/span>)\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Return the complete Cloudinary URL with transformations `https:\/\/res.cloudinary.com\/${cloudName}\/image\/upload\/${transformations}\/${plainPublicId}`<\/span>\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now you&#8217;re able to grab an affirmation from the API and use it to query Unsplash, storing the result into Cloudinary and using it to build your poster. In TANStack it looks like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> fetchNewAffirmationData = createServerFn({\n\n\u00a0\u00a0<span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">'GET'<\/span>,\n\n}).handler(<span class=\"hljs-keyword\">async<\/span> (): <span class=\"hljs-built_in\">Promise<\/span>&lt;AffirmationData&gt; =&gt; {\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ First fetch the affirmation<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> affirmationData = <span class=\"hljs-keyword\">await<\/span> getAffirmation()\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Extract the longest word from the affirmation to use as image search query<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> words = affirmationData.affirmation.split(<span class=\"hljs-string\">' '<\/span>).filter(<span class=\"hljs-function\"><span class=\"hljs-params\">word<\/span> =&gt;<\/span> word.length &gt; <span class=\"hljs-number\">0<\/span>)\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> longestWord = words.reduce(<span class=\"hljs-function\">(<span class=\"hljs-params\">longest, current<\/span>) =&gt;<\/span>\u00a0\n\n\u00a0\u00a0\u00a0\u00a0current.length &gt; longest.length ? current : longest, <span class=\"hljs-string\">''<\/span>\n\n\u00a0\u00a0).toLowerCase()\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Fetch an image based on the longest word<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> accessKey = <span class=\"hljs-keyword\">import<\/span>.meta.env.VITE_UNSPLASH_ACCESS_KEY\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (!accessKey) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">'Unsplash access key not configured'<\/span>)\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> unsplashResponse = <span class=\"hljs-keyword\">await<\/span> fetch(\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-string\">`https:\/\/api.unsplash.com\/photos\/random?client_id=<span class=\"hljs-subst\">${accessKey}<\/span>&amp;orientation=landscape&amp;query=<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">encodeURIComponent<\/span>(longestWord)}<\/span>`<\/span>\n\n\u00a0\u00a0)\n\n\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (!unsplashResponse.ok) {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">'Failed to fetch Unsplash photo'<\/span>)\n\n\u00a0\u00a0}\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> unsplashData = <span class=\"hljs-keyword\">await<\/span> unsplashResponse.json() <span class=\"hljs-keyword\">as<\/span> { <span class=\"hljs-attr\">id<\/span>: string; urls: { <span class=\"hljs-attr\">full<\/span>: string } }\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Upload the Unsplash image to Cloudinary<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> publicId = <span class=\"hljs-keyword\">await<\/span> uploadToCloudinary(unsplashData.urls.full)\n\n\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Build the Cloudinary URL with transformations<\/span>\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> cloudinaryUrl = buildCloudinaryImageUrl(publicId)\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">affirmation<\/span>: affirmationData.affirmation,\n\n\u00a0\u00a0\u00a0\u00a0longestWord,\n\n\u00a0\u00a0\u00a0\u00a0cloudinaryUrl,\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-attr\">photoId<\/span>: unsplashData.id,\n\n\u00a0\u00a0\u00a0\u00a0publicId,\n\n\u00a0\u00a0}\n\n})<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And once you have all your pieces in place, you&#8217;ll be able to view that matching affirmation, image, and printable styling all in one place so you can build a PDF poster:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">const handlePrint = () =&gt; {\n\n\u00a0\u00a0\u00a0\u00a0if (posterRef.current) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const printWindow = window.open('', '_blank')\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (printWindow) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0printWindow.document.write(`\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Affirmation Poster<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span><span class=\"css\">\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0..<span class=\"hljs-selector-class\">.some<\/span> <span class=\"hljs-selector-tag\">fancy<\/span> <span class=\"hljs-selector-tag\">styling<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"poster-container\"<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"${imageUrl}\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"${affirmation}\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"poster-image\"<\/span> \/&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>${longestWordWithDots}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"poster-line\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>${affirmation}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0printWindow.document.close()\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Wait for image to load before printing\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setTimeout(() =&gt; {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0printWindow.focus()\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0printWindow.print()\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0printWindow.onafterprint = () =&gt; printWindow.close()\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}, 250)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>So there you have it&#8230;you&#8217;ve built a delightfully useless little app that combines a few API calls with optimized image presentation to make you feel a little less seasonally-affected, we hope.<\/p>\n\n\n\n<p>Happy New Year! If you liked this little app, there are plenty more where it comes from from your friends at Cloudinary Developer Relations.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1769707525\/blog-Demotivational_Posters_with_the_TANStack_or_Next.js-7.png\" alt=\"\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more&#8230; more exercise, a more rigorous diet, even more mindfulness, doggone it! But what if we (and hear me out) instead thought about doing less? Less struggling against those 4 [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":39770,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[367,370,165,212],"class_list":["post-39760","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-dev-rel","tag-image","tag-image-transformation","tag-next-js"],"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>DRY January: Demotivational Posters With the TANStack or Next.js<\/title>\n<meta name=\"description\" content=\"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous\" \/>\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\/demotivational-posters-tanstack-next-js\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DRY January: Demotivational Posters With the TANStack or Next.js\" \/>\n<meta property=\"og:description\" content=\"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-29T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-29T22:35:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\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\/demotivational-posters-tanstack-next-js#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"DRY January: Demotivational Posters With the TANStack or Next.js\",\"datePublished\":\"2026-01-29T15:00:00+00:00\",\"dateModified\":\"2026-01-29T22:35:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\"},\"wordCount\":1022,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA\",\"keywords\":[\"Dev Rel\",\"Image\",\"Image Transformation\",\"Next.js\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\",\"url\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\",\"name\":\"DRY January: Demotivational Posters With the TANStack or Next.js\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA\",\"datePublished\":\"2026-01-29T15:00:00+00:00\",\"dateModified\":\"2026-01-29T22:35:52+00:00\",\"description\":\"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DRY January: Demotivational Posters With the TANStack or Next.js\"}]},{\"@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\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"DRY January: Demotivational Posters With the TANStack or Next.js","description":"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous","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\/demotivational-posters-tanstack-next-js","og_locale":"en_US","og_type":"article","og_title":"DRY January: Demotivational Posters With the TANStack or Next.js","og_description":"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous","og_url":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js","og_site_name":"Cloudinary Blog","article_published_time":"2026-01-29T15:00:00+00:00","article_modified_time":"2026-01-29T22:35:52+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"DRY January: Demotivational Posters With the TANStack or Next.js","datePublished":"2026-01-29T15:00:00+00:00","dateModified":"2026-01-29T22:35:52+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js"},"wordCount":1022,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","keywords":["Dev Rel","Image","Image Transformation","Next.js"],"inLanguage":"en-US","copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js","url":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js","name":"DRY January: Demotivational Posters With the TANStack or Next.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","datePublished":"2026-01-29T15:00:00+00:00","dateModified":"2026-01-29T22:35:52+00:00","description":"January can be a time when we make all the resolutions to do and be better in the shiny new year. We resolve to do more... more exercise, a more rigorous","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/demotivational-posters-tanstack-next-js#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"DRY January: Demotivational Posters With the TANStack or Next.js"}]},{"@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":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1769712212\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js\/Blog_DRY_January_Demotivational-Posters-with-the-TanStack-or-Next_js.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39760","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\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=39760"}],"version-history":[{"count":2,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39760\/revisions"}],"predecessor-version":[{"id":39771,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39760\/revisions\/39771"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/39770"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=39760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=39760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=39760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}