@calebhailey.com https://calebhailey.com/ 2025-08-25T21:42:14Z Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1756158134000 2025-08-25T21:42:14Z 2025-08-25T21:42:14Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Just wrapping up day 1 of a <a href="https://hypertemplates.net" data-hyper-mention>@hypertemplates.net</a> hack week with <a href="https://blog.thoward.me" data-hyper-mention>@blog.thoward.me</a>! ๐Ÿ’ฅ</p> <p>Just wrapping up day 1 of a <a href="https://hypertemplates.net" data-hyper-mention>@hypertemplates.net</a> hack week with <a href="https://blog.thoward.me" data-hyper-mention>@blog.thoward.me</a>! ๐Ÿ’ฅ</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1755888038000 2025-08-22T18:40:38Z 2025-08-22T18:40:38Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Been meaning to post about this. Google keeps promoting YouTube as a closed alternative to standards-based podcasting amid never-ending rumors about the death of podcasting. Meanwhile Apple continues to promote traditional podcasting!</p> <p>Now if only Apple could wield its cultural influence (via the iPhone) by shifting Apple News more towards <a href="/tags/rss/" data-hyper-mention>#RSS</a>. Brand it as webcasting or <a href="https://textcasting.org" data-hyper-mention>@textcasting.org</a> if necessary.</p> <p>Apple has the ability to make &quot;Wherever you follow websites&quot; a thingโ„ข <a href="https://www.anildash.com/2024/02/06/wherever_you_get_podcasts/">like it did for podcasting</a>.</p> <p>A boy can dream!</p> <p>Been meaning to post about this. Google keeps promoting YouTube as a closed alternative to standards-based podcasting amid never-ending rumors about the death of podcasting. Meanwhile Apple continues to promote traditional podcasting!</p> <p>Now if only Apple could wield its cultural influence (via the iPhone) by shifting Apple News more towards <a href="/tags/rss/" data-hyper-mention>#RSS</a>. Brand it as webcasting or <a href="https://textcasting.org" data-hyper-mention>@textcasting.org</a> if necessary.</p> <p>Apple has the ability to make &quot;Wherever you follow websites&quot; a thingโ„ข <a href="https://www.anildash.com/2024/02/06/wherever_you_get_podcasts/">like it did for podcasting</a>.</p> <p>A boy can dream!</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1752268731000 2025-07-11T21:18:51Z 2025-07-11T21:18:51Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>I want so badly for this game to exist. The world needs a proper NBA Street Vol.2 successor! ๐Ÿ€</p> <p>I want so badly for this game to exist. The world needs a proper NBA Street Vol.2 successor! ๐Ÿ€</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1752267696000 2025-07-11T21:01:36Z 2025-07-11T21:01:36Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Finally ready to outsource bookkeeping for <a href="https://herd.works" data-hyper-mention>@herd.works</a> ๐ŸŽ‰</p> <p><a href="/tags/startups/" data-hyper-mention>#startups</a> <a href="/tags/achievementunlocked/" data-hyper-mention>#AchievementUnlocked</a></p> <p>Finally ready to outsource bookkeeping for <a href="https://herd.works" data-hyper-mention>@herd.works</a> ๐ŸŽ‰</p> <p><a href="/tags/startups/" data-hyper-mention>#startups</a> <a href="/tags/achievementunlocked/" data-hyper-mention>#AchievementUnlocked</a></p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1752191368000 2025-07-10T23:49:28Z 2025-07-10T23:49:28Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Scored some sweet deals on the Prime Sale this year after mostly ignoring it for the past few years. I had my eye on this charger for a while and noticed it was $60 off, so I snagged one of these and massively simplified the device charging setup in my home office. This thing is an absolute beast.</p> <p>PS - this is not an affiliate link. Iโ€™m just sharing out of the goodness of my nerdy little heart. ๐Ÿค“</p> <p>Scored some sweet deals on the Prime Sale this year after mostly ignoring it for the past few years. I had my eye on this charger for a while and noticed it was $60 off, so I snagged one of these and massively simplified the device charging setup in my home office. This thing is an absolute beast.</p> <p>PS - this is not an affiliate link. Iโ€™m just sharing out of the goodness of my nerdy little heart. ๐Ÿค“</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1752190692000 2025-07-10T23:38:12Z 2025-07-10T23:38:12Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Is this thing on?!</p> <p>Is this thing on?!</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1746743939000 2025-05-08T22:38:59Z 2025-05-08T22:38:59Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>I noticed my <a href="/?tab=Following">following</a> feed was broken earlier this week. It turns out it's been broken since the updated site went live at the beginning of the year. Whoops! ๐Ÿ˜…</p> <p>The issue was with my static site generator and how it was parsing OPML data files. With that fixed I can now drop a lightly modified OPML file (with paywalled <a href="/tags/rss/" data-hyper-mention>#RSS</a> feeds removed) into a data folder and get an auto-generated <a href="/?tab=Following">following</a> page. ๐ŸคŒ๐Ÿฝ</p> <p>This whole idea was inspired by this <a href="https://anildash.com" data-hyper-mention>@anildash.com</a> blog post that I think about way too often.</p> <p>I noticed my <a href="/?tab=Following">following</a> feed was broken earlier this week. It turns out it's been broken since the updated site went live at the beginning of the year. Whoops! ๐Ÿ˜…</p> <p>The issue was with my static site generator and how it was parsing OPML data files. With that fixed I can now drop a lightly modified OPML file (with paywalled <a href="/tags/rss/" data-hyper-mention>#RSS</a> feeds removed) into a data folder and get an auto-generated <a href="/?tab=Following">following</a> page. ๐ŸคŒ๐Ÿฝ</p> <p>This whole idea was inspired by this <a href="https://anildash.com" data-hyper-mention>@anildash.com</a> blog post that I think about way too often.</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1746512481000 2025-05-06T06:21:21Z 2025-05-06T06:21:21Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Office productivity is going to take a slight hit this week. โšฝ๏ธ๐Ÿ˜…๐Ÿ“‰</p> <p>Office productivity is going to take a slight hit this week. โšฝ๏ธ๐Ÿ˜…๐Ÿ“‰</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1746387256000 2025-05-04T19:34:16Z 2025-05-04T19:47:16Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>The web needs more experimentation like this from <a href="https://eieio.games" data-hyper-mention>@eieio.games</a>. ๐Ÿ‘๐Ÿ‘๐Ÿ‘</p> <p>The web needs more experimentation like this from <a href="https://eieio.games" data-hyper-mention>@eieio.games</a>. ๐Ÿ‘๐Ÿ‘๐Ÿ‘</p> Steve Jobs' talk at the 1983 International Design Conference in Aspen https://calebhailey.com/links/steve-jobs-talk-at-the-1983-international-design-conference-in-aspen 2025-05-04T18:50:52Z 2025-05-04T18:50:52Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com Steve Jobs Archive https://stevejobsarchive.com/ @stevejobsarchive.com https://stevejobsarchive.com/apple-touch-icon.png Link to https://stevejobsarchive.com/exhibits/objects-of-our-life Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1746223784000 2025-05-02T22:09:44Z 2025-05-02T22:09:44Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Cool to see <a href="https://stripe.com" data-hyper-mention>@stripe.com</a> jump in! Competition for payments on iOS?!</p> <p>The comments on <a href="https://x.com/AzianMike/status/1917830346332332329">this Twitter thread from Stripe Product Manager Michael Lou</a> are amazing. It reads like an FAQ, haha.</p> <p>One <a href="https://x.com/ntelas_/status/1917934277557211168">comment</a> replies &quot;But using Apple Pay makes purchasing something way more likely for me.&quot; Lou <a href="https://x.com/AzianMike/status/1917934617291796939">responds</a> &quot;You can use Apple pay via Stripe!&quot;</p> <p>Another <a href="https://x.com/irishnick23/status/1918124789895516639">comment</a> asks &quot;Do users return to the app automatically after successful completion or is an action required?&quot; Lou <a href="https://x.com/AzianMike/status/1918127289596035231">responds</a> &quot;They return automatically if [the developer has] Universal Links enabled&quot;.</p> <p>๐Ÿฟ</p> <!-- Links --> <p>Cool to see <a href="https://stripe.com" data-hyper-mention>@stripe.com</a> jump in! Competition for payments on iOS?!</p> <p>The comments on <a href="https://x.com/AzianMike/status/1917830346332332329">this Twitter thread from Stripe Product Manager Michael Lou</a> are amazing. It reads like an FAQ, haha.</p> <p>One <a href="https://x.com/ntelas_/status/1917934277557211168">comment</a> replies &quot;But using Apple Pay makes purchasing something way more likely for me.&quot; Lou <a href="https://x.com/AzianMike/status/1917934617291796939">responds</a> &quot;You can use Apple pay via Stripe!&quot;</p> <p>Another <a href="https://x.com/irishnick23/status/1918124789895516639">comment</a> asks &quot;Do users return to the app automatically after successful completion or is an action required?&quot; Lou <a href="https://x.com/AzianMike/status/1918127289596035231">responds</a> &quot;They return automatically if [the developer has] Universal Links enabled&quot;.</p> <p>๐Ÿฟ</p> <!-- Links --> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1746217881000 2025-05-02T20:31:21Z 2025-05-02T20:31:21Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>I knew today was gonna be an exceptional Daily Update on <a href="https://stratechery.com" data-hyper-mention>@stratechery.com</a> and I was not disappointed! ๐Ÿ”ฅ</p> <p>I knew today was gonna be an exceptional Daily Update on <a href="https://stratechery.com" data-hyper-mention>@stratechery.com</a> and I was not disappointed! ๐Ÿ”ฅ</p> Three meaningful changes to App Review guidelines https://calebhailey.com/posts/1746162218000 2025-05-02T05:03:38Z 2025-05-02T05:03:38Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>These might be the three most meaningful paragraphs of policy/legal <a href="https://youtu.be/jIveQ4O9Tnw">mumbo jumbo</a> I've experienced in my professional career.</p> <p>From an inconspicuously titled <a href="https://developer.apple.com/news/?id=9txfddzf">&quot;Updated guidelines now available&quot;</a> from <a href="https://developer.apple.com" data-hyper-mention>@developer.apple.com</a>:</p> <blockquote> <p>3.1.1(a): On the United States storefront, there is no prohibition on an app including buttons, external links, or other calls to action, and no entitlement is required to do so.</p> <p>3.1.3: The prohibition on encouraging users to use a purchasing method other than in-app purchase does not apply on the United States storefront.</p> <p>3.1.3(a): The External Link Account entitlement is not required for apps on the United States storefront to include buttons, external links, or other calls to action.</p> </blockquote> <p>The email opened with an acknowledgement of <a href="https://daringfireball.net/2025/04/gonzales_rogers_apple_app_store_ruling">this week's monumental legal mandate</a>:</p> <blockquote> <p>The App Review Guidelines have been updated for compliance with a United States court decision regarding buttons, external links, and other calls to action in apps. These changes affect apps distributed on the United States storefront of the App Store</p> </blockquote> <p>Three cheers for regulation?! ๐Ÿ‘ฉโ€โš–๏ธ</p> <p>The most exciting thing about this to me personally is how <a href="https://apple.com" data-hyper-mention>@apple.com</a> itself might respond to these changes by <em>actually competing</em> for developers' business in an area where it hasn't had to in the past.</p> <p>It's gonna be a fun <a href="/tags/wwdc/" data-hyper-mention>#WWDC</a> &amp; summer! ๐Ÿ™Œ๐Ÿฝ</p> <p>These might be the three most meaningful paragraphs of policy/legal <a href="https://youtu.be/jIveQ4O9Tnw">mumbo jumbo</a> I've experienced in my professional career.</p> <p>From an inconspicuously titled <a href="https://developer.apple.com/news/?id=9txfddzf">&quot;Updated guidelines now available&quot;</a> from <a href="https://developer.apple.com" data-hyper-mention>@developer.apple.com</a>:</p> <blockquote> <p>3.1.1(a): On the United States storefront, there is no prohibition on an app including buttons, external links, or other calls to action, and no entitlement is required to do so.</p> <p>3.1.3: The prohibition on encouraging users to use a purchasing method other than in-app purchase does not apply on the United States storefront.</p> <p>3.1.3(a): The External Link Account entitlement is not required for apps on the United States storefront to include buttons, external links, or other calls to action.</p> </blockquote> <p>The email opened with an acknowledgement of <a href="https://daringfireball.net/2025/04/gonzales_rogers_apple_app_store_ruling">this week's monumental legal mandate</a>:</p> <blockquote> <p>The App Review Guidelines have been updated for compliance with a United States court decision regarding buttons, external links, and other calls to action in apps. These changes affect apps distributed on the United States storefront of the App Store</p> </blockquote> <p>Three cheers for regulation?! ๐Ÿ‘ฉโ€โš–๏ธ</p> <p>The most exciting thing about this to me personally is how <a href="https://apple.com" data-hyper-mention>@apple.com</a> itself might respond to these changes by <em>actually competing</em> for developers' business in an area where it hasn't had to in the past.</p> <p>It's gonna be a fun <a href="/tags/wwdc/" data-hyper-mention>#WWDC</a> &amp; summer! ๐Ÿ™Œ๐Ÿฝ</p> A Janky Experience https://calebhailey.com/posts/a-janky-experience 2025-04-22T23:30:08Z 2025-04-22T23:30:08Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>While asking <a href="https://chatgpt.com" data-hyper-mention>@chatgpt.com</a> to help me debug a SwiftUI issue, it offered a solution and then said &quot;but that results in a janky experience&quot;!</p> <p>The AI has become self-aware! ๐Ÿ˜…</p> <p>While asking <a href="https://chatgpt.com" data-hyper-mention>@chatgpt.com</a> to help me debug a SwiftUI issue, it offered a solution and then said &quot;but that results in a janky experience&quot;!</p> <p>The AI has become self-aware! ๐Ÿ˜…</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1745351056000 2025-04-22T19:44:16Z 2025-04-22T19:44:16Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Looks like the <a href="https://gohugo.io" data-hyper-mention>@gohugo.io</a> website got a refresh. ๐Ÿ‘Œ</p> <p>Looks like the <a href="https://gohugo.io" data-hyper-mention>@gohugo.io</a> website got a refresh. ๐Ÿ‘Œ</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/links/1745349481000 2025-04-22T19:18:01Z 2025-04-22T19:18:01Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Markdown: this is the way. ๐ŸคŒ</p> <p>Markdown: this is the way. ๐ŸคŒ</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/links/1745281070000 2025-04-22T00:17:50Z 2025-04-22T00:17:50Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>The web never rests. I love seeing stuff like this from <a href="https://webkit.org" data-hyper-mention>@webkit.org</a> in the roadmap! <a href="/tags/html/" data-hyper-mention>#HTML</a></p> <p>The web never rests. I love seeing stuff like this from <a href="https://webkit.org" data-hyper-mention>@webkit.org</a> in the roadmap! <a href="/tags/html/" data-hyper-mention>#HTML</a></p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1743796578000 2025-04-04T19:56:18Z 2025-04-04T19:56:18Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Just got a Freshboi ๐Ÿ’ˆ</p> <p>Just got a Freshboi ๐Ÿ’ˆ</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1743788523000 2025-04-04T17:42:03Z 2025-04-04T17:42:03Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Setting up my HyperTextingโ€ฆ ๐ŸคŒ</p> <p>Setting up my HyperTextingโ€ฆ ๐ŸคŒ</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1743637686000 2025-04-02T23:48:06Z 2025-04-02T23:48:06Z Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>is experimentingโ€ฆ ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ”ฌ</p> <p>is experimentingโ€ฆ ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ”ฌ</p> New page https://calebhailey.com/posts/1743053292166 2025-03-26T22:28:12-07:00 2025-03-26T22:28:12-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>It's happening!! ๐Ÿ˜ฑ</p> <p>It's happening!! ๐Ÿ˜ฑ</p> New page https://calebhailey.com/posts/1743051854058 2025-03-26T22:04:14-07:00 2025-03-26T22:04:14-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Whoa! ๐Ÿคฏ</p> <p>Whoa! ๐Ÿคฏ</p> New page https://calebhailey.com/posts/1743051775653 2025-03-26T22:02:55-07:00 2025-03-26T22:02:55-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Test post from a new tool I've been working on. I hope this works!</p> <p>Test post from a new tool I've been working on. I hope this works!</p> customElements.apply() https://calebhailey.com/posts/customelements-apply 2025-02-12T11:00:00-08:00 2025-02-12T11:00:00-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <h2 id="customelementsapply"><code>customElements.apply()</code></h2> <p><strong>A (naive?) approach to workaround <code>customElements.define()</code> &quot;same tag name&quot; errors.</strong></p> <p>Web components have completely changed the way I write vanilla JavaScript. It turns out classes are quite useful for encapsulation (who knew?)! Complementary approaches like <a href="https://adactio.com/journal/20618">HTML web components</a> (and <a href="https://hawkticehurst.com/2024/11/css-web-components-for-marketing-sites/">CSS web components</a>) have <em>reduced</em> the amount of JavaScript I'm writing by about 95%. These ideas from <a href="https://adactio.com" data-hyper-mention>@adactio.com</a> and <a href="https://hawkticehurst.com" data-hyper-mention>@hawkticehurst.com</a> together with a steady stream of web component content from <a href="https://gomakethings.com" data-hyper-mention>@gomakethings.com</a> have revived my interest in modern web development.</p> <p>But recently I started running into a little speed bump. I've been exploring HTML templating workflows that enable me to compose sections and entire pages from a collection of layout &quot;partials&quot; (ala <a href="https://en.wikipedia.org/wiki/Server_Side_Includes">server side includes</a>). This sometimes causes multiple <code>&lt;script&gt;</code> tags to be added for a given web component, resulting in redundant calls to <code>customElements.define()</code> and a <em>&quot;cannot define multiple custom elements with the same tag name&quot;</em> error.</p> <alert-quote ht-element danger> <p><strong>NotSupportedError:</strong> Cannot define multiple custom elements with the same tag name.</p> </alert-quote> <p>My initial reaction to this was to move all <code>&lt;script src&gt;</code> tags into the <code>&lt;head&gt;</code>, but this inevitably resulted in failing to load a component's JavaScript on certain pages (dependency management fail). Then I read <a href="https://jakelazaroff.com" data-hyper-mention>@jakelazaroff.com</a>'s excellent <a href="https://til.jakelazaroff.com/html/define-a-custom-element/">Define a custom element</a> blog post and it opened my eyes to the many different approaches to managing custom elements. But I also felt like my challenge might have been slightly different than the problem Jake was solving. So I tried something different that has been working really well for me.</p> <p>It started with reviewing the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry"><code>CustomElementsRegistry</code></a> reference documentation and discovering that <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get"><code>get()</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/getName"><code>getName()</code></a> methods already existed. All that was needed was an idempotent method for registering custom elements. It turns out this was trivial to implement.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">CustomElementRegistry</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">apply</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">component</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="o">!!</span><span class="nx">component</span><span class="p">.</span><span class="nx">constructor</span> <span class="o">&amp;&amp;</span> <span class="nx">component</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&#34;class&#34;</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// guard </span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">tag</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// lookup by tag name </span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getName</span><span class="p">(</span><span class="nx">component</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// lookup by component class </span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span> <span class="k">try</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">define</span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">component</span><span class="p">)</span> <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">6</span><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="sb">`component </span><span class="si">${</span><span class="nx">component</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb"> already registered as &lt;</span><span class="si">${</span><span class="nx">tag</span><span class="si">}</span><span class="sb">&gt;`</span><span class="p">);</span> </span></span><span class="line"><span class="ln">7</span><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="p">};</span> </span></span></code></pre><p>This is already working so well for me that it's just about the only JavaScript I keep in <code>main.js</code> for new projects. I'm replacing calls to <code>customElements.define</code> with <code>customElements.apply</code> in all of my web component JavaScript.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">customElements</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="s2">&#34;my-element&#34;</span><span class="p">,</span> <span class="kr">class</span> <span class="nx">MyElement</span> <span class="kr">extends</span> <span class="nx">HTMLElement</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="c1">// this is where the magic happens ๐Ÿช„ </span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span><span class="p">});</span> </span></span></code></pre><p>In doing so, I can add <code>&lt;script src='/js/my-component.js'&gt;</code> tags in any layout partial without worrying about &quot;same tag name&quot; errors.</p> <p>Do you find this helpful? Or is this a horrible idea? &#x1f605; Send me an email and let me know what you think: <strong>hello [at] calebhailey.com</strong></p> <!-- Links --> <h2 id="customelementsapply"><code>customElements.apply()</code></h2> <p><strong>A (naive?) approach to workaround <code>customElements.define()</code> &quot;same tag name&quot; errors.</strong></p> <p>Web components have completely changed the way I write vanilla JavaScript. It turns out classes are quite useful for encapsulation (who knew?)! Complementary approaches like <a href="https://adactio.com/journal/20618">HTML web components</a> (and <a href="https://hawkticehurst.com/2024/11/css-web-components-for-marketing-sites/">CSS web components</a>) have <em>reduced</em> the amount of JavaScript I'm writing by about 95%. These ideas from <a href="https://adactio.com" data-hyper-mention>@adactio.com</a> and <a href="https://hawkticehurst.com" data-hyper-mention>@hawkticehurst.com</a> together with a steady stream of web component content from <a href="https://gomakethings.com" data-hyper-mention>@gomakethings.com</a> have revived my interest in modern web development.</p> <p>But recently I started running into a little speed bump. I've been exploring HTML templating workflows that enable me to compose sections and entire pages from a collection of layout &quot;partials&quot; (ala <a href="https://en.wikipedia.org/wiki/Server_Side_Includes">server side includes</a>). This sometimes causes multiple <code>&lt;script&gt;</code> tags to be added for a given web component, resulting in redundant calls to <code>customElements.define()</code> and a <em>&quot;cannot define multiple custom elements with the same tag name&quot;</em> error.</p> <alert-quote ht-element danger> <p><strong>NotSupportedError:</strong> Cannot define multiple custom elements with the same tag name.</p> </alert-quote> <p>My initial reaction to this was to move all <code>&lt;script src&gt;</code> tags into the <code>&lt;head&gt;</code>, but this inevitably resulted in failing to load a component's JavaScript on certain pages (dependency management fail). Then I read <a href="https://jakelazaroff.com" data-hyper-mention>@jakelazaroff.com</a>'s excellent <a href="https://til.jakelazaroff.com/html/define-a-custom-element/">Define a custom element</a> blog post and it opened my eyes to the many different approaches to managing custom elements. But I also felt like my challenge might have been slightly different than the problem Jake was solving. So I tried something different that has been working really well for me.</p> <p>It started with reviewing the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry"><code>CustomElementsRegistry</code></a> reference documentation and discovering that <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get"><code>get()</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/getName"><code>getName()</code></a> methods already existed. All that was needed was an idempotent method for registering custom elements. It turns out this was trivial to implement.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">CustomElementRegistry</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">apply</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">component</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="o">!!</span><span class="nx">component</span><span class="p">.</span><span class="nx">constructor</span> <span class="o">&amp;&amp;</span> <span class="nx">component</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&#34;class&#34;</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// guard </span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">tag</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// lookup by tag name </span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getName</span><span class="p">(</span><span class="nx">component</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="p">};</span> <span class="c1">// lookup by component class </span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span> <span class="k">try</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">define</span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">component</span><span class="p">)</span> <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">6</span><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="sb">`component </span><span class="si">${</span><span class="nx">component</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb"> already registered as &lt;</span><span class="si">${</span><span class="nx">tag</span><span class="si">}</span><span class="sb">&gt;`</span><span class="p">);</span> </span></span><span class="line"><span class="ln">7</span><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="p">};</span> </span></span></code></pre><p>This is already working so well for me that it's just about the only JavaScript I keep in <code>main.js</code> for new projects. I'm replacing calls to <code>customElements.define</code> with <code>customElements.apply</code> in all of my web component JavaScript.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">customElements</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="s2">&#34;my-element&#34;</span><span class="p">,</span> <span class="kr">class</span> <span class="nx">MyElement</span> <span class="kr">extends</span> <span class="nx">HTMLElement</span> <span class="p">{</span> </span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="c1">// this is where the magic happens ๐Ÿช„ </span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"></span><span class="p">});</span> </span></span></code></pre><p>In doing so, I can add <code>&lt;script src='/js/my-component.js'&gt;</code> tags in any layout partial without worrying about &quot;same tag name&quot; errors.</p> <p>Do you find this helpful? Or is this a horrible idea? &#x1f605; Send me an email and let me know what you think: <strong>hello [at] calebhailey.com</strong></p> <!-- Links --> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/the-only-intuitive-interface 2025-01-24T09:05:27-08:00 2025-01-24T09:05:27-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com iA https://ia.net/ @ia.net https://calebhailey.com/img/ia.net/apple-touch-icon.png <p>This post by <a href="https://ia.net" data-hyper-mention>@ia.net</a> reminds me of a quote I used to have permanently written on the top of the whiteboard in my office:</p> <blockquote> <p>The only intuitive interface is the nipple. Everything else is learned.</p> <p><strong>โ€” Bruce &quot;Tog&quot; Tognazzini</strong></p> </blockquote> <!-- https://asktog.com/atc/about-bruce-tognazzini/ --> <!-- https://en.wikipedia.org/wiki/Bruce_Tognazzini --> <p>My favorite quote from the interview is:</p> <pull-quote ht-element> <p>Design requires a willingness to make a fool of yourself by asking outrageous and offensive questions and to be amazed at things that seem perfectly normal to other people.</p> </pull-quote> <p>This post by <a href="https://ia.net" data-hyper-mention>@ia.net</a> reminds me of a quote I used to have permanently written on the top of the whiteboard in my office:</p> <blockquote> <p>The only intuitive interface is the nipple. Everything else is learned.</p> <p><strong>โ€” Bruce &quot;Tog&quot; Tognazzini</strong></p> </blockquote> <!-- https://asktog.com/atc/about-bruce-tognazzini/ --> <!-- https://en.wikipedia.org/wiki/Bruce_Tognazzini --> <p>My favorite quote from the interview is:</p> <pull-quote ht-element> <p>Design requires a willingness to make a fool of yourself by asking outrageous and offensive questions and to be amazed at things that seem perfectly normal to other people.</p> </pull-quote> 'Wherever you get your podcasts' is a radical statement. https://calebhailey.com/posts/1737586048096 2025-01-22T14:47:28-08:00 2025-01-22T14:47:28-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com Anil Dash https://www.anildash.com/ @anildash.com https://cdn.glitch.global/d45aff89-36ba-46db-8c7c-3da7c8a93931/microphone-pandelache.jpg?v=1706588470713 <p>Speaking of <a href="/tags/rss/" data-hyper-mention>#RSS</a>, I love this piece by <a href="https://anildash.com" data-hyper-mention>@anildash.com</a>.</p> <p>I've always wondered if one of the biggest differences <em>in adoption</em> between podcasts and text-based RSS feeds is that &quot;podcast&quot; has a catchy ring to it, and &quot;really simple sindication&quot; does not. Neither does <a href="https://en.wikipedia.org/wiki/RSS">&quot;RDF site summary&quot;</a>. It makes me further wonder if <a href="https://textcasting.org" data-hyper-mention>@textcasting.org</a> (by <a href="https://scripting.com" data-hyper-mention>@scripting.com</a>) is more important as (re-)branding for text-based RSS feeds than it is as an actual new standard.</p> <p>Speaking of <a href="/tags/rss/" data-hyper-mention>#RSS</a>, I love this piece by <a href="https://anildash.com" data-hyper-mention>@anildash.com</a>.</p> <p>I've always wondered if one of the biggest differences <em>in adoption</em> between podcasts and text-based RSS feeds is that &quot;podcast&quot; has a catchy ring to it, and &quot;really simple sindication&quot; does not. Neither does <a href="https://en.wikipedia.org/wiki/RSS">&quot;RDF site summary&quot;</a>. It makes me further wonder if <a href="https://textcasting.org" data-hyper-mention>@textcasting.org</a> (by <a href="https://scripting.com" data-hyper-mention>@scripting.com</a>) is more important as (re-)branding for text-based RSS feeds than it is as an actual new standard.</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1737483314095 2025-01-21T10:15:14-08:00 2025-01-21T10:15:14-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com About Feeds https://aboutfeeds.com/ @aboutfeeds.com https://aboutfeeds.com/favicon.ico <p>I've been looking for good resources to introduce people to <a href="/tags/rss/" data-hyper-mention>#RSS</a> and this looks like a great one by <a href="https://interconnected.org" data-hyper-mention>@interconnected.org</a>!</p> <p>I've been looking for good resources to introduce people to <a href="/tags/rss/" data-hyper-mention>#RSS</a> and this looks like a great one by <a href="https://interconnected.org" data-hyper-mention>@interconnected.org</a>!</p> How To Market A Game (@howtomarketagame.com) https://calebhailey.com/posts/1737483277370 2025-01-21T10:14:37-08:00 2025-01-21T10:14:37-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com How To Market A Game https://howtomarketagame.com/ @howtomarketagame.com https://howtomarketagame.com/wp-content/uploads/2020/01/cropped-small_logo512x512-1-180x180.png Tuesday, January 21, 2025 Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1736910338434 2025-01-14T19:05:38-08:00 2025-01-14T19:05:38-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com Steph Ango https://stephango.com/ @stephango.com https://stephango.com/apple-touch-icon.png <p>I've thought about this <a href="https://stephango.com" data-hyper-mention>@stephango.com</a> blog post at least once per week for the last ~18 months.</p> <p>Just added this to my <a href="/inspired-by">inspired by</a> hall of fame.</p> <p>I've thought about this <a href="https://stephango.com" data-hyper-mention>@stephango.com</a> blog post at least once per week for the last ~18 months.</p> <p>Just added this to my <a href="/inspired-by">inspired by</a> hall of fame.</p> Daring Fireball (@daringfireball.net) https://calebhailey.com/posts/1736404743546 2025-01-08T22:39:03-08:00 2025-01-08T22:39:03-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com Daring Fireball https://daringfireball.net/ @daringfireball.net https://daringfireball.net/graphics/apple-touch-icon.png Wednesday, January 8, 2025 Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1736282628377 2025-01-07T12:43:48-08:00 2025-01-07T12:43:48-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>I still haven't used <a href="https://htmx.org" data-hyper-mention>@htmx.org</a>, but I've read the <a href="/tags/hypermedia/" data-hyper-mention>#HyperMedia</a> book and I'm a big fan of their ideas and where the project is headed overall. ๐Ÿš€</p> <p><a href="/tags/html/" data-hyper-mention>#html</a> <a href="/tags/htmx/" data-hyper-mention>#htmx</a> <a href="/tags/javascript/" data-hyper-mention>#javascript</a></p> <p>I still haven't used <a href="https://htmx.org" data-hyper-mention>@htmx.org</a>, but I've read the <a href="/tags/hypermedia/" data-hyper-mention>#HyperMedia</a> book and I'm a big fan of their ideas and where the project is headed overall. ๐Ÿš€</p> <p><a href="/tags/html/" data-hyper-mention>#html</a> <a href="/tags/htmx/" data-hyper-mention>#htmx</a> <a href="/tags/javascript/" data-hyper-mention>#javascript</a></p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1735957697150 2025-01-03T18:28:17-08:00 2025-01-03T18:28:17-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com This is hands-down my favorite craft cocktail website. ๐Ÿน This is hands-down my favorite craft cocktail website. ๐Ÿน Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1735944025063 2025-01-03T14:40:25-08:00 2025-01-03T14:40:25-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>I'm loving the new <a href="https://vw.com" data-hyper-mention>@vw.com</a> ID Buzz.</p> <p>And my new scrolling image gallery. ๐Ÿ˜Ž</p> <p>๐Ÿ‘ˆ๐Ÿฝ Swipe ๐Ÿ‘‰๐Ÿฝ</p> <p>I'm loving the new <a href="https://vw.com" data-hyper-mention>@vw.com</a> ID Buzz.</p> <p>And my new scrolling image gallery. ๐Ÿ˜Ž</p> <p>๐Ÿ‘ˆ๐Ÿฝ Swipe ๐Ÿ‘‰๐Ÿฝ</p> <!--more--> <p>Pretty cool, right?!</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/links/1735863820561 2025-01-02T16:23:40-08:00 2025-01-02T16:23:40-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com More like fast trashion, amirite? :sweat_smile: More like fast trashion, amirite? :sweat_smile: Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1734564951607 2024-12-18T15:35:51-08:00 2024-12-18T15:35:51-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <h2 id="keep-it-on-the-markdown-low">Keep it on the markdown-low</h2> <p>First post with my custom <a href="/tags/markdown/" data-hyper-mention>#markdown</a> parser.</p> <p>Here's a little sample code block to show off the <code>&lt;code&gt;</code> syntax highlighting.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#39;en-US&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 4</span><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/head.html&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 5</span><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">itemprop</span><span class="o">=</span><span class="s">&#39;template.name&#39;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#39;default&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 6</span><span class="cl"> </span></span><span class="line"><span class="ln"> 7</span><span class="cl"> <span class="c">&lt;!-- Web Components --&gt;</span> </span></span><span class="line"><span class="ln"> 8</span><span class="cl"> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#39;/js/components/relative-time.js&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 9</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">11</span><span class="cl"> <span class="p">&lt;</span><span class="nt">nav</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/nav.html&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="p">&lt;</span><span class="nt">content-whitespace</span><span class="p">&gt;&lt;/</span><span class="nt">content-whitespace</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">13</span><span class="cl"> <span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">&#39;post&#39;</span> <span class="na">data-color-scheme</span><span class="o">=</span><span class="s">&#39;light&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">14</span><span class="cl"> <span class="p">&lt;</span><span class="nt">article</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/post-article&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">article</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">15</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">16</span><span class="cl"> <span class="p">&lt;</span><span class="nt">content-whitespace</span><span class="p">&gt;&lt;/</span><span class="nt">content-whitespace</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">17</span><span class="cl"> <span class="p">&lt;</span><span class="nt">footer</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/footer.html&#39;</span> <span class="na">data-color-scheme</span><span class="o">=</span><span class="s">&#39;dark&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">18</span><span class="cl"> <span class="p">&lt;</span><span class="nt">section</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/tail.html&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">section</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">19</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre><p>This is all table stakes stuff, but I'm pumped to get it all wired up!</p> <h2 id="keep-it-on-the-markdown-low">Keep it on the markdown-low</h2> <p>First post with my custom <a href="/tags/markdown/" data-hyper-mention>#markdown</a> parser.</p> <p>Here's a little sample code block to show off the <code>&lt;code&gt;</code> syntax highlighting.</p> <pre tabindex="0" class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#39;en-US&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 4</span><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/head.html&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 5</span><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">itemprop</span><span class="o">=</span><span class="s">&#39;template.name&#39;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#39;default&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 6</span><span class="cl"> </span></span><span class="line"><span class="ln"> 7</span><span class="cl"> <span class="c">&lt;!-- Web Components --&gt;</span> </span></span><span class="line"><span class="ln"> 8</span><span class="cl"> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#39;/js/components/relative-time.js&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln"> 9</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">11</span><span class="cl"> <span class="p">&lt;</span><span class="nt">nav</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/nav.html&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="p">&lt;</span><span class="nt">content-whitespace</span><span class="p">&gt;&lt;/</span><span class="nt">content-whitespace</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">13</span><span class="cl"> <span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">&#39;post&#39;</span> <span class="na">data-color-scheme</span><span class="o">=</span><span class="s">&#39;light&#39;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">14</span><span class="cl"> <span class="p">&lt;</span><span class="nt">article</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/post-article&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">article</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">15</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">16</span><span class="cl"> <span class="p">&lt;</span><span class="nt">content-whitespace</span><span class="p">&gt;&lt;/</span><span class="nt">content-whitespace</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">17</span><span class="cl"> <span class="p">&lt;</span><span class="nt">footer</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/footer.html&#39;</span> <span class="na">data-color-scheme</span><span class="o">=</span><span class="s">&#39;dark&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">18</span><span class="cl"> <span class="p">&lt;</span><span class="nt">section</span> <span class="na">ht-include</span><span class="o">=</span><span class="s">&#39;partials/tail.html&#39;</span><span class="p">&gt;&lt;/</span><span class="nt">section</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">19</span><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre><p>This is all table stakes stuff, but I'm pumped to get it all wired up!</p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1710964320000 2024-03-20T12:52:00-07:00 2024-03-20T12:52:00-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Just started reading &quot;Filterworld&quot;, by <a href="https://kylechayka.com" data-hyper-mention>@kylechayka.com</a>, and it starts with a picture from <a href="https://en.wikipedia.org/wiki/Mechanical_Turk">one of my favorite Wikipedia pages</a> of all time. I think I'm gonna like this book!</p> <p><a href="/tags/nowreading/" data-hyper-mention>#NowReading</a></p> <p>Just started reading &quot;Filterworld&quot;, by <a href="https://kylechayka.com" data-hyper-mention>@kylechayka.com</a>, and it starts with a picture from <a href="https://en.wikipedia.org/wiki/Mechanical_Turk">one of my favorite Wikipedia pages</a> of all time. I think I'm gonna like this book!</p> <p><a href="/tags/nowreading/" data-hyper-mention>#NowReading</a></p> Caleb Hailey (@calebhailey.com) https://calebhailey.com/posts/1710625680000 2024-03-16T13:48:00-08:00 2024-03-16T13:48:00-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>TIL about the <a href="/tags/html/" data-hyper-mention>#HTML</a> <code>&lt;base&gt;</code> element!</p> <p>TIL about the <a href="/tags/html/" data-hyper-mention>#HTML</a> <code>&lt;base&gt;</code> element!</p> Herd Works (@herd.works) https://calebhailey.com/posts/1676408460000 2023-02-14T13:01:00-08:00 2023-02-14T13:01:00-08:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com Herd Works https://herd.works/ @herd.works https://herd.works/apple-touch-icon-57x57.png?v=1 Tuesday, February 14, 2023 The Best Chef in the World https://calebhailey.com/posts/sally-schmidt 2022-10-08T14:30:00-07:00 2022-10-08T14:30:00-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com YouTube https://www.youtube.com/ @youtube.com https://www.youtube.com/s/desktop/648a021a/img/logos/favicon_144x144.png <blockquote> <p>Originally posted on <a href="https://sheesh.blog" data-hyper-mention>@sheesh.blog</a>.</p> </blockquote> <p>As soon as you have 20 minutes to spare, I encourage you to go watch this short film about <a href="https://www.nytimes.com/2022/09/13/opinion/sally-schmitt-french-laundry.html">Sally Schmidt</a>, produced by Oscarยฎ award winning documentary filmmaker <a href="https://twitter.com/bgproudfoot">Ben Proudfoot</a>, for the <a href="https://nytimes.com" data-hyper-mention>@nytimes.com</a><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p> <p>Speaking of <a href="https://sheesh.blog/posts/popup-restaurant-theory">restaurants</a>, Sally started a little establishment you might have heard of called <a href="https://www.thomaskeller.com/early-history">The French Laundry</a>. &#x1f90c;</p> <blockquote> <p>Originally posted on <a href="https://sheesh.blog" data-hyper-mention>@sheesh.blog</a>.</p> </blockquote> <p>As soon as you have 20 minutes to spare, I encourage you to go watch this short film about <a href="https://www.nytimes.com/2022/09/13/opinion/sally-schmitt-french-laundry.html">Sally Schmidt</a>, produced by Oscarยฎ award winning documentary filmmaker <a href="https://twitter.com/bgproudfoot">Ben Proudfoot</a>, for the <a href="https://nytimes.com" data-hyper-mention>@nytimes.com</a><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p> <p>Speaking of <a href="https://sheesh.blog/posts/popup-restaurant-theory">restaurants</a>, Sally started a little establishment you might have heard of called <a href="https://www.thomaskeller.com/early-history">The French Laundry</a>. &#x1f90c;</p> <!--more--> <p>I particularly like this comment in the accompanying article:</p> <pull-quote ht-element cite='Ben Proudfoot' href='https://www.nytimes.com/2022/09/13/opinion/sally-schmitt-french-laundry.html'> <p>Talking to Ms. Schmitt that morning, I learned she held a different kind of wisdom: that success may have other definitions.</p> </pull-quote> <p>Now that's what I call <a href="https://sheesh.blog/posts/life-work-balance">life-work <em>balance</em></a>!</p> <!-- Footnotes --> <!-- Links --> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1"> <p><a href="https://www.nytimes.com/column/op-docs">Op-Docs</a> is a New York Times production of &quot;Oscar-winning series of short documentaries by independent filmmakers&quot;. This might be one of my new favorite places on the internet.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> </ol> </div> Long time listener, first time caller https://calebhailey.com/posts/long-time-listener 2022-04-24T20:26:18-07:00 2022-04-24T20:26:18-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <blockquote> <p>Originally posted on <a href="https://sheesh.blog" data-hyper-mention>@sheesh.blog</a>.</p> </blockquote> <h2 id="long-time-listener-first-time-caller">Long time listener, first time caller</h2> <p>I can't remember the last time I read a book from front to back<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, but I am a voracious reader. The thing is, I prefer to read &quot;the internet&quot; instead of books.</p> <p>At some point early on in my internet journey I discovered <a href="/tags/rss/" data-hyper-mention>#RSS</a> and I immediately fell in love<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. My RSS feed became like my own personal newspaper, where I was the curator. I could add and remove <del>columnists</del> blog feeds as my <a href="/about#interest-graph">interest graph</a> would change over time. I was one of the many<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> who decried the death of Google Reader. RSS lives on, but it's not as ubiquitious as it once was.</p> <p>For some years my feed shifted from RSS to social media โ€” almost exclusively Twitter, and mostly via Twitter Lists โ€” but a few trends in recent years have brought me back to RSS:</p> <ol> <li>RSS services are great again<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>.</li> <li>RSS apps are <a href="https://www.macstories.net/reviews/netnewswire-review-the-mac-rss-client-rebooted-with-a-solid-foundation-for-the-future/">making</a> <a href="https://thesweetsetup.com/netnewswire-5-0-relaunches-as-an-open-source-rss-reader-for-the-mac/">a</a> <a href="https://daringfireball.net/linked/2019/08/29/netnewswire-5">comeback</a>!</li> <li>&quot;Doomscrolling&quot; became a thingโ„ข๏ธ, prompting a renewed need to curate my feed.</li> </ol> <p>With my newfound replacement for Google Reader's service (<a href="https://feedbin.com">Feedbin.com</a>), and my favorite old RSS reader app making a glorious (and <a href="https://github.com/Ranchero-Software/NetNewsWire">open source</a>!!) comeback, I decided to start the curation process from scratch. I created folders for &quot;News&quot;, &quot;People&quot;, &quot;Portland&quot; (my local happenings), &quot;Products&quot;, &quot;Startups&quot;, and &quot;Tech&quot;.</p> <p>And then I started subscribing. And I discovered that the very first feeds I added were the very same feeds I've been reading all along. A combination of overlapping <a href="/about#interest-graph">interest graphs</a> (I'm assuming) and writing styles have kept me reading certain blogs for over a decade now. These are the bloggers who's writing has both intimidated me โ€“ because I hold them in high esteem โ€“ and inspired me to start this blog.</p> <p>I have feared that if I ever started a blog I would appear as a copy cat, a cheap imitation of these now-veterans who probably started like I am starting right now. But I decided that instead of shying away from writing, I should lean into it. Give credit where credit is due. Start my blog, in my own voice (however heavily &quot;inspired by&quot; it may be), and acknowledge those who went before me.</p> <p>Starting a blog is easy. Buy a domain โœ… write an <a href="/about">/about</a> page โœ… write a <a href="https://sheesh.blog/posts/helloworld">&quot;hello, world&quot;</a> โœ… smash the publish button. ๐Ÿ’ฅ But for me, I could not have started this blog without acknowledging who this blog was <a href="/inspired-by">inspired by</a>.</p> <p>โœŒ๏ธ</p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1"> <p>I mean, I do remember the last book I read, but it's embarrasing. ๐Ÿ˜…&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:2"> <p>FUN FACT: fast forward many years later and I somehow had the privilege of working with <a href="https://www.linkedin.com/in/mshobe/">Matt Shobe</a> โ€“ one of the co-founders of Feedburner (<a href="https://techcrunch.com/2007/05/23/100-million-payday-for-feedburner-this-deal-is-confirmed/">acquired by Google</a> in 2007). And by &quot;working with&quot; I mean he became an angel investor in my first company, and a critical advisor in our early stages.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:3"> <p>Or <em>few</em>, I guess. Otherwise we would still have Google Reader?&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:4"> <p>In the years following the death of Google Reader (RIP), I tried a handful of apps and services that built replacements for Google Reader โ€” from Feedly to Flipboard (powered by a carefully curated Twitter list) โ€“ but nothing stuck. Then a few years ago I tried Feedbin, and subsequently discovered its <a href="https://feedbin.com/blog/2016/02/03/subscribe-to-email-newsletters-in-feedbin/">support for Newsletters</a> (at a time when it seemed like everyone was starting a SubStack), and I almost forgot that Google Reader ever existed.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> </ol> </div> <blockquote> <p>Originally posted on <a href="https://sheesh.blog" data-hyper-mention>@sheesh.blog</a>.</p> </blockquote> <h2 id="long-time-listener-first-time-caller">Long time listener, first time caller</h2> <p>I can't remember the last time I read a book from front to back<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, but I am a voracious reader. The thing is, I prefer to read &quot;the internet&quot; instead of books.</p> <p>At some point early on in my internet journey I discovered <a href="/tags/rss/" data-hyper-mention>#RSS</a> and I immediately fell in love<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. My RSS feed became like my own personal newspaper, where I was the curator. I could add and remove <del>columnists</del> blog feeds as my <a href="/about#interest-graph">interest graph</a> would change over time. I was one of the many<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> who decried the death of Google Reader. RSS lives on, but it's not as ubiquitious as it once was.</p> <p>For some years my feed shifted from RSS to social media โ€” almost exclusively Twitter, and mostly via Twitter Lists โ€” but a few trends in recent years have brought me back to RSS:</p> <ol> <li>RSS services are great again<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>.</li> <li>RSS apps are <a href="https://www.macstories.net/reviews/netnewswire-review-the-mac-rss-client-rebooted-with-a-solid-foundation-for-the-future/">making</a> <a href="https://thesweetsetup.com/netnewswire-5-0-relaunches-as-an-open-source-rss-reader-for-the-mac/">a</a> <a href="https://daringfireball.net/linked/2019/08/29/netnewswire-5">comeback</a>!</li> <li>&quot;Doomscrolling&quot; became a thingโ„ข๏ธ, prompting a renewed need to curate my feed.</li> </ol> <p>With my newfound replacement for Google Reader's service (<a href="https://feedbin.com">Feedbin.com</a>), and my favorite old RSS reader app making a glorious (and <a href="https://github.com/Ranchero-Software/NetNewsWire">open source</a>!!) comeback, I decided to start the curation process from scratch. I created folders for &quot;News&quot;, &quot;People&quot;, &quot;Portland&quot; (my local happenings), &quot;Products&quot;, &quot;Startups&quot;, and &quot;Tech&quot;.</p> <p>And then I started subscribing. And I discovered that the very first feeds I added were the very same feeds I've been reading all along. A combination of overlapping <a href="/about#interest-graph">interest graphs</a> (I'm assuming) and writing styles have kept me reading certain blogs for over a decade now. These are the bloggers who's writing has both intimidated me โ€“ because I hold them in high esteem โ€“ and inspired me to start this blog.</p> <p>I have feared that if I ever started a blog I would appear as a copy cat, a cheap imitation of these now-veterans who probably started like I am starting right now. But I decided that instead of shying away from writing, I should lean into it. Give credit where credit is due. Start my blog, in my own voice (however heavily &quot;inspired by&quot; it may be), and acknowledge those who went before me.</p> <p>Starting a blog is easy. Buy a domain โœ… write an <a href="/about">/about</a> page โœ… write a <a href="https://sheesh.blog/posts/helloworld">&quot;hello, world&quot;</a> โœ… smash the publish button. ๐Ÿ’ฅ But for me, I could not have started this blog without acknowledging who this blog was <a href="/inspired-by">inspired by</a>.</p> <p>โœŒ๏ธ</p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1"> <p>I mean, I do remember the last book I read, but it's embarrasing. ๐Ÿ˜…&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:2"> <p>FUN FACT: fast forward many years later and I somehow had the privilege of working with <a href="https://www.linkedin.com/in/mshobe/">Matt Shobe</a> โ€“ one of the co-founders of Feedburner (<a href="https://techcrunch.com/2007/05/23/100-million-payday-for-feedburner-this-deal-is-confirmed/">acquired by Google</a> in 2007). And by &quot;working with&quot; I mean he became an angel investor in my first company, and a critical advisor in our early stages.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:3"> <p>Or <em>few</em>, I guess. Otherwise we would still have Google Reader?&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> <li id="fn:4"> <p>In the years following the death of Google Reader (RIP), I tried a handful of apps and services that built replacements for Google Reader โ€” from Feedly to Flipboard (powered by a carefully curated Twitter list) โ€“ but nothing stuck. Then a few years ago I tried Feedbin, and subsequently discovered its <a href="https://feedbin.com/blog/2016/02/03/subscribe-to-email-newsletters-in-feedbin/">support for Newsletters</a> (at a time when it seemed like everyone was starting a SubStack), and I almost forgot that Google Reader ever existed.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> </ol> </div> Hello, world https://calebhailey.com/posts/helloworld 2022-04-23T18:15:55-07:00 2022-04-23T18:15:55-07:00 Caleb Hailey https://calebhailey.com/ @calebhailey.com https://calebhailey.com/favicon.jpeg hello@calebhailey.com <p>Every new blog should start with an obligatory <a href="https://en.wikipedia.org/wiki/%22Hello,_World!%22_program#History">&quot;hello, world&quot;</a> โ€” so here I am doing just that. My experience with blogging has generally rhymed with the experience a former co-worker of mine once shared:</p> <blockquote> <p>&quot;Iโ€™ve started seven different blogs. Every one had one post.&quot;</p> <p>โ€” <strong>Derek Newsom</strong></p> </blockquote> <p>Something feels different this time, but only time will tell.</p> <p>โœŒ๏ธ</p> <p>Every new blog should start with an obligatory <a href="https://en.wikipedia.org/wiki/%22Hello,_World!%22_program#History">&quot;hello, world&quot;</a> โ€” so here I am doing just that. My experience with blogging has generally rhymed with the experience a former co-worker of mine once shared:</p> <blockquote> <p>&quot;Iโ€™ve started seven different blogs. Every one had one post.&quot;</p> <p>โ€” <strong>Derek Newsom</strong></p> </blockquote> <p>Something feels different this time, but only time will tell.</p> <p>โœŒ๏ธ</p>