{"id":206274,"date":"2015-08-14T11:49:51","date_gmt":"2015-08-14T18:49:51","guid":{"rendered":"http:\/\/css-tricks.com\/?p=206274"},"modified":"2017-10-12T14:25:17","modified_gmt":"2017-10-12T21:25:17","slug":"strategies-for-cache-busting-css","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/strategies-for-cache-busting-css\/","title":{"rendered":"Strategies for Cache-Busting CSS"},"content":{"rendered":"<p>Major performance gains are to be had from browser caching CSS. You ensure your <a href=\"https:\/\/github.com\/h5bp\/server-configs\" rel=\"noopener\">server is set up<\/a> to send headers that tell the browser to hang onto the CSS file for a given amount of time. It&#8217;s a best-practice that many if not most sites are doing already. <\/p>\n<p>Hand-in-hand with browser caching is <em>cache busting<\/em>. Say the browser has the CSS file cached for one year (not uncommon). Then you want to change the CSS. You need a strategy for breaking the cache and forcing the browser to download a new copy of the CSS.<\/p>\n<p>Here are some ways.<\/p>\n<p><!--more--><\/p>\n<h3>The CSS has to be cached for this to matter&#8230;<\/h3>\n<p>Just to make sure, here&#8217;s what some healthy looking headers look like for a cached CSS file:<\/p>\n<figure id='post-206538' class='align-right media-206538'><img data-recalc-dims=\"1\" src=\"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2015\/08\/cached-headers.png\" alt='' \/><\/figure>\n<p>We&#8217;re looking for that <code>Cache-Control<\/code> and <code>Expires<\/code> header. I&#8217;m not a server config expert. I&#8217;d probably look at the H5BP server configs. But here&#8217;s some kinda classic Apache\/HTAccess ways to get that going:<\/p>\n<pre rel=\"HTAccess\"><code>&lt;FilesMatch \"\\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\\.gz)?$\"&gt;\r\n  Header set Expires \"Thu, 15 Apr 2020 20:00:00 GMT\"\r\n&lt;\/FilesMatch&gt;<\/code><\/pre>\n<pre rel=\"HTAccess\"><code>&lt;IfModule mod_expires.c&gt;\r\n  ExpiresActive on\r\n  ExpiresByType text\/css                  \"access plus 1 year\"\r\n  ExpiresByType application\/javascript    \"access plus 1 year\"\r\n&lt;\/IfModule&gt;<\/code><\/pre>\n<h3>Query Strings<\/h3>\n<p>Most browsers these days will see a URL with a different query string as a different file and download a fresh copy. Most CDN&#8217;s even <a href=\"https:\/\/www.maxcdn.com\/one\/tutorial\/cache-busting\/\" rel=\"noopener\">support and recommend<\/a> this.<\/p>\n<pre rel=\"HTML\"><code class=\"language-markup\">&lt;link rel=\"stylesheet\" href=\"style.css?v=3.4.1\"&gt;<\/code><\/pre>\n<p>Make small change? Change it to:<\/p>\n<pre rel=\"HTML\"><code class=\"language-markup\">&lt;link rel=\"stylesheet\" href=\"style.css?v=3.4.2\"&gt;<\/code><\/pre>\n<p>You could potentially make it easier on yourself by setting a server side variable to use in multiple places. Thus changing it would break cache on lots of files at once. <\/p>\n<pre rel=\"PHP\"><code class=\"language-markup\">&lt;?php $cssVersion = \"3.4.2\"; ?&gt;\r\n\r\n&lt;link rel=\"stylesheet\" href=\"global.css?v=&lt;?php echo $cssVersion; ?&gt;\"&gt;<\/code><\/pre>\n<p>Perhaps you could even use <a href=\"http:\/\/semver.org\/\" rel=\"noopener\">Semantic Versioning<\/a>. You could also <a href=\"http:\/\/concrete5tricks.com\/blog\/cache-busting-techniques-for-your-themes-asset-files\/\" rel=\"noopener\">define a constant<\/a>.<\/p>\n<h3>Changing File Name<\/h3>\n<p>Query strings didn&#8217;t always work. Some browsers didn&#8217;t see a differnt query string as a different file. And some software (I&#8217;ve heard: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Squid_%28software%29\" rel=\"noopener\">Squid<\/a>) wouldn&#8217;t cache files with query string. Steve Souders <a href=\"http:\/\/www.stevesouders.com\/blog\/2008\/08\/23\/revving-filenames-dont-use-querystring\/\" rel=\"noopener\">told us not to<\/a>.<\/p>\n<p>A similar concept was to change the file name itself. Like this in the HTML:<\/p>\n<pre rel=\"HTML\"><code class=\"language-markup\">&lt;link rel=\"stylesheet\" href=\"style.232124.css\"&gt;<\/code><\/pre>\n<p>You would handle this programmatically, not literally change the file name in your project. Since that file doesn&#8217;t actually exist on the server, you&#8217;ll need to perform some trickery to route it to the right file. Jeremy Keith <a href=\"https:\/\/adactio.com\/journal\/8504\" rel=\"noopener\">covered his technique<\/a> for this fairly recently.<\/p>\n<pre rel=\"HTAccess\"><code>RewriteCond %{REQUEST_FILENAME} !-f\r\nRewriteRule ^(.+).(\\d+).(js|css)$ $1.$3 [L]<\/code><\/pre>\n<blockquote><p>That tells the server to ignore those numbers in JavaScript and CSS file names, but the browser will still interpret it as a new file whenever I update that number.<\/p><\/blockquote>\n<p>He uses Twig, so the templates he uses are ultimately like:<\/p>\n<pre rel=\"Twig\"><code class=\"language-markup\">{% set cssupdate = '20150310' %}\r\n\r\n&lt;link rel=\"stylesheet\" href=\"\/css\/main.{{ cssupdate }}.css\"&gt;<\/code><\/pre>\n<p>I&#8217;m sure you can imagine a version of that in any backend language (<a href=\"http:\/\/madskristensen.net\/post\/cache-busting-in-aspnet\" rel=\"noopener\">like ASP<\/a>). Level up by making a build tool or deployment script update the variable itself.<\/p>\n<h3>Basing Cache Busting &#8220;Number&#8221; on File Updated Date<\/h3>\n<p>While searching around about this cache busting stuff, you&#8217;ll see a lot of advice recommending you use the server to check when the file was last updated to create the cache busting &#8220;number&#8221; (number, meaning, whatever thing you change to bust cache).<\/p>\n<pre rel=\"PHP\"><code class=\"language-javascript\">function autoversion($url) {\r\n  $path = pathinfo($url);\r\n  $ver = '.'.filemtime($_SERVER['DOCUMENT_ROOT'].$url).'.';\r\n  return $path['dirname'].'\/'.str_replace('.', $ver, $path['basename']);\r\n}<\/code><\/pre>\n<pre rel=\"HTML\"><code class=\"language-markup\">&lt;link href=\"&lt;?php autoversion('\/path\/to\/theme.css'); ?&gt;\" rel=\"stylesheet\"&gt;<\/code><\/pre>\n<p>I can&#8217;t speak well to this. It <em>seems to me<\/em> that asking your server to dig up this information on every pageview would be pretty intensive and dangerous in production. In the past I&#8217;ve done things like &#8220;I&#8217;ll just have PHP output the dimensions of the image in data attributes!&#8221; only to find it grinds the server to halt. Anyway, beware.<\/p>\n<h3>ETags<\/h3>\n<p>ETags kinda seem like a good idea, because the whole point of them is information to check if the browser already has a copy of that file. <\/p>\n<p>But most advice out there says: &#8220;turn off your ETags headers&#8221;. Yahoo <a href=\"https:\/\/developer.yahoo.com\/performance\/rules.html\" rel=\"noopener\">says<\/a>:<\/p>\n<blockquote><p>The problem with ETags is that they typically are constructed using attributes that make them unique to a specific server hosting a site. ETags won&#8217;t match when a browser gets the original component from one server and later tries to validate that component on a different server, a situation that is all too common on Web sites that use a cluster of servers to handle requests.<\/p><\/blockquote>\n<p>Another issue is that they just aren&#8217;t as effective as actual caching. In order to check an ETag, a network request <a href=\"http:\/\/phpixie.jeromepasquier.com\/caching-dynamic-assets-javascript-css-etc\/\" rel=\"noopener\">still needs to be made<\/a>. It&#8217;s not just the downloading of files that affect performance, it&#8217;s all the network negotiation and latency stuff too.<\/p>\n<p>Again, not an expert here, but here&#8217;s what&#8217;s generally recommended to turn them off in Apache land:<\/p>\n<pre rel=\"HTAccess\"><code class=\"language-javascript\">&lt;IfModule mod_headers.c&gt;\r\n  Header unset ETag\r\n&lt;\/IfModule&gt;\r\nFileETag None<\/code><\/pre>\n<h3>Framework Does It For Us<\/h3>\n<h4>Rails Asset Pipeline<\/h4>\n<p>I have a little experience with the Rails <a href=\"http:\/\/guides.rubyonrails.org\/asset_pipeline.html\" rel=\"noopener\">Asset Pipeline<\/a> and <a href=\"https:\/\/github.com\/ndbroadbent\/turbo-sprockets-rails3\" rel=\"noopener\">Sprockets<\/a>. It&#8217;s kind of a dream system if you ask me. I link up stylesheets in templates:<\/p>\n<pre rel=\"ERB\"><code class=\"language-markup\">&lt;%= stylesheet_link_tag \"about\/about\" %&gt;<\/code><\/pre>\n<p>And it produces HTML like:<\/p>\n<pre rel=\"HTML\"><code class=\"language-markup\">&lt;link href=\"http:\/\/assets.codepen.io\/assets\/about\/about-7ca9d3db0013f3ea9ba05b9dcda5ede0.css\" media=\"screen\" rel=\"stylesheet\" type=\"text\/css\" \/&gt;<\/code><\/pre>\n<p>That cache busting number only changes when the file changes, so you only break cache on the files that need broken. Plus it has methods for images and JavaScript as well.<\/p>\n<h4>WordPress<\/h4>\n<p>If you use a <em>page<\/em> caching tool in WordPress, like W3 Total Cache or something, you probably have to be less afraid of that <code>filemtime<\/code> business being too server intensive.<\/p>\n<p>Gilbert Pellegrom <a href=\"http:\/\/gilbert.pellegrom.me\/cache-busting-wordpress-style-css\/\" rel=\"noopener\">posted a WordPress-specific technique<\/a> using it:<\/p>\n<pre rel=\"PHP\"><code class=\"language-javascript\">wp_register_style( 'screen', get_template_directory_uri().'\/style.css', array(), filemtime( get_template_directory().'\/style.css' ) );\r\nwp_enqueue_style( 'screen' );\r\n\r\n\/\/ Example Output: \/style.css?ver=1384432580<\/code><\/pre>\n<p>The WordPress plugin <a href=\"https:\/\/wordpress.org\/plugins\/busted\/\" rel=\"noopener\">Busted!<\/a> does this same thing behind the scenes. Just does it kinda automatically to everything.<\/p>\n<h3>CodeKit<\/h3>\n<p>CodeKit doesn&#8217;t have a built in method for changing file names, but it does have a way to execute Shell scripts under circumstances you set up.<\/p>\n<figure id='post-206546' class='align-right media-206546'><img data-recalc-dims=\"1\" src=\"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2015\/08\/codekit.png\" alt='' \/><\/figure>\n<p><a href=\"http:\/\/useless.today\/codekit-timestamps\/\" rel=\"noopener\">Michael Russell has a blog post<\/a> about how you can inject timestamps into file themselves, which I&#8217;m sure you could modify to change the filenames instead.<\/p>\n<h3>Build Tools<\/h3>\n<p>All the popular task runner \/ build tool thingies have plugins to help change file names. Sufian Rhazi <a href=\"https:\/\/blog.risingstack.com\/automatic-cache-busting-for-your-css\/\" rel=\"noopener\">has a post<\/a> on doing it in raw Node.js as well. <\/p>\n<h4>Grunt<\/h4>\n<ul>\n<li><a href=\"https:\/\/github.com\/hollandben\/grunt-cache-bust\" rel=\"noopener\">grunt-cache-bust<\/a><\/li>\n<\/ul>\n<h4>Gulp<\/h4>\n<ul>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/gulp-cache-bust\" rel=\"noopener\">gulp-cache-bust<\/a><\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/gulp-buster\" rel=\"noopener\">gulp-buster<\/a><\/li>\n<\/ul>\n<h4>Broccoli<\/h4>\n<ul>\n<li><a href=\"https:\/\/github.com\/mjackson\/broccoli-rev\" rel=\"noopener\">broccoli-rev<\/a><\/li>\n<\/ul>\n<h4>Within Preprocessors<\/h4>\n<p>When linking up assets within other assets (e.g. an image that you link to from within a LESS file, for example) you could put the preprocessor to work. Ben Nadel <a href=\"http:\/\/www.bennadel.com\/blog\/2643-cache-busting-css-images-with-less-css.htm\" rel=\"noopener\">has a post<\/a> on doing just that.<\/p>\n<h3>Async CSS<\/h3>\n<p>With Critical CSS becoming more of a thing, deferred loading of CSS is becoming more of a thing. There are some other reasons to defer loading of CSS as well (perhaps print CSS, or priming cache). <\/p>\n<p>If you&#8217;re loading CSS with <a href=\"https:\/\/github.com\/filamentgroup\/loadCSS\" rel=\"noopener\">loadCSS<\/a> (or perhaps <a href=\"http:\/\/blog.kevinchisholm.com\/javascript\/css-cache-buster\/\" rel=\"noopener\">injecting a link tag<\/a>), you&#8217;ll need to update the file name it requests in the JavaScript itself. Different than changing the file name, but not that different.<\/p>\n<h3>So<\/h3>\n<p>Anything I missed? What&#8217;s your cache busting strategy?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Major performance gains are to be had from browser caching CSS. You ensure your server is set up to send [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0","_share_on_mastodon_status":"%title% %permalink%"},"categories":[4],"tags":[],"class_list":["post-206274","post","type-post","status-publish","format-standard","hentry","category-articles"],"acf":{"show_toc":"No"},"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":337113,"url":"https:\/\/css-tricks.com\/wordpress-caching-all-you-need-to-know\/","url_meta":{"origin":206274,"position":0},"title":"WordPress Caching: All You Need To Know","author":"Chris Coyier","date":"April 1, 2021","format":false,"excerpt":"Here's Ashley Rich at Delicious Brains writing about all the layers of caching that are relevant to a WordPress site. I think we all know that caching is complicated, but jeez, it's a journey to understand all the caches at work here. The point of cache being speed and reducing\u2026","rel":"","context":"In &quot;Links&quot;","block_context":{"text":"Links","link":"https:\/\/css-tricks.com\/category\/links\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/4C07BF8E-841B-4FBD-A8CF-BF65C0E23B4D.jpeg?fit=1200%2C686&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/4C07BF8E-841B-4FBD-A8CF-BF65C0E23B4D.jpeg?fit=1200%2C686&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/4C07BF8E-841B-4FBD-A8CF-BF65C0E23B4D.jpeg?fit=1200%2C686&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/4C07BF8E-841B-4FBD-A8CF-BF65C0E23B4D.jpeg?fit=1200%2C686&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/4C07BF8E-841B-4FBD-A8CF-BF65C0E23B4D.jpeg?fit=1200%2C686&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":364166,"url":"https:\/\/css-tricks.com\/adding-cdn-caching-to-a-vite-build\/","url_meta":{"origin":206274,"position":1},"title":"Adding CDN Caching to a Vite Build","author":"Adam Rackis","date":"April 4, 2022","format":false,"excerpt":"Content delivery networks, or CDNs, allow you to improve the delivery of your website\u2019s static resources, most notably, with CDN caching. They do this by serving your content from edge locations, which are located all over the world. When a user browses to your site, and your site requests resources\u2026","rel":"","context":"In &quot;Articles&quot;","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/vite-cloudfront.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/vite-cloudfront.jpg?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/vite-cloudfront.jpg?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/vite-cloudfront.jpg?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/vite-cloudfront.jpg?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":293453,"url":"https:\/\/css-tricks.com\/quick-gulp-cache-busting\/","url_meta":{"origin":206274,"position":2},"title":"Quick Gulp Cache Busting","author":"Chris Coyier","date":"August 7, 2019","format":false,"excerpt":"You should for sure be setting far-out cache headers on your assets like CSS and JavaScript (and images and fonts and whatever else). That tells the browser \"hang on to this file basically forever.\" That way, when navigating from page to page on a site \u2014 or revisiting it, or\u2026","rel":"","context":"In &quot;Articles&quot;","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/gulp-dynamite.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/gulp-dynamite.png?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/gulp-dynamite.png?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/gulp-dynamite.png?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/gulp-dynamite.png?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":204407,"url":"https:\/\/css-tricks.com\/web-performance-cache-efficiency-exercise\/","url_meta":{"origin":206274,"position":3},"title":"Web performance: Cache efficiency exercise","author":"Chris Coyier","date":"June 30, 2015","format":false,"excerpt":"Ryan Albrecht digs into how efficient browser caching is on Facebook.com. They release code twice a day, breaking cache as they do, so they were curious if that was too often for browser cache to be efficient. After collecting data, they are seeing 44.6% users getting an empty cache, which\u2026","rel":"","context":"In &quot;Links&quot;","block_context":{"text":"Links","link":"https:\/\/css-tricks.com\/category\/links\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":352381,"url":"https:\/\/css-tricks.com\/working-with-graphql-caching\/","url_meta":{"origin":206274,"position":4},"title":"Working With GraphQL Caching","author":"Jamie Barton","date":"September 23, 2021","format":false,"excerpt":"If you\u2019ve recently started working with GraphQL, or reviewed its pros and cons, you\u2019ve no doubt heard things like \u201cGraphQL doesn\u2019t support caching\u201d or \u201cGraphQL doesn\u2019t care about caching.\u201d And for most, that is a big deal. The official GraphQL documentation refers to caching techniques so, clearly, the folks behind\u2026","rel":"","context":"In &quot;Articles&quot;","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/11\/graphql-pattern.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/11\/graphql-pattern.jpg?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/11\/graphql-pattern.jpg?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/11\/graphql-pattern.jpg?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/11\/graphql-pattern.jpg?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":359055,"url":"https:\/\/css-tricks.com\/add-a-service-worker-to-your-site\/","url_meta":{"origin":206274,"position":5},"title":"Add a Service Worker to Your Site","author":"Chris Ferdinandi","date":"December 28, 2021","format":false,"excerpt":"One of the best things you can do for your website in 2022 is add a service worker, if you don't have one in place already. Service workers give your website super powers. Today, I want to show you some of the amazing things that they can do, and give\u2026","rel":"","context":"In &quot;2021 End-of-Year Thoughts&quot;","block_context":{"text":"2021 End-of-Year Thoughts","link":"https:\/\/css-tricks.com\/category\/2021-end-of-year-thoughts\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/cog-pattern.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/cog-pattern.jpg?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/cog-pattern.jpg?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/cog-pattern.jpg?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/cog-pattern.jpg?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/206274","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=206274"}],"version-history":[{"count":8,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/206274\/revisions"}],"predecessor-version":[{"id":261276,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/206274\/revisions\/261276"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=206274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=206274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=206274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}