<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://henry.codes/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Code snippets and brave beginnings of ideas from the desk of Henry (From Online)</title>
    <link>https://henry.codes/</link>
    <atom:link href="https://henry.codes/rss/notes.xml" rel="self" type="application/rss+xml" />
    <description>The personal site and portfolio of creative web developer Henry from Online</description>
    <language>en</language>
    
<item>
    <title>There is yet room for techno-optimism</title>
    <link>https://henry.codes/writing/there-is-yet-room-for-techno-optimism/</link>
    <description>&lt;p&gt;Earlier today, in a particularly enthusiastic scroll-sesh, I read a reply to an article about AI use that read something to the effect of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bluesky has a toxic AI discourse problem…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And man, I actually feel you — hard-lining doesn’t always feel useful. Especially when you find yourself open-armed, open-eyed, willing to approach this burgeoning space with unbridled optimism, but upon returning to the village find many quite upset with the fruits of your labor — it must be especially frustrating.&lt;/p&gt;
&lt;p&gt;But I think rather than “people are too emotional or angry about AI”, the more salient point to arrive at is something else. Love it or hate it, a lot of the tech under the AI umbrella have well-documented trade-offs and outright harms. It’s fairly reasonable, then, to accept that most folks insist upon “solutions that don’t knowingly create new problems”, especially given that the world looks &lt;em&gt;*gestures wildly at everything*&lt;/em&gt; like &lt;em&gt;this&lt;/em&gt;, these days.&lt;/p&gt;
&lt;article class=&quot;article-block article-block--external themed dark&quot;&gt;
    &lt;h1 class=&quot;article-block__title&quot;&gt;AI data centres can warm surrounding areas by up to 9.1°C&lt;/h1&gt;
    &lt;div class=&quot;article-block__meta&quot;&gt;
        &lt;p class=&quot;article-block__meta-highlight&quot;&gt;by New Scientist&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;article-block__excerpt&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hundreds of millions of people live close enough to data centres used to power AI to feel warmer average temperatures in their local area&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;article-block__external-disclaimer&quot;&gt;
&lt;span&gt;this link goes some strange place beyond this website&lt;/span&gt;
&lt;span&gt;go with care&lt;/span&gt;
&lt;/div&gt;
&lt;a href=&quot;https://www.newscientist.com/article/2521256-ai-data-centres-can-warm-surrounding-areas-by-up-to-9-1c/&quot; class=&quot;article-block__link with-arrow with-arrow--out&quot;&gt;Read more&lt;/a&gt;&lt;p&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;p&gt;Let us take you at your word, that you are someone who believes the value of AI/LLMs/etc is the solutions they bring to People. If you see that many People feel emotionally reactive towards these technologies, and your value system believes in People, wouldn’t you be better served by moving your scope to &lt;em&gt;include&lt;/em&gt; those People? That is, wouldn’t you be better off viewing “solutions don’t knowingly create new problems” as creative constraint for the way that you solve problems?&lt;/p&gt;
&lt;p&gt;I value you, person-who-believes-AI-creates-good, for thy optimistic spirit. I just also believe you ought to spend your energy in realms where that spirit has more economy. There is something noble about the work of common-ground reframing — considering the possibility you might do more good by inventing solutions that people also want, than by inventing ones that they don’t and then criticizing those doubters for their lack of nuance.&lt;/p&gt;
&lt;p&gt;I’ll say this: I’m frankly not a wise enough person to magically solve the schism here. I reckon there &lt;em&gt;is&lt;/em&gt; a bit — and even a lot — of alignment between folks who think they can make the world better using AI, and people that don’t use AI because they don’t want the world doesn’t get any worse. I just mean to encourage those big-hearted folks with technological optimism to spare to reassess their thinking — “making the world better with AI” should be more about &lt;em&gt;the world&lt;/em&gt; than about AI.&lt;/p&gt;
&lt;h3 id=&quot;further-reading&quot; tabindex=&quot;-1&quot;&gt;Further reading&lt;/h3&gt;
&lt;p&gt;I’m sure it’s clear from this note, but I’m generally AI-skeptical (though I do try not to be dogmatic about that position) — if you’re into that point of view, I’ve written more about the implications of a technology like LLMs, specifically from a labor angle, &lt;a href=&quot;https://henry.codes/writing/economics-and-labor-rights-in-ai-skepticism/&quot;&gt;elsewhere on the blog&lt;/a&gt;.&lt;/p&gt;
&lt;article class=&quot;card article-block&quot;&gt;
    &lt;dl class=&quot;article-block__meta&quot;&gt;
        &lt;div&gt;
            &lt;dt class=&quot;visually-hidden&quot;&gt;Category&lt;/dt&gt;
            &lt;dd&gt;journal&lt;/dd&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;dt class=&quot;visually-hidden&quot;&gt;Tags&lt;/dt&gt;
            &lt;dd&gt;rants | labor | the other world&lt;/dd&gt;
        &lt;/div&gt;
    &lt;/dl&gt;
    &lt;h1 class=&quot;article-block__title&quot;&gt;Economics &amp;amp; labor rights in AI skepticism&lt;/h1&gt;
    &lt;dl class=&quot;article-block__meta&quot;&gt;
        &lt;div&gt;
            &lt;dt class=&quot;visually-hidden&quot;&gt;Reading Time&lt;/dt&gt;
            &lt;dd&gt;6 minute read&lt;/dd&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;dt class=&quot;visually-hidden&quot;&gt;Last updated&lt;/dt&gt;
            &lt;dd&gt;
                &lt;time&gt;Last updated June 3, 2025&lt;/time&gt;
            &lt;/dd&gt;
        &lt;/div&gt;
    &lt;/dl&gt;
    &lt;a href=&quot;https://henry.codes/writing/economics-and-labor-rights-in-ai-skepticism/&quot; class=&quot;article-block__link with-arrow&quot;&gt;Read more&lt;/a&gt;
