{"id":21406,"date":"2016-08-18T12:10:05","date_gmt":"2016-08-18T12:10:05","guid":{"rendered":"http:\/\/automatic_responsive_images_with_client_hints"},"modified":"2025-08-21T12:22:35","modified_gmt":"2025-08-21T19:22:35","slug":"automatic_responsive_images_with_client_hints","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints","title":{"rendered":"How to Scale an Image Automatically with Client Hints"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><meta http-equiv=\"Accept-CH\" content=\"DPR,Width,Viewport-Width\">\n<p>I\u2019ll start by giving it to you straight:<\/p>\n<p>As part of the recent \u201c<a href=\"https:\/\/cloudinary.com\/blog\/introducing_smart_cropping_intelligent_quality_selection_and_automated_responsive_images\">auto\u2013everything<\/a>\u201d launch, we introduced two new transformation parameters \u2013 <a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automatic_pixel_density_detection\"><code>dpr_auto<\/code><\/a> and <a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automatic_image_width\"><code>w_auto<\/code><\/a>, which pair the <code>DPR<\/code> and <code>Width<\/code>  Client Hints with Cloudinary\u2019s existing image resizing and delivery infrastructure, in order to serve up <em>simple, automatic responsive images<\/em>.<\/p>\n<p>If you\u2019ve spent any time wrestling images into responsive layouts you know that those words \u2014 \u201csimple\u201d, \u201cautomatic\u201d, and <a href=\"https:\/\/cloudinary.com\/blog\/make_all_images_on_your_website_responsive_in_3_easy_steps\">\u201cresponsive images\u201d<\/a> \u2014 are rarely found in honest proximity. So, take a quick peek at <a href=\"http:\/\/ericportis.com\/etc\/w_auto_demo\">the demo<\/a> and allow me give you a glimpse into the future of images on the web.<\/p>\n<p style=\"font-size: 18px; font-weight: bold; text-align: center\">\n<a href=\"http:\/\/ericportis.com\/etc\/w_auto_demo\" data-popup=\"true\" rel=\"nofollow\">Client Hints live demo<\/a>\n<\/p>\n<h2>Mo\u2019 resources, mo\u2019 problems<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/eric-cloudinary\/image\/upload\/q_auto,w_500,dpr_2.0\/matroyshka-heads.png\" alt=\"A cluster of matroyshka heads\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"300\"\/><\/p>\n<p>Along with media queries and fluid grids, \u201cflexible images\u201d are one of the tentpoles of Ethan Marcotte\u2019s  <a href=\"http:\/\/responsivewebdesign.com\">Responsive Web Design<\/a>. And, as Ethan pointed out in the seminal <a href=\"http:\/\/alistapart.com\/article\/fluid-images\">first edition of his book<\/a>, achieving <em>visually<\/em> flexible images is as easy as:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">img<\/span> { <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">100%<\/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\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>For that rule to work though, the image resources backing it up must be big enough to fill large viewports and high-resolution displays. Shoving single-<code>src<\/code> images into responsive layouts means sending <em>gigantic<\/em> resources to <em>everyone<\/em>. Which is a <a href=\"https:\/\/timkadlec.com\/2013\/06\/why-we-need-responsive-images\/\">performance disaster<\/a>.<\/p>\n<p>And so, along came <a href=\"http:\/\/ricg.io\">a suite of new HTML features<\/a> which allow images to <em>adapt<\/em>, ensuring that each user gets a resource that is tailored to their particular context. These features implement a key idea: authors should be able to mark up <em>multiple, alternate resources<\/em>. These features let us transform this bit of ham-fisted responsiveness:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"enormous.jpg\"<\/span> \n     <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"Worst-case performance scenarios for all\"<\/span> \/&gt;<\/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\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>\u2026into an adaptable, multi-headed Hydra:<\/p>\n<pre class=\"js-syntax-highlighted\" 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\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">sizes<\/span>=<span class=\"hljs-string\">\"100vw\"<\/span>\n     <span class=\"hljs-attr\">srcset<\/span>=<span class=\"hljs-string\">\"tiny.jpg      320w,\n             small.jpg     512w,\n             medium.jpg    640w,\n             large.jpg    1024w,\n             huge.jpg     1280w,\n             enormous.jpg 2048w\"<\/span>\n     <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"fallback.jpg\"<\/span> \n     <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"To each according to his ability\"<\/span> \/&gt;<\/span>\n<\/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<p>But this adaptability comes at a price, paid in complexity. Generating, managing, and marking-up two or three (or six) \u201cmultiple, alternate\u201d resources for every image can be both tedious and <a href=\"https:\/\/cloudfour.com\/thinks\/responsive-images-101-part-9-image-breakpoints\/\">fiendishly complex<\/a>. Services like Cloudinary can <a href=\"https:\/\/cloudinary.com\/blog\/responsive_images_with_srcset_sizes_and_cloudinary\">automate the <em>resource generation<\/em> side of the equation<\/a>. But what to do about all of that markup?<\/p>\n<h2>Considering JavaScript<\/h2>\n<p>One answer to that question \u2014 <a href=\"https:\/\/cloudinary.com\/blog\/how_to_automatically_create_images_for_responsive_design\">one that we have embraced and implemented<\/a> \u2014 is: use JavaScript.<\/p>\n<p>Our last example offered the browser an array of options, allowing it to pick the best resource for the current context. A smart bit of JavaScript can <em>directly measure<\/em> the browsing context, and \u2014 when paired with on-the-fly, server-side resizing \u2014 request a single, perfectly-sized resource every time, with little or no extra markup required.<\/p>\n<p>But\u2026 There are some problems with this approach. First, it requires setting up some JavaScript infrastructure, which is a complexity of a different flavor. Second, we\u2019re inserting JavaScript between users and our pages\u2019 <em>core content<\/em>, which <a href=\"https:\/\/twitter.com\/heydonworks\/status\/752471431682879488\">can be tricky to do well<\/a>. Worst of all, though \u2014 as it turns out \u2014 the smart people that make browsers for a living have noticed that <a href=\"http:\/\/httparchive.org\/interesting.php?a=All&amp;l=Jul%2015%202016\">images account for 64% of the web\u2019s bytes<\/a>, and they have gone to Herculean lengths to get those bytes across the wire as quickly as possible. Their main tool in that quest: the <a href=\"http:\/\/andydavies.me\/blog\/2013\/10\/22\/how-the-browser-pre-loader-makes-pages-load-faster\/\">speculative pre-parser<\/a>. In a nutshell, it tries to kick off as many image loads as possible<a href=\"#w_auto_pre_parser\"><sup>[1]<\/sup><\/a> before a page\u2019s HTML has <em>even finished parsing<\/em>. This results in <a href=\"https:\/\/www.stevesouders.com\/blog\/2013\/04\/26\/i\/\">an enormous 20% speed boost<\/a>, and <a href=\"https:\/\/cloudfour.com\/thinks\/the-real-conflict-behind-picture-and-srcset\/\">an intractable problem, when it comes to responsive images<\/a>.<\/p>\n<p>You see, for a JavaScript to load made-to-measure image resources, it must first measure the page \u2014 which means waiting until page layout is complete. This happens long after the pre-parser has raced through the HTML, kicking off image loads with wild abandon. This means that if we wish to use JavaScript to load responsive images, we face a choice. We must either:<\/p>\n<ol>\n<li>let the pre-parser do its thing, and, after a lengthy delay, set our Javascript loose to double-load all of our images, or,<\/li>\n<li>sabotage the pre-parser by authoring invalid, <code>src<\/code>-less <code>&lt;img&gt;<\/code>s so that our JavaScript can, after that same delay, start loading our pages\u2019 images <em>last<\/em>, instead of <em>first<\/em>.<\/li>\n<\/ol>\n<p>Both options present significant compromises; both set us back from achieving our over-arching goal, which is not, after all, simply to load appropriately-sized images. Our larger goal is <em>performance<\/em>.<\/p>\n<h2>Enter Client Hints<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/eric-cloudinary\/image\/upload\/q_auto,w_500,dpr_2.0\/matroyshka-butts.png\" alt=\"A small Matroyshka head popping out of a bunch of nested bottoms\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"300\"\/><\/p>\n<p>So, where does that leave us? Performant, flexible images are inherently complex; marking up multiple, alternate resources can get verbose and complicated; trying to solve the problem with Javascript is fraught with compromise. What other tools do we have at our disposal? Where else can we shift the burden of this complexity?<\/p>\n<p>The idea of Client Hints is: let\u2019s put it on the server! If you\u2019re a front-end developer, Client Hints means making responsive images <em>somebody else\u2019s problem.<\/em> Cloudinary\u2019s pitch to you, front-end-developer, is: make responsive images <em>our<\/em> problem! Leverage our Automatic Width and Automatic DPR features and we\u2019ll handle this stuff so that you don\u2019t have to.<\/p>\n<h2>How to Change Resolution of Image With Automatic DPR<\/h2>\n<p>Here\u2019s a simple, live example:<\/p>\n<p><cld-code-widget\n      class=\" c-code-widget\"\n      snippets=\"[{&quot;sdkId&quot;:&quot;nodejs&quot;,&quot;framework&quot;:&quot;nodejs&quot;,&quot;language&quot;:&quot;nodejs&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Node.js&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;react_2&quot;,&quot;framework&quot;:&quot;react_2&quot;,&quot;language&quot;:&quot;react&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/react&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;react&quot;,&quot;framework&quot;:&quot;react&quot;,&quot;language&quot;:&quot;react&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;Image publicId=\\&quot;bike.jpg\\&quot; useRootPath=\\&quot;true\\&quot;&gt; &lt;Transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt; &lt;\\\/Image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;Image publicId=\\&quot;bike.jpg\\&quot; useRootPath=\\&quot;true\\&quot;&gt;\\n\\t&lt;Transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt;\\n&lt;\\\/Image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React&quot;,&quot;packageName&quot;:&quot;cloudinary-react&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;vue_2&quot;,&quot;framework&quot;:&quot;vue_2&quot;,&quot;language&quot;:&quot;vue&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Vue.js&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/vue&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;vue&quot;,&quot;framework&quot;:&quot;vue&quot;,&quot;language&quot;:&quot;vue&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;cld-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt; &lt;cld-transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt; &lt;\\\/cld-image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;cld-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt;\\n\\t&lt;cld-transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt;\\n&lt;\\\/cld-image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Vue.js&quot;,&quot;packageName&quot;:&quot;cloudinary-vue&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;angular_2&quot;,&quot;framework&quot;:&quot;angular_2&quot;,&quot;language&quot;:&quot;angular&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Angular&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/ng&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;angular&quot;,&quot;framework&quot;:&quot;angular&quot;,&quot;language&quot;:&quot;angular&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;cl-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt; &lt;cl-transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot;&gt; &lt;\\\/cl-transformation&gt; &lt;\\\/cl-image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;cl-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt;\\n\\t&lt;cl-transformation width=\\&quot;512\\&quot; dpr=\\&quot;auto\\&quot; crop=\\&quot;scale\\&quot;&gt;\\n\\t&lt;\\\/cl-transformation&gt;\\n&lt;\\\/cl-image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Angular&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/angular-5.x&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;js_2&quot;,&quot;framework&quot;:&quot;js_2&quot;,&quot;language&quot;:&quot;js&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;JS&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/url-gen&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;js&quot;,&quot;framework&quot;:&quot;js&quot;,&quot;language&quot;:&quot;js&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.imageTag(&#039;bike.jpg&#039;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, useRootPath: true}).toHtml();&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.imageTag(&#039;bike.jpg&#039;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, useRootPath: true}).toHtml();&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;JS&quot;,&quot;packageName&quot;:&quot;cloudinary-core&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;python&quot;,&quot;framework&quot;:&quot;python&quot;,&quot;language&quot;:&quot;python&quot;,&quot;rawCodeSnippet&quot;:&quot;CloudinaryImage(\\&quot;bike.jpg\\&quot;).image(width=512, dpr=\\&quot;auto\\&quot;, crop=\\&quot;scale\\&quot;, use_root_path=True)&quot;,&quot;codeSnippet&quot;:&quot;CloudinaryImage(\\&quot;bike.jpg\\&quot;).image(width=512, dpr=\\&quot;auto\\&quot;, crop=\\&quot;scale\\&quot;, use_root_path=True)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Python&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;php_2&quot;,&quot;framework&quot;:&quot;php_2&quot;,&quot;language&quot;:&quot;php&quot;,&quot;rawCodeSnippet&quot;:&quot;(new ImageTag(&#039;bike.jpg&#039;))\\n\\t-&gt;resize(Resize::scale()-&gt;width(512))\\n\\t-&gt;delivery(Delivery::dpr(\\n\\tDpr::auto()));&quot;,&quot;codeSnippet&quot;:&quot;(new ImageTag(&#039;bike.jpg&#039;))\\n\\t-&gt;resize(Resize::scale()-&gt;width(512))\\n\\t-&gt;delivery(Delivery::dpr(\\n\\tDpr::auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;PHP&quot;,&quot;packageName&quot;:&quot;cloudinary_php&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;3.x&quot;},{&quot;sdkId&quot;:&quot;php&quot;,&quot;framework&quot;:&quot;php&quot;,&quot;language&quot;:&quot;php&quot;,&quot;rawCodeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, array(\\&quot;width\\&quot;=&gt;512, \\&quot;dpr\\&quot;=&gt;\\&quot;auto\\&quot;, \\&quot;crop\\&quot;=&gt;\\&quot;scale\\&quot;, \\&quot;use_root_path\\&quot;=&gt;true))&quot;,&quot;codeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, array(\\&quot;width\\&quot;=&gt;512, \\&quot;dpr\\&quot;=&gt;\\&quot;auto\\&quot;, \\&quot;crop\\&quot;=&gt;\\&quot;scale\\&quot;, \\&quot;use_root_path\\&quot;=&gt;true))&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;PHP&quot;,&quot;packageName&quot;:&quot;cloudinary_php&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;java&quot;,&quot;framework&quot;:&quot;java&quot;,&quot;language&quot;:&quot;java&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.url().transformation(new Transformation().width(512).dpr(\\&quot;auto\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).imageTag(\\&quot;bike.jpg\\&quot;);&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.url().transformation(new Transformation().width(512).dpr(\\&quot;auto\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).imageTag(\\&quot;bike.jpg\\&quot;);&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Java&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;ruby&quot;,&quot;framework&quot;:&quot;ruby&quot;,&quot;language&quot;:&quot;ruby&quot;,&quot;rawCodeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true)&quot;,&quot;codeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Ruby&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;csharp&quot;,&quot;framework&quot;:&quot;csharp&quot;,&quot;language&quot;:&quot;csharp&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(512).Dpr(\\&quot;auto\\&quot;).Crop(\\&quot;scale\\&quot;)).UseRootPath(true).BuildImageTag(\\&quot;bike.jpg\\&quot;)&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(512).Dpr(\\&quot;auto\\&quot;).Crop(\\&quot;scale\\&quot;)).UseRootPath(true).BuildImageTag(\\&quot;bike.jpg\\&quot;)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;.NET&quot;,&quot;packageName&quot;:&quot;CloudinaryDotNet&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;dart&quot;,&quot;framework&quot;:&quot;dart&quot;,&quot;language&quot;:&quot;dart&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(512))\\n\\t.delivery(Delivery.dpr(\\n\\tDpr.auto())));&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(512))\\n\\t.delivery(Delivery.dpr(\\n\\tDpr.auto())));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Dart&quot;,&quot;packageName&quot;:&quot;cloudinary_dart&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;swift&quot;,&quot;framework&quot;:&quot;swift&quot;,&quot;language&quot;:&quot;swift&quot;,&quot;rawCodeSnippet&quot;:&quot;imageView.cldSetImage(cloudinary.createUrl().setUseRootPath( true).setTransformation(CLDTransformation().setWidth(512).setDpr(\\&quot;auto\\&quot;).setCrop(\\&quot;scale\\&quot;)).generate(\\&quot;bike.jpg\\&quot;)!, cloudinary: cloudinary)&quot;,&quot;codeSnippet&quot;:&quot;imageView.cldSetImage(cloudinary.createUrl().setUseRootPath( true).setTransformation(CLDTransformation().setWidth(512).setDpr(\\&quot;auto\\&quot;).setCrop(\\&quot;scale\\&quot;)).generate(\\&quot;bike.jpg\\&quot;)!, cloudinary: cloudinary)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;iOS&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;5.x&quot;},{&quot;sdkId&quot;:&quot;android&quot;,&quot;framework&quot;:&quot;android&quot;,&quot;language&quot;:&quot;android&quot;,&quot;rawCodeSnippet&quot;:&quot;MediaManager.get().url().transformation(new Transformation().width(512).dpr(\\&quot;auto\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).generate(\\&quot;bike.jpg\\&quot;);&quot;,&quot;codeSnippet&quot;:&quot;MediaManager.get().url().transformation(new Transformation().width(512).dpr(\\&quot;auto\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).generate(\\&quot;bike.jpg\\&quot;);&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Android&quot;,&quot;packageName&quot;:&quot;cloudinary-android&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;3.x&quot;},{&quot;sdkId&quot;:&quot;flutter&quot;,&quot;framework&quot;:&quot;flutter&quot;,&quot;language&quot;:&quot;flutter&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(512))\\n\\t.delivery(Delivery.dpr(\\n\\tDpr.auto())));&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(512))\\n\\t.delivery(Delivery.dpr(\\n\\tDpr.auto())));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Flutter&quot;,&quot;packageName&quot;:&quot;cloudinary_flutter&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;kotlin&quot;,&quot;framework&quot;:&quot;kotlin&quot;,&quot;language&quot;:&quot;kotlin&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image {\\n\\tpublicId(\\&quot;bike.jpg\\&quot;)\\n\\t resize(Resize.scale() { width(512) })\\n\\t delivery(Delivery.dpr(\\n\\tDpr.auto())) \\n}.generate()&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image {\\n\\tpublicId(\\&quot;bike.jpg\\&quot;)\\n\\t resize(Resize.scale() { width(512) })\\n\\t delivery(Delivery.dpr(\\n\\tDpr.auto())) \\n}.generate()&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Kotlin&quot;,&quot;packageName&quot;:&quot;kotlin-url-gen&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;jquery&quot;,&quot;framework&quot;:&quot;jquery&quot;,&quot;language&quot;:&quot;jquery&quot;,&quot;rawCodeSnippet&quot;:&quot;$.cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;codeSnippet&quot;:&quot;$.cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: 512, dpr: \\&quot;auto\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;jQuery&quot;,&quot;packageName&quot;:&quot;cloudinary-jquery&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;react_native&quot;,&quot;framework&quot;:&quot;react_native&quot;,&quot;language&quot;:&quot;react_native&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;)\\n  .resize(scale().width(512))\\n  .delivery(dpr(auto()));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React Native&quot;,&quot;packageName&quot;:&quot;cloudinary-react-native&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;}]\"\n      parsed-url=\"{&quot;url&quot;:&quot;https:\\\/\\\/res.cloudinary.com\\\/demo\\\/w_512,dpr_auto\\\/bike.jpg&quot;,&quot;cloud_name&quot;:&quot;demo&quot;,&quot;host&quot;:&quot;res.cloudinary.com&quot;,&quot;type&quot;:&quot;upload&quot;,&quot;resource_type&quot;:&quot;image&quot;,&quot;transformation&quot;:[{&quot;width&quot;:&quot;512&quot;,&quot;dpr&quot;:&quot;auto&quot;}],&quot;transformation_string&quot;:&quot;w_512,dpr_auto&quot;,&quot;url_suffix&quot;:&quot;&quot;,&quot;version&quot;:&quot;&quot;,&quot;secure&quot;:true,&quot;public_id&quot;:&quot;bike.jpg&quot;,&quot;extension&quot;:&quot;jpg&quot;,&quot;format&quot;:&quot;jpg&quot;,&quot;format_code&quot;:true,&quot;url_code&quot;:false,&quot;signature&quot;:&quot;&quot;,&quot;private_cdn&quot;:false,&quot;result_asset_type&quot;:&quot;image&quot;}\"\n      with-url=\"true\"\n    >\n      <span class=\"u-visually-hidden\">Loading code examples<\/span>\n    <\/cld-code-widget><a class=\"c-image-link\" href=\"https:\/\/res.cloudinary.com\/demo\/w_512,dpr_auto\/bike.jpg\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/demo\/w_512,dpr_auto\/bike.jpg\" alt=\"Live Client-Hints responsive image example\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"341\"\/><\/a><\/p>\n<p>The above URL delivers <em>different resources<\/em> to <em>different users<\/em>, <em>depending on their context.<\/em> In <a href=\"http:\/\/caniuse.com\/#feat=client-hints-dpr-width-viewport\">browsers that support Client Hints<\/a> (at the moment, that\u2019s mostly just Chrome), 1x devices will receive 1x resources; 2x screens will receive 2x resources. The above URL responds to varying DPRs automatically.<\/p>\n<p>How? There\u2019s a little tag in the <code>&lt;head&gt;<\/code> of this page which looks like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">http-equiv<\/span>=<span class=\"hljs-string\">\"Accept-CH\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"DPR\"<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>That tells the browser to tack an extra HTTP header named <code>DPR<\/code> onto all of its subsequent requests, advertising the current <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/devicePixelRatio\"><code>devicePixelRatio<\/code><\/a>. Those <code>DPR<\/code> HTTP headers are Client Hints. And smart servers can use them to tailor custom, smart responses. And so, when we opt-in to sending <code>DPR<\/code> Hints with a little <code>meta<\/code> magic, and add <code>dpr_auto<\/code> to our URL, we\u2019re able to deliver different resources to different users depending on the density of their display.<\/p>\n<p>Why else might we want to vary the scale of a resource in response to a fact about the browsing context? I\u2019ll tell you why: to fit flexible, responsive layouts!<\/p>\n<h2>How to Scale an Image with Automatic Width<\/h2>\n<p>Just like <code>dpr_auto<\/code>, <code>w_auto<\/code> sends different users different resources from the same URL. But whereas <code>dpr_auto<\/code> scales images to fit different display densities, <code>w_auto<\/code> scales images to fit variable layout widths. In its simplest form, <code>w_auto<\/code> looks like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">http-equiv<\/span>=<span class=\"hljs-string\">\"Accept-CH\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"DPR, Width\"<\/span>&gt;<\/span>\n\n&#91;\u2026snip\u2026]\n\t\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">sizes<\/span>=<span class=\"hljs-string\">\"100vw\"<\/span>\n     <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/demo\/w_auto\/bike.jpg\"<\/span> \n     <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"Smiling girl with a bike.\"<\/span> \/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>What have we done here?<\/p>\n<p>First, we\u2019ve used our <code>meta<\/code> tag to opt the browser into sending another Client Hint along with its requests: <code>Width<\/code>.<\/p>\n<p>Next, note that our <code>img<\/code> includes a <a href=\"https:\/\/cloudfour.com\/thinks\/responsive-images-101-part-5-sizes\/\"><code>sizes<\/code> attribute<\/a>. This attribute tells the browser the layout width of the image <a href=\"#w_auto_sizes_layout_width\"><sup>[2]<\/sup><\/a> The browser then broadcasts that width to the server, via the <code>Width<\/code> hint. No <code>sizes<\/code>, no <code>Width<\/code>. No <code>Width<\/code>? <code>w_auto<\/code> does nothing. So (besides the opt-in <code>meta<\/code> tag), this is the one additional thing that <code>w_auto<\/code> asks of you: for it to work, you\u2019ll have to stick <code>sizes<\/code> on your <code>img<\/code>s.<\/p>\n<p>Finally, note that I <em>didn\u2019t<\/em> include <code>dpr_auto<\/code> in the URL. I didn\u2019t have to! If we opt into sending both <code>DPR<\/code> and <code>Width<\/code> Hints in the <code>meta<\/code> tag up top, <code>w_auto<\/code> images will be scaled based on both of them.<\/p>\n<p>So \u2014 that\u2019s <code>w_auto<\/code> at its simplest; in Chrome, it just works. But, especially if you\u2019re using the feature in production, you should dive a little deeper.<\/p>\n<h2>Advanced w_auto usage<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/eric-cloudinary\/image\/upload\/q_auto,w_500,dpr_2.0\/matroyshka-advanced.png\" alt=\"Now the matroyshkas are wearing glasses\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"300\"\/><\/p>\n<p><code>w_auto<\/code> can take two optional parameters:<\/p>\n<p><cld-code-widget\n      class=\" c-code-widget\"\n      snippets=\"[{&quot;sdkId&quot;:&quot;nodejs&quot;,&quot;framework&quot;:&quot;nodejs&quot;,&quot;language&quot;:&quot;nodejs&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Node.js&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;react_2&quot;,&quot;framework&quot;:&quot;react_2&quot;,&quot;language&quot;:&quot;react&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/react&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;react&quot;,&quot;framework&quot;:&quot;react&quot;,&quot;language&quot;:&quot;react&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;Image publicId=\\&quot;bike.jpg\\&quot; useRootPath=\\&quot;true\\&quot;&gt; &lt;Transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt; &lt;\\\/Image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;Image publicId=\\&quot;bike.jpg\\&quot; useRootPath=\\&quot;true\\&quot;&gt;\\n\\t&lt;Transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt;\\n&lt;\\\/Image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React&quot;,&quot;packageName&quot;:&quot;cloudinary-react&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;vue_2&quot;,&quot;framework&quot;:&quot;vue_2&quot;,&quot;language&quot;:&quot;vue&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Vue.js&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/vue&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;vue&quot;,&quot;framework&quot;:&quot;vue&quot;,&quot;language&quot;:&quot;vue&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;cld-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt; &lt;cld-transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt; &lt;\\\/cld-image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;cld-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt;\\n\\t&lt;cld-transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot; \\\/&gt;\\n&lt;\\\/cld-image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Vue.js&quot;,&quot;packageName&quot;:&quot;cloudinary-vue&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;angular_2&quot;,&quot;framework&quot;:&quot;angular_2&quot;,&quot;language&quot;:&quot;angular&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Angular&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/ng&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;angular&quot;,&quot;framework&quot;:&quot;angular&quot;,&quot;language&quot;:&quot;angular&quot;,&quot;rawCodeSnippet&quot;:&quot;&lt;cl-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt; &lt;cl-transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot;&gt; &lt;\\\/cl-transformation&gt; &lt;\\\/cl-image&gt;&quot;,&quot;codeSnippet&quot;:&quot;&lt;cl-image public-id=\\&quot;bike.jpg\\&quot; use-root-path=\\&quot;true\\&quot;&gt;\\n\\t&lt;cl-transformation width=\\&quot;auto:100:400\\&quot; crop=\\&quot;scale\\&quot;&gt;\\n\\t&lt;\\\/cl-transformation&gt;\\n&lt;\\\/cl-image&gt;&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Angular&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/angular-5.x&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;js_2&quot;,&quot;framework&quot;:&quot;js_2&quot;,&quot;language&quot;:&quot;js&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;JS&quot;,&quot;packageName&quot;:&quot;@cloudinary\\\/url-gen&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;js&quot;,&quot;framework&quot;:&quot;js&quot;,&quot;language&quot;:&quot;js&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.imageTag(&#039;bike.jpg&#039;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, useRootPath: true}).toHtml();&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.imageTag(&#039;bike.jpg&#039;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, useRootPath: true}).toHtml();&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;JS&quot;,&quot;packageName&quot;:&quot;cloudinary-core&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;python&quot;,&quot;framework&quot;:&quot;python&quot;,&quot;language&quot;:&quot;python&quot;,&quot;rawCodeSnippet&quot;:&quot;CloudinaryImage(\\&quot;bike.jpg\\&quot;).image(width=\\&quot;auto:100:400\\&quot;, crop=\\&quot;scale\\&quot;, use_root_path=True)&quot;,&quot;codeSnippet&quot;:&quot;CloudinaryImage(\\&quot;bike.jpg\\&quot;).image(width=\\&quot;auto:100:400\\&quot;, crop=\\&quot;scale\\&quot;, use_root_path=True)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Python&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;php_2&quot;,&quot;framework&quot;:&quot;php_2&quot;,&quot;language&quot;:&quot;php&quot;,&quot;rawCodeSnippet&quot;:&quot;(new ImageTag(&#039;bike.jpg&#039;))\\n\\t-&gt;resize(Resize::scale()-&gt;width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;(new ImageTag(&#039;bike.jpg&#039;))\\n\\t-&gt;resize(Resize::scale()-&gt;width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;PHP&quot;,&quot;packageName&quot;:&quot;cloudinary_php&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;3.x&quot;},{&quot;sdkId&quot;:&quot;php&quot;,&quot;framework&quot;:&quot;php&quot;,&quot;language&quot;:&quot;php&quot;,&quot;rawCodeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, array(\\&quot;width\\&quot;=&gt;\\&quot;auto:100:400\\&quot;, \\&quot;crop\\&quot;=&gt;\\&quot;scale\\&quot;, \\&quot;use_root_path\\&quot;=&gt;true))&quot;,&quot;codeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, array(\\&quot;width\\&quot;=&gt;\\&quot;auto:100:400\\&quot;, \\&quot;crop\\&quot;=&gt;\\&quot;scale\\&quot;, \\&quot;use_root_path\\&quot;=&gt;true))&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;PHP&quot;,&quot;packageName&quot;:&quot;cloudinary_php&quot;,&quot;packageStatus&quot;:&quot;legacy&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;java&quot;,&quot;framework&quot;:&quot;java&quot;,&quot;language&quot;:&quot;java&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.url().transformation(new Transformation().width(\\&quot;auto:100:400\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).imageTag(\\&quot;bike.jpg\\&quot;);&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.url().transformation(new Transformation().width(\\&quot;auto:100:400\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).imageTag(\\&quot;bike.jpg\\&quot;);&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Java&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;ruby&quot;,&quot;framework&quot;:&quot;ruby&quot;,&quot;language&quot;:&quot;ruby&quot;,&quot;rawCodeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true)&quot;,&quot;codeSnippet&quot;:&quot;cl_image_tag(\\&quot;bike.jpg\\&quot;, width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Ruby&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;csharp&quot;,&quot;framework&quot;:&quot;csharp&quot;,&quot;language&quot;:&quot;csharp&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(\\&quot;auto:100:400\\&quot;).Crop(\\&quot;scale\\&quot;)).UseRootPath(true).BuildImageTag(\\&quot;bike.jpg\\&quot;)&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(\\&quot;auto:100:400\\&quot;).Crop(\\&quot;scale\\&quot;)).UseRootPath(true).BuildImageTag(\\&quot;bike.jpg\\&quot;)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;.NET&quot;,&quot;packageName&quot;:&quot;CloudinaryDotNet&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;dart&quot;,&quot;framework&quot;:&quot;dart&quot;,&quot;language&quot;:&quot;dart&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(\\&quot;auto:100:400\\&quot;)));&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(\\&quot;auto:100:400\\&quot;)));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Dart&quot;,&quot;packageName&quot;:&quot;cloudinary_dart&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;swift&quot;,&quot;framework&quot;:&quot;swift&quot;,&quot;language&quot;:&quot;swift&quot;,&quot;rawCodeSnippet&quot;:&quot;imageView.cldSetImage(cloudinary.createUrl().setUseRootPath( true).setTransformation(CLDTransformation().setWidth(\\&quot;auto:100:400\\&quot;).setCrop(\\&quot;scale\\&quot;)).generate(\\&quot;bike.jpg\\&quot;)!, cloudinary: cloudinary)&quot;,&quot;codeSnippet&quot;:&quot;imageView.cldSetImage(cloudinary.createUrl().setUseRootPath( true).setTransformation(CLDTransformation().setWidth(\\&quot;auto:100:400\\&quot;).setCrop(\\&quot;scale\\&quot;)).generate(\\&quot;bike.jpg\\&quot;)!, cloudinary: cloudinary)&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;iOS&quot;,&quot;packageName&quot;:&quot;cloudinary&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;5.x&quot;},{&quot;sdkId&quot;:&quot;android&quot;,&quot;framework&quot;:&quot;android&quot;,&quot;language&quot;:&quot;android&quot;,&quot;rawCodeSnippet&quot;:&quot;MediaManager.get().url().transformation(new Transformation().width(\\&quot;auto:100:400\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).generate(\\&quot;bike.jpg\\&quot;);&quot;,&quot;codeSnippet&quot;:&quot;MediaManager.get().url().transformation(new Transformation().width(\\&quot;auto:100:400\\&quot;).crop(\\&quot;scale\\&quot;)).useRootPath(true).generate(\\&quot;bike.jpg\\&quot;);&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Android&quot;,&quot;packageName&quot;:&quot;cloudinary-android&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;3.x&quot;},{&quot;sdkId&quot;:&quot;flutter&quot;,&quot;framework&quot;:&quot;flutter&quot;,&quot;language&quot;:&quot;flutter&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(\\&quot;auto:100:400\\&quot;)));&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image(&#039;bike.jpg&#039;).transformation(Transformation()\\n\\t.resize(Resize.scale().width(\\&quot;auto:100:400\\&quot;)));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Flutter&quot;,&quot;packageName&quot;:&quot;cloudinary_flutter&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;kotlin&quot;,&quot;framework&quot;:&quot;kotlin&quot;,&quot;language&quot;:&quot;kotlin&quot;,&quot;rawCodeSnippet&quot;:&quot;cloudinary.image {\\n\\tpublicId(\\&quot;bike.jpg\\&quot;)\\n\\t resize(Resize.scale() { width(\\&quot;auto:100:400\\&quot;) }) \\n}.generate()&quot;,&quot;codeSnippet&quot;:&quot;cloudinary.image {\\n\\tpublicId(\\&quot;bike.jpg\\&quot;)\\n\\t resize(Resize.scale() { width(\\&quot;auto:100:400\\&quot;) }) \\n}.generate()&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;Kotlin&quot;,&quot;packageName&quot;:&quot;kotlin-url-gen&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;},{&quot;sdkId&quot;:&quot;jquery&quot;,&quot;framework&quot;:&quot;jquery&quot;,&quot;language&quot;:&quot;jquery&quot;,&quot;rawCodeSnippet&quot;:&quot;$.cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;codeSnippet&quot;:&quot;$.cloudinary.image(\\&quot;bike.jpg\\&quot;, {width: \\&quot;auto:100:400\\&quot;, crop: \\&quot;scale\\&quot;, use_root_path: true})&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;jQuery&quot;,&quot;packageName&quot;:&quot;cloudinary-jquery&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;2.x&quot;},{&quot;sdkId&quot;:&quot;react_native&quot;,&quot;framework&quot;:&quot;react_native&quot;,&quot;language&quot;:&quot;react_native&quot;,&quot;rawCodeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;codeSnippet&quot;:&quot;new CloudinaryImage(\\&quot;bike.jpg\\&quot;).resize(scale().width(\\&quot;auto:100:400\\&quot;));&quot;,&quot;status&quot;:0,&quot;statusText&quot;:&quot;Ok&quot;,&quot;displayName&quot;:&quot;React Native&quot;,&quot;packageName&quot;:&quot;cloudinary-react-native&quot;,&quot;packageStatus&quot;:&quot;&quot;,&quot;packageVersion&quot;:&quot;1.x&quot;}]\"\n      parsed-url=\"{&quot;url&quot;:&quot;https:\\\/\\\/res.cloudinary.com\\\/demo\\\/w_auto:100:400\\\/bike.jpg&quot;,&quot;cloud_name&quot;:&quot;demo&quot;,&quot;host&quot;:&quot;res.cloudinary.com&quot;,&quot;type&quot;:&quot;upload&quot;,&quot;resource_type&quot;:&quot;image&quot;,&quot;transformation&quot;:[{&quot;width&quot;:&quot;auto:100:400&quot;}],&quot;transformation_string&quot;:&quot;w_auto:100:400&quot;,&quot;url_suffix&quot;:&quot;&quot;,&quot;version&quot;:&quot;&quot;,&quot;secure&quot;:true,&quot;public_id&quot;:&quot;bike.jpg&quot;,&quot;extension&quot;:&quot;jpg&quot;,&quot;format&quot;:&quot;jpg&quot;,&quot;format_code&quot;:true,&quot;url_code&quot;:false,&quot;signature&quot;:&quot;&quot;,&quot;private_cdn&quot;:false,&quot;result_asset_type&quot;:&quot;image&quot;}\"\n      with-url=\"true\"\n    >\n      <span class=\"u-visually-hidden\">Loading code examples<\/span>\n    <\/cld-code-widget><\/p>\n<p><a href=\"https:\/\/res.cloudinary.com\/demo\/w_auto:100:400\/bike.jpg\" data-popup=\"true\"><img decoding=\"async\" alt=\"Responsive image with Client Hints example\" src=\"https:\/\/res.cloudinary.com\/demo\/w_auto:100:400\/bike.jpg\" style=\"margin: 0 auto;display: block; max-width: 100%\" title=\"Responsive image with Client Hints example\" sizes=\"(min-width: 1200px) calc((1200px * .667) - 70px),\n(min-width:  992px) calc(( 970px * .667) - 70px),\n(min-width:  768px) calc(( 750px * .667) - 70px), \ncalc(100% - 70px)\"><\/a><\/p>\n<p>The first (<code>:100<\/code>) tells Cloudinary how big the \u201cjumps\u201d between alternate resources should be. If you set this to <code>:1<\/code>, resources will be scaled to match the layout width <em>exactly<\/em> \u2014 which as it turns out, is a bad idea. To deliver perfectly-scaled resources, our servers must render and store <em>hundreds, maybe thousands<\/em> of alternate versions of your image, which is both computationally expensive <em>and<\/em> terrible for your pages\u2019 performance. More, alternate resources means fewer <a href=\"https:\/\/cloudinary.com\/glossary\/cache-hit-ratio\">cache hits<\/a>, and a hit at any level \u2014 in the local browser cache, on the CDN, or server-side \u2014 will always be <em>significantly<\/em> faster than a miss. Thus, this first parameter allows you to limit the number of possible responses by defining a \u201crounding step\u201d between them. For example, here, if the target width is 452 pixels, Cloudinary will round up to the nearest hundred and return a 500-pixel-wide resource.<\/p>\n<p>The second parameter (<code>:400<\/code>) serves as a <em>fallback <code>Width<\/code><\/em>, which will be used if the browser doesn\u2019t send a <code>Width<\/code> Hint. In this example, browsers that don\u2019t support Client Hints are served a 400-pixel-wide image. (<code>400<\/code> is a \u201cmobile-first\u201d default. If you would rather serve a \u201cdesktop-first\u201d default to non-supporting browsers, set this to something higher, like 1000). Word to the wise: without a <code>Width<\/code> or this fallback, <code>w_auto<\/code> images will be delivered at their <em>original size<\/em>. If you\u2019re working with large originals \u2014 especially given Client Hints\u2019 nascent support \u2014 this could be disastrous! You <em>do not<\/em> want to start sending 12 megapixel originals to Mobile Safari.<\/p>\n<p>There is one more thing to know about these parameters; I\u2019ve saved <code>w_auto<\/code>\u2019s best trick for last.<\/p>\n<h2>Automatic breakpoints<\/h2>\n<p>Picking an arbitrary step-size using the first parameter can feel, well, confusingly arbitrary. Four years ago, Jason Grigsby <a href=\"https:\/\/cloudfour.com\/thinks\/how-do-you-pick-responsive-images-breakpoints\/\">pointed out<\/a> that it makes more sense to think about these steps in terms of <em>bytes<\/em>, rather than <em>pixels<\/em>. We agreed, and built a tool that implements Jason\u2019s idea \u2014 the <a href=\"http:\/\/www.responsivebreakpoints.com\/\">Responsive Image Breakpoints Generator<\/a>. We\u2019ve now built that same logic into <code>w_auto<\/code>.<\/p>\n<p>Our servers can look at your images, see how they compress, and determine byte-size-based gaps between images <em>for you<\/em> if you set the steps parameter to a special value: <code>:breakpoints<\/code>.<\/p>\n<p><code>w_auto:breakpoints<\/code> packages up a lot of smart thinking and builds on years\u2019 worth of foundational effort to provide an astoundingly automatic responsive images solution that\u2019s smart not only about images\u2019 <em>context<\/em> \u2014 but also their particular <em>content<\/em>. Alas, <code>:breakpoints<\/code> requires a bit of gymnastics at the CDN layer, and in order to use it you\u2019ll need to set up either <a href=\"https:\/\/support.cloudinary.com\/hc\/en-us\/articles\/202520562-Can-we-have-our-own-CNAME-to-our-own-domain-Like-cdn-example-com-\">a custom domain name<\/a> <em>or<\/em> a private CDN distribution \u2014 features which are available only on <a href=\"https:\/\/cloudinary.com\/pricing\">Advanced or Enterprise\/Custom Plans<\/a>. <a href=\"https:\/\/support.cloudinary.com\/hc\/en-us\/requests\/new\">Contact us<\/a> if you\u2019re interested in setting up <code>:breakpoints<\/code> on your account.<\/p>\n<p>Speaking of the imperfect present\u2026<\/p>\n<h2>Let\u2019s talk about Client Hints\u2019 browser support<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/eric-cloudinary\/image\/upload\/q_auto,w_500,dpr_2.0\/matroyshka-browser.png\" alt=\"A matroyshka has fallen over; a friend observes, concerned\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"300\"\/><\/p>\n<p>Right now, <a href=\"http:\/\/caniuse.com\/#feat=client-hints-dpr-width-viewport\">Client Hints are only supported in Chrome and Opera<\/a>. That means that <code>dpr_auto<\/code> and <code>w_auto<\/code> will work for approximately half of your users<a href=\"#w_auto_chrome_stats\"><sup>[3]<\/sup><\/a>.<\/p>\n<p>Other browsers have <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=145380\">been<\/a> <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=935216\">slow<\/a> <a href=\"https:\/\/groups.google.com\/forum\/#!msg\/mozilla.dev.platform\/05fJvmuG35c\/UaNE8yrUBAAJ\">to<\/a> follow Google\u2019s lead. Like every new web platform feature, Client Hints faces a chicken-and-egg problem. Vendors don\u2019t want to implement features in browsers until they see a clearly-expressed demand; authors don\u2019t want to use features on their pages until they enjoy almost universal support.<\/p>\n<p><code>dpr_auto<\/code> and <code>w_auto<\/code> are, among other things, our attempt to nudge Client Hints forward. We developed these features and are advocating for their adoption because we believe fully-automated, drop-dead simple, responsive, and performant images should not be the exception, but rather the norm.<\/p>\n<h2>So, should you use them?<\/h2>\n<p>If you\u2019re starting a new project or retrofitting an old one, doing <em>something<\/em> about responsive images should be at the top of your to-do list. If you\u2019re willing to put in the effort, a markup-based solution will get you the most browser support, but <em>automating<\/em> that markup can be complicated. JavaScript-based solutions are simpler, but operate within significant performance constraints.<\/p>\n<p>Client Hints pave a third path, which is both <em>simple and performant<\/em>. And, despite browsers\u2019 uneven Client Hints support, <code>w_auto<\/code> and <code>dpr_auto<\/code> provide a lot of value, right now.<\/p>\n<p>The <a href=\"https:\/\/www.chromestatus.com\/metrics\/feature\/timeline\/popularity\/523\">vast<\/a> <a href=\"https:\/\/www.chromestatus.com\/metrics\/feature\/timeline\/popularity\/524\">majority<\/a> of websites aren\u2019t doing anything about responsive images; most developers are still sending a single, wasteful, high-resolution resource to everyone. Implementing <code>dpr_auto<\/code> and <code>w_auto<\/code> requires next-to-no effort and delivers fully-responsive images to around half of your visitors without negatively impacting the other half. They provide tremendous performance gains now, and those gains will grow as browser support improves.<\/p>\n<p>Client Hints are where the puck is going for images on the web. <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a free account<\/a> and start using them, today.<\/p>\n<h2>Further reading<\/h2>\n<p>2,000 words in and you still want more? I encourage you to dive into the following resources:<\/p>\n<ul>\n<li>Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automating_responsive_images_with_client_hints\">official automatic responsive images documentation<\/a>, featuring:\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automatic_pixel_density_detection\">dpr_auto<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automatic_image_width\">w_auto<\/a>\n<\/li>\n<li>A special shout-out to <a href=\"https:\/\/cloudinary.com\/documentation\/responsive_images#automatic_image_width_using_optimal_responsive_breakpoints\">w_auto:breakpoints<\/a>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<a href=\"https:\/\/www.smashingmagazine.com\/2016\/01\/leaner-responsive-images-client-hints\/\">Leaner Responsive Images with Client Hints<\/a>, by Jon Arne S\u00e6ter\u00e5s<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/how_to_automatically_create_images_for_responsive_design\">Implementing responsive images with Cloudinary &amp; Javascript<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/responsive_images_with_srcset_sizes_and_cloudinary\">Implementing responsive images with Cloudinary &amp; HTML<\/a>\n<\/li>\n<\/ul>\n<a name=\"w_auto_pre_parser\" class=\"anchor\"\/>\n**[1]** Speculative pre-parsers [initiate 43% of all image loads](https:\/\/twitter.com\/Souders\/status\/597821415354535936)\n<a name=\"w_auto_sizes_layout_width\" class=\"anchor\"\/>\n**[2]** Sizes takes [CSS lengths](https:\/\/css-tricks.com\/the-lengths-of-css\/) and optionally pairs them with media queries. A complete account of its abilities is out of scope for this article, but suffice to say, `sizes` (especially in combination with [viewport relative units](https:\/\/css-tricks.com\/the-lengths-of-css\/#article-header-id-12), the CSS [calc function](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/calc), and media queries), can express just about any dynamic layout width that you can dream up. Based on the information in `sizes`, browsers (and their speculative pre-parsers) can figure out how many `px` the image will occupy on the layout without knowing about, or needing to load, any other piece of the page.\n<a name=\"w_auto_chrome_stats\" class=\"anchor\"\/>\n**[3]** Depending on your audience, it could actually be a lot higher! For instance: 70% of our readers here on the Cloudinary blog use Chrome.\n<h2>Further Reading on Responsive Images<\/h2>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/make_all_images_on_your_website_responsive_in_3_easy_steps\">Responsive images with Cloudinary<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/introducing_smart_cropping_intelligent_quality_selection_and_automated_responsive_images\">Auto-Crop Images for Responsive Designs and Improved Image Quality<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/responsive_images_with_srcset_sizes_and_cloudinary\">Responsive Images: The srcset and sizes HTML Image Attributes<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/make_all_images_on_your_website_responsive_in_3_easy_steps\">Make All Images on Your Website Responsive in 3 Easy Steps<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/blog\/best_practices_for_responsive_web_design\">Best Practices for Responsive Web Design<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":21407,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[92,426,144,165,176,177,214,229,249,251,257],"class_list":["post-21406","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-dotnet","tag-featured","tag-html","tag-image-transformation","tag-java","tag-javascript","tag-node","tag-php","tag-responsive","tag-responsive-images","tag-ruby-on-rails"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Scale an Image Automatically with Client Hints<\/title>\n<meta name=\"description\" content=\"Learn how to scale an image using Cloudinary&#039;s &quot;Automatic Width&quot; and &quot;Automatic DPR&quot; transformations to implement automatic responsive images solution.\" \/>\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\/automatic_responsive_images_with_client_hints\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Scale an Image Automatically with Client Hints\" \/>\n<meta property=\"og:description\" content=\"Learn how to scale an image using Cloudinary&#039;s &quot;Automatic Width&quot; and &quot;Automatic DPR&quot; transformations to implement automatic responsive images solution.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-08-18T12:10:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-08-21T19:22:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"900\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to Scale an Image Automatically with Client Hints\",\"datePublished\":\"2016-08-18T12:10:05+00:00\",\"dateModified\":\"2025-08-21T19:22:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA\",\"keywords\":[\"DotNet\",\"Featured\",\"HTML\",\"Image Transformation\",\"Java\",\"Javascript\",\"Node\",\"PHP\",\"Responsive\",\"Responsive Images\",\"Ruby on Rails\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2016\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\",\"url\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\",\"name\":\"How to Scale an Image Automatically with Client Hints\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA\",\"datePublished\":\"2016-08-18T12:10:05+00:00\",\"dateModified\":\"2025-08-21T19:22:35+00:00\",\"description\":\"Learn how to scale an image using Cloudinary's \\\"Automatic Width\\\" and \\\"Automatic DPR\\\" transformations to implement automatic responsive images solution.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA\",\"width\":1540,\"height\":900},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Scale an Image Automatically with Client Hints\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Scale an Image Automatically with Client Hints","description":"Learn how to scale an image using Cloudinary's \"Automatic Width\" and \"Automatic DPR\" transformations to implement automatic responsive images solution.","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\/automatic_responsive_images_with_client_hints","og_locale":"en_US","og_type":"article","og_title":"How to Scale an Image Automatically with Client Hints","og_description":"Learn how to scale an image using Cloudinary's \"Automatic Width\" and \"Automatic DPR\" transformations to implement automatic responsive images solution.","og_url":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints","og_site_name":"Cloudinary Blog","article_published_time":"2016-08-18T12:10:05+00:00","article_modified_time":"2025-08-21T19:22:35+00:00","og_image":[{"width":1540,"height":900,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints"},"author":{"name":"","@id":""},"headline":"How to Scale an Image Automatically with Client Hints","datePublished":"2016-08-18T12:10:05+00:00","dateModified":"2025-08-21T19:22:35+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","keywords":["DotNet","Featured","HTML","Image Transformation","Java","Javascript","Node","PHP","Responsive","Responsive Images","Ruby on Rails"],"inLanguage":"en-US","copyrightYear":"2016","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints","url":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints","name":"How to Scale an Image Automatically with Client Hints","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","datePublished":"2016-08-18T12:10:05+00:00","dateModified":"2025-08-21T19:22:35+00:00","description":"Learn how to scale an image using Cloudinary's \"Automatic Width\" and \"Automatic DPR\" transformations to implement automatic responsive images solution.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","width":1540,"height":900},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/automatic_responsive_images_with_client_hints#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Scale an Image Automatically with Client Hints"}]},{"@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\/v1649734462\/Web_Assets\/blog\/matroyshka-hero-with-code_2140776b4c\/matroyshka-hero-with-code_2140776b4c.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21406","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=21406"}],"version-history":[{"count":15,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21406\/revisions"}],"predecessor-version":[{"id":36913,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21406\/revisions\/36913"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/21407"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}