&lt;/article&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 05:59:43 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/there-is-yet-room-for-techno-optimism/</guid>
</item>
<item>
    <title>War is not hell: war is war, and hell is hell</title>
    <link>https://henry.codes/writing/war-is-not-hell-war-is-war-and-hell-is-hell/</link>
    <description>&lt;p&gt;It just seemed natural that the thing to come after proxy war of imperial aggression for us is &lt;em&gt;direct&lt;/em&gt; war of imperial aggression. The other day, I was shown this quote &lt;a href=&quot;https://www.imdb.com/title/tt0638432/&quot;&gt;from an episode of M*A*S*H&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Capt. Benjamin Franklin ‘Hawkeye’ Pierce&lt;/strong&gt;: War isn’t Hell. War is war, and Hell is Hell. And of the two, war is a lot worse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Father Francis Mulcahy&lt;/strong&gt;: How do you figure that, Hawkeye?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hawkeye&lt;/strong&gt;: Easy, Father. Tell me, who goes to Hell?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mulcahy&lt;/strong&gt;: Sinners, I believe.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hawkeye&lt;/strong&gt;: Exactly. There are no innocent bystanders in Hell. War is chock full of them - little kids, cripples, old ladies. In fact, except for some of the brass, almost everybody involved is an innocent bystander.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are no innocent bystanders in Hell.&lt;/p&gt;
&lt;p&gt;While on the subject, I am reminded of another old eschatological Internet classic:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;is this hell?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;in what sense?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;the present moment is both eternal and painful.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;in Hell, there is relief in utter helplessness. here, our actions have consequences for both ourselves and others.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;truly, it is worse&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sorry to post so doomfully on the blog today. There is still immense value in acting in solidarity with our neighbors and moving with grace and patience and noble intention. It just feels small in the face of the immense violence American empire commits in our name, this afternoon.&lt;/p&gt;
&lt;p&gt;Old friends, we have been owed a better world for so long, and what an utterly irredeemable one we have built in its stead.&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/war-is-not-hell-war-is-war-and-hell-is-hell/</guid>
</item>
<item>
    <title>AI at work is anti-labor by design</title>
    <link>https://henry.codes/writing/ai-at-work-is-anti-labor-by-design/</link>
    <description>&lt;ul class=&quot;changelog&quot;&gt;
&lt;li&gt;&lt;em&gt;27 January 2026&lt;/em&gt; — Added Pinterest layoff news.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;4 March 2026&lt;/em&gt; — Added Block layoff news.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In regards to &lt;a href=&quot;https://www.aljazeera.com/news/2025/10/28/is-artificial-intelligence-to-blame-for-amazon-job-cuts&quot;&gt;recent announcements by Amazon&lt;/a&gt; &lt;a href=&quot;https://apnews.com/article/pinterest-layoffs-ai-cf278cf06929db07d5b1310ab7f91861&quot;&gt;and now Pinterest&lt;/a&gt;, &lt;a href=&quot;https://www.cnn.com/2026/02/26/business/block-layoffs-ai-jack-dorsey&quot;&gt;and now Block&lt;/a&gt; that they’d be laying off historical numbers of workers, only a few months after Amazon CEO &lt;a href=&quot;https://www.aboutamazon.com/news/company-news/amazon-ceo-andy-jassy-on-generative-ai&quot;&gt;Andrew Jassy announced AI adoption would be directly responsible for reductions in workforce&lt;/a&gt;:&lt;/p&gt;
&lt;article class=&quot;article-block article-block--external themed dark&quot;&gt;
    &lt;h1 class=&quot;article-block__title&quot;&gt;Is artificial intelligence to blame for Amazon job cuts?&lt;/h1&gt;
    &lt;div class=&quot;article-block__meta&quot;&gt;
        &lt;p class=&quot;article-block__meta-highlight&quot;&gt;by Al Jazeera&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;article-block__excerpt&quot;&gt;
Amazon confirms 14,000 layoffs after CEO says AI likely to lead to job losses.
&lt;/div&gt;
&lt;div class=&quot;article-block__external-disclaimer&quot;&gt;
&lt;span&gt;this link goes some strange place beyond this website&lt;/span&gt;
&lt;span&gt;go with care&lt;/span&gt;
&lt;/div&gt;
&lt;a href=&quot;https://www.aljazeera.com/news/2025/10/28/is-artificial-intelligence-to-blame-for-amazon-job-cuts&quot; class=&quot;article-block__link with-arrow with-arrow--out&quot;&gt;Read more&lt;/a&gt;&lt;p&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;article class=&quot;article-block article-block--external themed dark&quot;&gt;
    &lt;h1 class=&quot;article-block__title&quot;&gt;Pinterest will lay off 15% of its workforce as the platform pivots resources to AI&lt;/h1&gt;
    &lt;div class=&quot;article-block__meta&quot;&gt;
        &lt;p class=&quot;article-block__meta-highlight&quot;&gt;by AP News&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;article-block__excerpt&quot;&gt;
Pinterest will lay off 15% of its workforce as the platform pivots resources to AI
&lt;/div&gt;
&lt;div class=&quot;article-block__external-disclaimer&quot;&gt;
&lt;span&gt;this link goes some strange place beyond this website&lt;/span&gt;
&lt;span&gt;go with care&lt;/span&gt;
&lt;/div&gt;
&lt;a href=&quot;https://apnews.com/article/pinterest-layoffs-ai-cf278cf06929db07d5b1310ab7f91861&quot; class=&quot;article-block__link with-arrow with-arrow--out&quot;&gt;Read more&lt;/a&gt;&lt;p&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;article class=&quot;article-block article-block--external themed dark&quot;&gt;
    &lt;h1 class=&quot;article-block__title&quot;&gt;Block lays off nearly half its staff because of AI. Its CEO said most companies will do the same&lt;/h1&gt;
    &lt;div class=&quot;article-block__meta&quot;&gt;
        &lt;p class=&quot;article-block__meta-highlight&quot;&gt;by AP News&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class=&quot;article-block__excerpt&quot;&gt;
Block lays off nearly half its staff because of AI. Its CEO said most companies will do the same
&lt;/div&gt;
&lt;div class=&quot;article-block__external-disclaimer&quot;&gt;
&lt;span&gt;this link goes some strange place beyond this website&lt;/span&gt;
&lt;span&gt;go with care&lt;/span&gt;
&lt;/div&gt;
&lt;a href=&quot;https://www.cnn.com/2026/02/26/business/block-layoffs-ai-jack-dorsey&quot; class=&quot;article-block__link with-arrow with-arrow--out&quot;&gt;Read more&lt;/a&gt;&lt;p&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;p&gt;AI/LLMs are by design anti-labor technology. The feverish pushing of &lt;abbr title=&quot;Large Language Model&quot;&gt;LLM&lt;/abbr&gt; adoption by all levels of management is exemplary of this: You are not asked to use this tech because it will enable better work and ideas, but because it is cheaper to your boss than your coworker’s salary.&lt;/p&gt;
&lt;p&gt;The goals of capital are not interested in the lofty ideals of magically improving your day-to-day workload, or enhancing your ability to think, be creative, enact your will — these are marketing promises made by those who benefit from eliminating your role when your coworker’s output increases.&lt;/p&gt;
&lt;p&gt;Your boss is not incentivized by utopian imagination, he is incentivized by showing &lt;em&gt;his&lt;/em&gt; boss a lowering of costs so he can keep &lt;em&gt;his&lt;/em&gt; job and lifestyle. The miraculous science fiction future AI shills often proselytize will not be realized in the halls of SaaS companies, because the incentives for that future do not exist in a capitalist framework.&lt;/p&gt;
&lt;p&gt;Reject AI: reject its devaluation of your fellow workers’ labor and its destruction of our ecosystem. Look always to improve the world you live in, instead of inventing new ones where all the problems are solved by handwaving at unrealized technology.&lt;/p&gt;
&lt;h3 id=&quot;further-reading&quot; tabindex=&quot;-1&quot;&gt;Further reading&lt;/h3&gt;
&lt;p&gt;I’ve also &lt;a href=&quot;https://henry.codes/writing/economics-and-labor-rights-in-ai-skepticism/&quot;&gt;written a bit more about the inherent anti-labor tilt of the AI project&lt;/a&gt; elsewhere on the blog :)&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/ai-at-work-is-anti-labor-by-design/</guid>
</item>
<item>
    <title>Frequently-used ffmpeg recipes</title>
    <link>https://henry.codes/writing/frequently-used-ffmpeg-recipes/</link>
    <description>&lt;p&gt;I use a &lt;code&gt;ffmpeg&lt;/code&gt; at least twice weekly for stupid side projects and non-stupid side projects; here’s a list for posterity and for my future self (who I adore) to keep track of commonly-used recipes.&lt;/p&gt;
&lt;h3 id=&quot;converting-webm-to-mp4&quot; tabindex=&quot;-1&quot;&gt;Converting .webm to .mp4&lt;/h3&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-fflags&lt;/span&gt; +genpts &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${filename}&lt;/span&gt;.webm &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${target frame rate}&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${target filename}&lt;/span&gt;.mp4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;+genpts&lt;/code&gt; format flag &lt;em&gt;generates presentation timestamps&lt;/em&gt;, which &lt;abbr title=&quot;in my experience&quot;&gt;IME&lt;/abbr&gt; fixes some jank when trying to copy the file over directly. The &lt;code&gt;-r ${framerate}&lt;/code&gt; bit is not required, but it’s one more thing to sort out jank outputs.&lt;/p&gt;
&lt;h3 id=&quot;converting-a-video-to-frames&quot; tabindex=&quot;-1&quot;&gt;Converting a video to frames&lt;/h3&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${input filename}&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${output filename prefix}&lt;/span&gt;%d.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;%d&lt;/code&gt; in the output filename adds a frame number to the end. If you have like 400 frames and you want all the filename numbers padded, you can do something like &lt;code&gt;%3d&lt;/code&gt; instead, to output something like &lt;code&gt;frame_001.png&lt;/code&gt; instead of &lt;code&gt;frame_1.png&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;converting-frames-back-to-video-or-gif&quot; tabindex=&quot;-1&quot;&gt;Converting frames back to video (or GIF)&lt;/h3&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; frames/frame_%d.png output.gif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This one’s pretty obvious lol, it just ingests the frame format however you specify. There might be different rules for converting to something other than &lt;code&gt;.gif&lt;/code&gt; but I only tested &lt;code&gt;.gif&lt;/code&gt; for this post.&lt;/p&gt;
&lt;p class=&quot;editors-note&quot;&gt;For what it’s worth, I tested both &lt;code&gt;.gif&lt;/code&gt; with a soft G sound and &lt;code&gt;.gif&lt;/code&gt; with a hard G sound but the output is the same.&lt;/p&gt;
&lt;h3 id=&quot;generating-and-consuming-a-color-palette-for-gifs-etc&quot; tabindex=&quot;-1&quot;&gt;Generating &amp;amp; consuming a color palette for GIFs, etc.&lt;/h3&gt;
&lt;p&gt;To generate a color palette:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; input.mp4 &lt;span class=&quot;token parameter variable&quot;&gt;-vf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;palettegen&quot;&lt;/span&gt; palette.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use that palette to optimize a GIF output:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; frames/frame_%0d.png &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; palette.png &lt;span class=&quot;token parameter variable&quot;&gt;-filter_complex&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;paletteuse&quot;&lt;/span&gt; output.gif
&lt;/code&gt;&lt;/pre&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/frequently-used-ffmpeg-recipes/</guid>
</item>
<item>
    <title>A bookmarklet for clearing cookies for the current page</title>
    <link>https://henry.codes/writing/a-bookmarklet-for-clearing-cookies-for-the-current-page/</link>
    <description>&lt;h2 id=&quot;tl-dr&quot; tabindex=&quot;-1&quot;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Here’s the one-liner:&lt;/p&gt;
&lt;!-- prettier-ignore-start --&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;javascript&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; o&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; t&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; c&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toUTCString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; t&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;^(.*?)=&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;__Host-&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;t&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;$=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;c&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/;secure&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;t&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;c&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;t&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;c&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/;domain=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;o&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Error clearing cookies: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;!-- prettier-ignore-end --&gt;
&lt;h2 id=&quot;how-do-i-use-this&quot; tabindex=&quot;-1&quot;&gt;How do I use this?&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a new bookmark:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;In Firefox:&lt;/em&gt; In the top menu, navigate to &lt;code&gt;Bookmarks &amp;gt; Manage Bookmarks&lt;/code&gt;, click the gear icon, and add a bookmark.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;In Chrome:&lt;/em&gt; Navigate to &lt;code&gt;chrome://bookmarks/&lt;/code&gt;, then click the &lt;code&gt;⁝&lt;/code&gt; icon and &lt;code&gt;Add new bookmark&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Name it whatever you want (I use “Clear cookies”) and set the URL to the snippet above.&lt;/li&gt;
&lt;li&gt;On a page with cookies you want to clear, click the bookmark you created, and it will execute the JS that invalidates all the cookies.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;walk-me-through-what-this-js-does-before-i-run-some-stranger-s-code-in-my-browser&quot; tabindex=&quot;-1&quot;&gt;Walk me through what this JS does before I run some stranger’s code in my browser&lt;/h2&gt;
&lt;p&gt;Lol sure, here’s the code beautified and commented out. Some things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://whitep4nth3r.com/blog/cookies-not-deleted/&quot;&gt;You can’t actually delete cookies&lt;/a&gt;, you have to just set their expiration date to Before Now, so the browser considers them invalid.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__Host-&lt;/code&gt; prefixed cookies need the &lt;code&gt;secure&lt;/code&gt; flag in order to be updated.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__Secure-&lt;/code&gt; prefixed cookies cannot be set via JavaScript.&lt;/li&gt;
&lt;li&gt;This code doesn’t address cookies set on a subdomain. You could add some logic to break out a subdomain but it starts to get pretty RegEx-y and I figured we could keep this far simpler and cover most use-cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Create an IIFE¹.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get the domain name in order to remove domain-specific cookies&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; domain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hostname&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get all the cookies set on the document and break &#39;em up&#39;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cookiesList &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Create a new date from right this instant, we&#39;ll use this to invalidate all existing cookies.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dateToInvalidateBy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toUTCString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    cookiesList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;cookie&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Cookies are set like `cookieName=cookieValue;`, this grabs ONLY the name segment.&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cookieName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cookie&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;^(.*?)=&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// I found I needed to select cookies that started with __Host&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// and pass them the `secure` flag in order to properly invalidate them.&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cookieName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;__Host-&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// For all cookies, we just tell the document cookie manager that the cookie&#39;s value has changed&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Basically: cookie name has an empty value, expires right now, and has some metadata (path, security, domain, etc)&lt;/span&gt;
        document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;cookieName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;$=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;dateToInvalidateBy&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/;secure&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;cookieName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;dateToInvalidateBy&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cookie &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;cookieName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;=;expires=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;dateToInvalidateBy&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;path=/;domain=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;domain&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Cookies cleared. Feel free to reload.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Error clearing cookies: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;footnotes&quot; tabindex=&quot;-1&quot;&gt;Footnotes&lt;/h3&gt;
&lt;p&gt;¹ — &lt;abbr title=&quot;Immediately Invoked Function Expression&quot;&gt;&lt;em&gt;IIFE&lt;/em&gt;&lt;/abbr&gt;: Immediately Invoked Function Expression. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/IIFE&quot;&gt;More on IIFEs here&lt;/a&gt;.&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/a-bookmarklet-for-clearing-cookies-for-the-current-page/</guid>
</item>
<item>
    <title>Disabling WebGL in your browser</title>
    <link>https://henry.codes/writing/disabling-webgl-in-your-browser/</link>
    <description>&lt;p&gt;For testing different scenarios and user preferences, you can use these steps to disable WebGL in different browsers. These work for MacOS. If someone tells me how to do it in Windows or I get the gumption I’ll update this post lol.&lt;/p&gt;
&lt;h2 id=&quot;disabling-web-gl-in-firefox-and-zen&quot; tabindex=&quot;-1&quot;&gt;Disabling WebGL in Firefox &amp;amp; Zen&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Navigate your browser to &lt;code&gt;about:config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the search bar, type &lt;code&gt;webgl.disabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the property that shows up to &lt;em&gt;true&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To re-enable WebGL, you’ll need to un-set this configuration property.&lt;/p&gt;
&lt;h2 id=&quot;disabling-web-gl-in-google-chrome-and-arc&quot; tabindex=&quot;-1&quot;&gt;Disabling WebGL in Google Chrome &amp;amp; Arc&lt;/h2&gt;
&lt;p&gt;For Chrome/Chromium-based browsers, you have to pass a special flag when you start the application. If you’ve installed Chrome somewhere other than the default location, you’ll need to update this script accordingly.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In your Terminal, run:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;/Applications/Google&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt; Chrome.app/Contents/MacOS/Google&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt; Chrome --disable-webgl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To re-enable WebGL, just close the browser completely and start it again how you normally would.&lt;/p&gt;
&lt;h2 id=&quot;disabling-web-gl-in-safari-edge-etc&quot; tabindex=&quot;-1&quot;&gt;Disabling WebGL in Safari, Edge, etc.&lt;/h2&gt;
&lt;p class=&quot;editors-note&quot;&gt;Sorry to bait you here with the headline. Haven’t worked out how to do it yet, but I’ll update when I do!&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/disabling-webgl-in-your-browser/</guid>
</item>
<item>
    <title>Quickly checking HTTP response headers</title>
    <link>https://henry.codes/writing/quickly-checking-http-response-headers/</link>
    <description>&lt;p&gt;Fastest cleanest way if you’re a Terminal Enjoyer™ is with &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; https://henry.codes/
&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;editors-note&quot;&gt;The &lt;code&gt;-I&lt;/code&gt; flag, short for &lt;code&gt;--head&lt;/code&gt;, includes only HTTP headers in the output. &lt;a href=&quot;https://devhints.io/curl&quot;&gt;Here’s a tidy little &lt;code&gt;curl&lt;/code&gt; cheat sheet&lt;/a&gt; for you; don’t spend it all in one place.&lt;/p&gt;
&lt;p&gt;But if you prefer using a browser dev inspector, you can go &lt;code&gt;Inspector &amp;gt; Network &amp;gt; HTML &amp;gt; [the current page]&lt;/code&gt; and scroll to Response Headers.&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-400w.webp 400w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-800w.webp 800w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-1400w.webp 1400w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-2420w.webp 2420w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-400w.jpeg&quot; alt=&quot;A screenshot of a browser window as described, requesting the homepage of henry.codes and revealing its relevant HTTP headers in the right-side inspector panel.&quot; width=&quot;2420&quot; height=&quot;1654&quot; srcset=&quot;https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-400w.jpeg 400w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-800w.jpeg 800w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-1400w.jpeg 1400w, https://henry.codes/writing/quickly-checking-http-response-headers/CleanShot_2025-05-06_at_12.43.59_2x_htycso-2420w.jpeg 2420w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/quickly-checking-http-response-headers/</guid>
</item>
<item>
    <title>Human-readable date formatting with vanilla JavaScript</title>
    <link>https://henry.codes/writing/human-readable-date-formatting-with-vanilla-javascript/</link>
    <description>&lt;p&gt;Have one of these?&lt;/p&gt;
&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;Sat Mar 22 2025 19:50:03 GMT-0500 (Eastern Standard Time)

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- or perhaps one of these? --&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 2025-03-22T01:23:48.693Z --&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Need one of these?&lt;/p&gt;
&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;March 22, 2025
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or some other format? You probably don’t need &lt;code&gt;moment.js&lt;/code&gt; or piles of StackOverflow-ing into your apartment, you just need &lt;code&gt;Date.toLocaleDateString()&lt;/code&gt;. Here’s some common use cases:&lt;/p&gt;
&lt;p class=&quot;editors-note&quot;&gt;&lt;abbr title=&quot;your mileage may vary&quot;&gt;YMMV&lt;/abbr&gt; with the &lt;code&gt;en-US&lt;/code&gt; locale tag — if you’re based somewhere else you might be better served by &lt;a href=&quot;https://www.techonthenet.com/js/language_tags.php&quot;&gt;using another locale&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;date-only&quot; tabindex=&quot;-1&quot;&gt;Date Only&lt;/h2&gt;
&lt;h3 id=&quot;march-22-2025&quot; tabindex=&quot;-1&quot;&gt;March 22, 2025&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;long&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;numeric&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;numeric&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;.toLocaleDateString()&lt;/code&gt; method exists on any &lt;code&gt;Date&lt;/code&gt; object. If we’ve got a string that represents a date, we’ll need to parse a &lt;code&gt;Date&lt;/code&gt; object from it first:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; someArbitraryDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;2025-03-22T01:23:48.693Z&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

someArbitraryDate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-22-2025&quot; tabindex=&quot;-1&quot;&gt;3/22/2025&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;03-01-25&quot; tabindex=&quot;-1&quot;&gt;03/01/25&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;22-03-25-blimey-lol&quot; tabindex=&quot;-1&quot;&gt;22/03/25 (blimey lol)&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-GB&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2-digit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;saturday-march-22-2025&quot; tabindex=&quot;-1&quot;&gt;Saturday, March 22, 2025&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;dateStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;full&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;time-only&quot; tabindex=&quot;-1&quot;&gt;Time only&lt;/h2&gt;
&lt;p&gt;Now we’ll mix it up and use &lt;code&gt;Date().toLocaleTimeString()&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;8-08-03-pm&quot; tabindex=&quot;-1&quot;&gt;8:08:03 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;20-08-03-pm&quot; tabindex=&quot;-1&quot;&gt;20:08:03 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;hour12&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-08-pm&quot; tabindex=&quot;-1&quot;&gt;8:08 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;short&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-08-03-pm-est&quot; tabindex=&quot;-1&quot;&gt;8:08:03 PM EST&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;long&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-08-03-pm-eastern-standard-time&quot; tabindex=&quot;-1&quot;&gt;8:08:03 PM Eastern Standard Time&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;full&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-08-03-pm-east-africa-time&quot; tabindex=&quot;-1&quot;&gt;8:08:03 PM East Africa Time&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;full&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeZone&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Africa/Nairobi&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a full list of time zone options, you can use the &lt;code&gt;TZ identifier&lt;/code&gt; column on &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_tz_database_time_zones&quot;&gt;the Wikipedia list page for tz database time zones&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;8-08-03-pm-gmt-3&quot; tabindex=&quot;-1&quot;&gt;8:08:03 PM GMT+3&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeZone&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Africa/Nairobi&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeZoneName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;short&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-pm&quot; tabindex=&quot;-1&quot;&gt;8 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleTimeString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;numeric&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;date-and-time&quot; tabindex=&quot;-1&quot;&gt;Date &amp;amp; Time&lt;/h2&gt;
&lt;p&gt;You can use &lt;code&gt;Date.toLocaleString&lt;/code&gt; to combine the two:&lt;/p&gt;
&lt;h3 id=&quot;3-22-2025-8-08-03-pm&quot; tabindex=&quot;-1&quot;&gt;3/22/2025, 8:08:03 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;mar-22-2025-8-08-pm&quot; tabindex=&quot;-1&quot;&gt;Mar 22, 2025, 8:08 PM&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;en-US&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;dateStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;medium&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;timeStyle&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;short&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/human-readable-date-formatting-with-vanilla-javascript/</guid>
</item>
<item>
    <title>I Know About The Date In The Footer</title>
    <link>https://henry.codes/writing/i-know-about-the-date-in-the-footer/</link>
    <description>&lt;p&gt;I appreciate you looking out, but thankfully &lt;a href=&quot;https://github.com/xdesro/true-terrors/blob/9beed8c771730845307e8a3f1782202ff9a06cf3/src/_includes/footer.njk#L40-L44&quot;&gt;this is just a bit of tongue-in-cheek humor&lt;/a&gt; and I am eternally my own &lt;s&gt;worst enemy&lt;/s&gt; target audience. A better man with a better sense of humor might stop trying to beat this particular horse, but I’m not him bro.&lt;/p&gt;
&lt;p&gt;All I’m gonna say is that &lt;abbr title=&quot;this is Robb Owen’s joke lol&quot;&gt;it seemed like a good idea at the &lt;code&gt;Date().getTime()&lt;/code&gt;&lt;/abbr&gt;.&lt;/p&gt;
&lt;div class=&quot;with-soft-filter-outline with-flowed-children&quot;&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-1284w.webp 1284w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1284&quot; height=&quot;228&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.54.55_ugbkjr-1284w.jpeg 1284w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-1206w.webp 1206w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1206&quot; height=&quot;320&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.57.29_gh4sqg-1206w.jpeg 1206w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-1214w.webp 1214w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1214&quot; height=&quot;446&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_16.58.10_a53cdh-1214w.jpeg 1214w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-1118w.webp 1118w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1118&quot; height=&quot;256&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.00.58_efsibc-1118w.jpeg 1118w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-1358w.webp 1358w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1358&quot; height=&quot;318&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.02.50_xypie5-1358w.jpeg 1358w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-1294w.webp 1294w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1294&quot; height=&quot;231&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.26_uabdsj-1294w.jpeg 1294w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-1234w.webp 1234w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1234&quot; height=&quot;164&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.03.58_kthciz-1234w.jpeg 1234w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-400w.webp 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-800w.webp 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-1220w.webp 1220w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-400w.jpeg&quot; alt=&quot;&quot; width=&quot;1220&quot; height=&quot;318&quot; srcset=&quot;https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-400w.jpeg 400w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-800w.jpeg 800w, https://henry.codes/writing/i-know-about-the-date-in-the-footer/CleanShot_2025-01-09_at_17.04.30_2x_zlhvfx-1220w.jpeg 1220w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;/div&gt;</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/i-know-about-the-date-in-the-footer/</guid>
</item>
<item>
    <title>Hinting &amp; autocompletion for JSON in VS Code</title>
    <link>https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/</link>
    <description>&lt;p&gt;Here’s a short and sweet guide to typing your JSON with JSON Schema and having VSCode validate and autocomplete based on that schema. Shoot me an email with questions or corrections!&lt;/p&gt;
&lt;h2 id=&quot;create-json-schema&quot; tabindex=&quot;-1&quot;&gt;Create JSON Schema&lt;/h2&gt;
&lt;p&gt;There’s a standard for typing JSON called &lt;a href=&quot;https://json-schema.org/&quot;&gt;JSON Schema&lt;/a&gt;, which you can use to model your data. For instance, I have a file &lt;code&gt;_data/recentReading.json&lt;/code&gt; &lt;a href=&quot;https://github.com/xdesro/true-terrors/blob/main/src/_data/recentReading.json&quot;&gt;in the repo for this project&lt;/a&gt;, and when I add new articles, I want VSCode to suggest the required fields, and warn me when I forget a field.&lt;/p&gt;
&lt;p&gt;The JSON goes something like this:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A Brief History &amp;amp; Ethos of the Digital Garden&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Maggie Appleton&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://maggieappleton.com/garden-history&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a pretty simple example, so it ought to be noted that JSON Schema of course does way more than this.&lt;/p&gt;
&lt;p&gt;Following the guides on the JSON Schema site, I can create a file &lt;code&gt;recentReading.schema.json&lt;/code&gt;, which I’ll keep in my &lt;code&gt;.vscode&lt;/code&gt; directory for now, since VSCode is the only interested party.&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// .vscode/recentReading.schema.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Recent Reading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A list of recently read articles online.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The top-level object should take a property &quot;posts&quot;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// which is an array of post objects.&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;array&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// The post object should accept properties &quot;title&quot;, &quot;author&quot;,&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// and &quot;url&quot;, and no additional properties:&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;format&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;uri&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;additionalProperties&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// &quot;title&quot;, &quot;author&quot;, and &quot;url&quot; must be present.&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I reckon this is pretty self-explanatory, but I recommend checking out &lt;a href=&quot;https://json-schema.org/understanding-json-schema/reference&quot;&gt;the JSON Schema reference&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h2 id=&quot;make-vs-code-observe-the-schema&quot; tabindex=&quot;-1&quot;&gt;Make VSCode observe the schema&lt;/h2&gt;
&lt;p&gt;Supposedly, you can set the schema for a glob of URLs using &lt;code&gt;json.schemas: [{ fileMatch, url }]&lt;/code&gt; in &lt;code&gt;.vscode/settings.json&lt;/code&gt;, but I found this didn’t work properly. Instead, I set the &lt;code&gt;$schema&lt;/code&gt; property directly in the &lt;code&gt;recentReading.json&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/_data/recentReading.json&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;$schema&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../.vscode/recentReading.schema.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// or whatever the path to schema you created is, relative to the current JSON file.&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;editors-note&quot;&gt;This isn’t ideal, because it makes the files concerned with their own validation, and I prefer them only to be concerned with their content. If someone knows why the VSCode settings &lt;code&gt;json.schemas&lt;/code&gt; configuration didn’t work, email me lol.&lt;/p&gt;
&lt;p&gt;Now in my JSON file, if I create an object under &lt;code&gt;&amp;quot;posts&amp;quot;&lt;/code&gt; that contains anything but a title, author, and URL, it’ll throw an error in the VSCode Problems view:&lt;/p&gt;
&lt;div class=&quot;subgrid two-col&quot; style=&quot;--standard-column: 2 / span 10;&quot;&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-400w.webp 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-800w.webp 800w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-1132w.webp 1132w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-400w.jpeg&quot; alt=&quot;A VSCode screenshot showing the IDE throwing an error when an empty object is added to the &amp;quot;posts&amp;quot; entry of the described JSON, as the required properties &amp;quot;title&amp;quot;, &amp;quot;author&amp;quot;, and &amp;quot;url&amp;quot; are missing.&quot; width=&quot;1132&quot; height=&quot;704&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-400w.jpeg 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-800w.jpeg 800w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.41.39_2x_icrwuq-1132w.jpeg 1132w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-400w.webp 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-800w.webp 800w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-1000w.webp 1000w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-400w.jpeg&quot; alt=&quot;A VSCode screenshot showing the IDE throwing an error when an object with the property &amp;quot;test&amp;quot; is added to the &amp;quot;posts&amp;quot; entry of the described JSON, as the &amp;quot;test&amp;quot; property isn’t allowed.&quot; width=&quot;1000&quot; height=&quot;686&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-400w.jpeg 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-800w.jpeg 800w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.42.40_2x_itztpo-1000w.jpeg 1000w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;autocompletion-in-vs-code&quot; tabindex=&quot;-1&quot;&gt;Autocompletion in VSCode&lt;/h2&gt;
&lt;p&gt;We can use a special VSCode schema property called “defaultSnippets” to show VSCode how to automatically scaffold our entries. In the schema file, where you define the properties for the item you want auto-completed, you can add the following:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;array&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;defaultSnippets&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New recent reading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Creates a post in recent reading list&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$3&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More on &lt;code&gt;defaultSnippets&lt;/code&gt; formatting can be found &lt;a href=&quot;https://code.visualstudio.com/Docs/languages/json#_define-snippets-in-json-schemas&quot;&gt;in the VSCode docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, in my &lt;code&gt;recentReading.json&lt;/code&gt; file, under my &lt;code&gt;posts&lt;/code&gt; entry, I can use the keyboard shortcut &lt;kbd&gt;Control (^)&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt; to show my available auto-completions:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.56.59_2x_xy9t8a-400w.webp 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.56.59_2x_xy9t8a-558w.webp 558w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.56.59_2x_xy9t8a-400w.jpeg&quot; alt=&quot;A VSCode editor window showing the described autocompletion, opening a suggestion to inset &amp;quot;new recent reading&amp;quot;.&quot; width=&quot;558&quot; height=&quot;144&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.56.59_2x_xy9t8a-400w.jpeg 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_15.56.59_2x_xy9t8a-558w.jpeg 558w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Which will auto-expand into the shape I expect for an entry:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_16.02.36_2x_mc9yln-400w.webp 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_16.02.36_2x_mc9yln-502w.webp 502w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_16.02.36_2x_mc9yln-400w.jpeg&quot; alt=&quot;A VSCode editor window showing the described object insertion, an object with the properties title, author, and url set to empty strings.&quot; width=&quot;502&quot; height=&quot;252&quot; srcset=&quot;https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_16.02.36_2x_mc9yln-400w.jpeg 400w, https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/CleanShot_2025-01-09_at_16.02.36_2x_mc9yln-502w.jpeg 502w&quot; sizes=&quot;100vw&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p class=&quot;editors-note&quot;&gt;I’m not sure what the keyboard shortcut is on Windows or Linux, I would guess &lt;kbd&gt;Alt&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt;, but the action in VSCode is “Trigger Suggest” if you want to look it up in Keyboard Shortcuts.&lt;/p&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/hinting-and-autocompletion-for-json-in-vs-code/</guid>
</item>
<item>
    <title>Set the default language for a file extension in VS Code</title>
    <link>https://henry.codes/writing/set-the-default-language-for-a-file-extension-in-vs-code/</link>
    <description>&lt;p&gt;In &lt;code&gt;.vscode/settings.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;files.associations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// extension as blob: language&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;*.webc&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;html&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
    <pubDate>Tue, 31 Mar 2026 01:43:04 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/set-the-default-language-for-a-file-extension-in-vs-code/</guid>
</item>
<item>
    <title>Animated link underlines with skip-ink effect</title>
    <link>https://henry.codes/writing/animated-link-underlines-with-skip-ink-effect/</link>
    <description>&lt;p&gt;You can use &lt;code&gt;-webkit-text-stroke&lt;/code&gt; and &lt;code&gt;paint-order&lt;/code&gt; in CSS to animate a link underline without losing the really neat &lt;code&gt;text-decoration-skip-ink&lt;/code&gt; effect from standard text-decoration.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/xdesro/pen/JjgxqLy&quot;&gt;Here’s a demo&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TODO fix console errors coming from this --&gt;
&lt;iframe height=&quot;300&quot; style=&quot;width: 100%;&quot; scrolling=&quot;no&quot; title=&quot;Animated Underline with text-decoration-skip-ink Effect&quot; src=&quot;https://codepen.io/xdesro/embed/JjgxqLy?default-tab=css%2Cresult&amp;theme-id=37307&quot; frameborder=&quot;no&quot; loading=&quot;lazy&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/xdesro/pen/JjgxqLy&quot;&gt;
  Animated Underline with text-decoration-skip-ink Effect&lt;/a&gt; by Henry Desroches (&lt;a href=&quot;https://codepen.io/xdesro&quot;&gt;@xdesro&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;
&lt;!-- &lt;p class=&quot;codepen&quot; data-height=&quot;300&quot; data-theme-id=&quot;37307&quot; data-default-tab=&quot;result,css&quot; data-slug-hash=&quot;JjgxqLy&quot; data-pen-title=&quot;Animated Underline with text-decoration-skip-ink Effect&quot; data-user=&quot;xdesro&quot; style=&quot;height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;
  &lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/xdesro/pen/JjgxqLy&quot;&gt;
  Animated Underline with text-decoration-skip-ink Effect&lt;/a&gt; by Henry Desroches (&lt;a href=&quot;https://codepen.io/xdesro&quot;&gt;@xdesro&lt;/a&gt;)
  on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;
&lt;script data-taxi-reload async src=&quot;https://public.codepenassets.com/embed/index.js&quot;&gt;&lt;/script&gt; --&gt;</description>
    <pubDate>Wed, 13 Oct 2021 06:00:00 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/animated-link-underlines-with-skip-ink-effect/</guid>
</item>
<item>
    <title>Create an SVG gradient from an array of colors</title>
    <link>https://henry.codes/writing/create-an-svg-gradient-from-an-array-of-colors/</link>
    <description>&lt;p class=&quot;under-construction&quot;&gt;Alright this isn’t actually usable yet, I created this for a &lt;a href=&quot;https://reading.henry.codes&quot;&gt;specific side project&lt;/a&gt; and have yet to sanitize it for reusability in new contexts.&lt;/p&gt;
&lt;p&gt;If you’ve a random list of colors and you want a perfect gradient between them, here’s how. I’ve got it in Vue here but I’ll add templating for like Nunjucks or Liquid down the line.&lt;/p&gt;
&lt;p&gt;This uses the &lt;code&gt;mapRange&lt;/code&gt; linear interpolation function I talk about in &lt;a href=&quot;https://henry.codes/writing/how-to-map-a-number-between-two-ranges/#tl-dr&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Vue single-file components:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;linearGradient&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;fill-mask&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;y1&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;y2&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;stop&lt;/span&gt;
          &lt;span class=&quot;token attr-name&quot;&gt;v-for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;(color, index) in colors&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token attr-name&quot;&gt;:stop-color&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token attr-name&quot;&gt;:offset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;mapRange(index, 0, colors.length, 0, 1)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token attr-name&quot;&gt;:key&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;linearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rect&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;url(#rating-percentage-shape-mask)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;url(#fill-mask)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
    <pubDate>Wed, 13 Oct 2021 06:00:00 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/create-an-svg-gradient-from-an-array-of-colors/</guid>
</item>
<item>
    <title>Hint VS Code for eleventyConfig autocompletion</title>
    <link>https://henry.codes/writing/hint-vs-code-for-eleventyconfig-autocompletion/</link>
    <description>&lt;p&gt;Allows VS Code to start offering intellisense and autocompletion options for the &lt;code&gt;eleventyConfig&lt;/code&gt; object. Super useful when you’re trying to remember the capitalization on &lt;code&gt;eleventy.addPassthroughCopy()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;.eleventy.js&lt;/code&gt; or &lt;code&gt;eleventy.config.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 *  @param {import(&quot;@11ty/eleventy/src/UserConfig&quot;)} eleventyConfig
 */&lt;/span&gt;
module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Maybe obvious, but the &lt;code&gt;/** ... */&lt;/code&gt; comment is the important part for VSC.)&lt;/em&gt;&lt;/p&gt;
</description>
    <pubDate>Wed, 13 Oct 2021 06:00:00 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/hint-vs-code-for-eleventyconfig-autocompletion/</guid>
</item>
<item>
    <title>Find and kill processes at a given port</title>
    <link>https://henry.codes/writing/find-and-kill-processes-at-a-given-port/</link>
    <description>&lt;p&gt;In your terminal or &lt;code&gt;.zshrc&lt;/code&gt;, etc:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-name function&quot;&gt;killport&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;🚨 Killing all processes at port&#39;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;lsof&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-ti&lt;/span&gt; tcp:&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usage&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;killport &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 🚨 Killing all processes at port 8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
    <pubDate>Wed, 13 Oct 2021 06:00:00 GMT</pubDate>
    <dc:creator>Henry Desroches</dc:creator>
    <guid>https://henry.codes/writing/find-and-kill-processes-at-a-given-port/</guid>
</item>

</channel>
</rss>