<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Syntackle</title>
  <subtitle>A developer blog</subtitle>
  <link href="https://syntackle.com/feed.xml" rel="self"/>
  <link href="https://syntackle.com/"/>
  <updated>2026-03-22T09:36:29Z</updated>
  <id>https://syntackle.com/</id>
  <author>
    <name>Murtuzaali Surti</name>
    <email>hey.murtuza@gmail.com</email>
  </author>
  
  <entry>
    <title>Open Source AI Coding Agents to Try for Free</title>
    <link href="https://syntackle.com/blog/opensource-ai-coding-agents-to-try/"/>
    <published>2026-03-22T09:36:29Z</published>
    <updated>2026-03-29T07:21:25Z</updated>
    <id>https://syntackle.com/blog/opensource-ai-coding-agents-to-try/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;There is no shortage of AI coding tools right now, but the ones that get the most attention are almost always proprietary such as &lt;a href=&quot;https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/&quot;&gt;Claude Code&lt;/a&gt;, Codex, and Cursor. They are well-marketed and easy to get started with. But they also come with tradeoffs such as not owning the workflow, you cannot swap providers freely, and you are locked into one vendor&#39;s pricing.&lt;/p&gt;
&lt;p&gt;Open source AI coding agents are getting really good. I have been using a few of them in my own workflow, and the biggest thing I have learned is that &lt;strong&gt;the model quality is not the only differentiator anymore&lt;/strong&gt;, in fact, most of these tools connect to the same frontier models. What actually matters is asking the right questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Does it fit how you already work?&lt;/strong&gt; Terminal-first, editor-first, or GUI-first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How much control does it give you?&lt;/strong&gt; Provider switching, context management, prompt engineering, extensibility.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Can you switch providers and models easily?&lt;/strong&gt; Useful especially when rate limits hit or you want to try a cheaper model for routine tasks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What is the Claude situation?&lt;/strong&gt; Anthropic recently pushed back on some tools legally, and that has changed the subscription access story in ways that directly affect which tool is best for whom.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;When I say &lt;em&gt;free&lt;/em&gt;, I mean &lt;em&gt;free to install and try&lt;/em&gt;. That does not always mean zero cost. Your running cost depends on API pricing, credits, free-tier models, or whether the tool lets you use an existing subscription login.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;opencode&quot; tabindex=&quot;-1&quot;&gt;OpenCode&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The strongest ai coding agent offering the best TUI experience.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1774767120/Syntackle/Posts/opencode-banner_c9dtct.png&quot; alt=&quot;OpenCode&#39;s Logo&quot; height=&quot;854&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://opencode.ai/&quot;&gt;OpenCode&lt;/a&gt; is for you if you already like working in a terminal. Docs say it supports &lt;strong&gt;75+ providers&lt;/strong&gt; plus local models, and it ships with a workflow that makes sense, &amp;quot;Build&amp;quot; for full access and &amp;quot;Plan&amp;quot; for a safer, read-only-first pass.&lt;/p&gt;
&lt;p&gt;If your idea of AI coding is &amp;quot;let me stay in the terminal and get real work done,&amp;quot; OpenCode makes immediate sense. They also introduced OpenCode Desktop app for all platforms and is currently in beta at the time of this writing.&lt;/p&gt;
&lt;p&gt;OpenCode is also one of the best tools for switching between providers and models. Its provider agnostic approach is one of the core reasons to use it.&lt;/p&gt;
&lt;p&gt;The downside is that OpenCode is now less attractive for Claude subscription users because you can&#39;t use your existing Claude subscription inside OpenCode and you must use an API key.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pick OpenCode if&lt;/strong&gt; you are a terminal-first developer and want the strongest default agent workflow without spending time assembling the system yourself. Also a good pick if you switch between providers and models often.&lt;/p&gt;
&lt;h2 id=&quot;pi&quot; tabindex=&quot;-1&quot;&gt;pi&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The best pick for heavy users who want control.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1774767606/Syntackle/Posts/pi-logo-dark_azt0vi.png&quot; alt=&quot;Pi&#39;s Logo&quot; height=&quot;854&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://pi.dev/&quot;&gt;pi&lt;/a&gt; is the tool I would recommend to people who use coding agents a lot and start feeling constrained by defaults.&lt;/p&gt;
&lt;p&gt;pi&#39;s official site calls it a &lt;em&gt;minimal terminal coding harness&lt;/em&gt; and that is exactly what it is. pi gives you a strong base and lets you shape it through extensions, skills, prompt templates, themes, and packages. pi gives you more of that control than the others.&lt;/p&gt;
&lt;p&gt;However, with more customizability, comes more of a steep learning curve. You need to learn how to glue these pieces together and make the best use of them.&lt;/p&gt;
&lt;p&gt;pi also explicitly supports Anthropic Claude Pro/Max subscriptions. If Claude subscription access matters, that alone makes pi more attractive than OpenCode right now.&lt;/p&gt;
&lt;p&gt;Like OpenCode, pi makes switching between models and providers feel natural. If you move between providers depending on task, budget, or rate limits, pi handles that well, much more smoothly than T3 Code did in my testing.&lt;/p&gt;
&lt;p&gt;pi is less opinionated out of the box. Some developers love that. Others want something more pre-configured.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pick pi if&lt;/strong&gt; you are a heavy user and want more control than convenience. Also the clearest choice right now if Claude subscription access is a deciding factor.&lt;/p&gt;
&lt;h2 id=&quot;t3-code&quot; tabindex=&quot;-1&quot;&gt;T3 Code&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The best GUI-first option, but more constrained.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1774767859/Syntackle/Posts/t3-logo-dark_d02fp4.png&quot; alt=&quot;T3 Code&#39;s Logo&quot; height=&quot;854&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;If OpenCode and pi are terminal-native tools, &lt;a href=&quot;https://t3.codes/&quot;&gt;T3 Code&lt;/a&gt; is the option for people who want a cleaner visual layer. Not everyone wants to do agentic coding inside a TUI, and T3 Code respects that.&lt;/p&gt;
&lt;p&gt;T3 Code now lets you access Claude models via existing Claude subscription if you have Claude Code CLI installed and signed in.&lt;/p&gt;
&lt;p&gt;However, T3 Code is more constrained than the others. In my testing, T3 Code did not let me switch models across providers in the same session, the way OpenCode and pi do. If you like moving between providers based on task, budget, or availability in the same session, T3 Code can feel more limited.&lt;/p&gt;
&lt;p&gt;Considering that limitation, plus the project still in its early stages, I see T3 Code more as a &lt;strong&gt;GUI convenience layer&lt;/strong&gt; than the most flexible agent in this comparison.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pick T3 Code if&lt;/strong&gt; your requirement is the best GUI experience. Just know that the workflow is more constrained and T3 Code is younger than the rest.&lt;/p&gt;
&lt;h2 id=&quot;kilo-code&quot; tabindex=&quot;-1&quot;&gt;Kilo Code&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Good for integrations and team oriented workflows.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1774768747/Syntackle/Posts/kilo-dark-logo_x5grax.png&quot; alt=&quot;Kilo Code&#39;s Logo&quot; height=&quot;854&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;If your workflow is editor-first and maybe team-oriented, &lt;a href=&quot;https://kilo.ai/&quot;&gt;Kilo&lt;/a&gt; makes sense. It has a stronger story around structured modes, code reviews, cloud execution, free/budget model guidance, and local models through Ollama and LM Studio.&lt;/p&gt;
&lt;p&gt;While OpenCode and pi feel like tools for developers who think from the terminal outward, Kilo feels like a tool for developers who think from the editor and team workflow outward.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;Kilo CLI is actually a fork of OpenCode.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The downside is that it is simply bigger. If you want something minimal, Kilo can feel like more product than you asked for. And credits still remain part of the usage story even with its documented free model paths.&lt;/p&gt;
&lt;p&gt;Kilo does not support subscription based access and only supports API key authentication if you want to use a different &lt;a href=&quot;https://kilo.ai/docs/ai-providers&quot;&gt;provider&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pick Kilo if&lt;/strong&gt; you are editor first, team-workflow first, or want a broader product/platform with modes, reviews, cloud agents and integrations.&lt;/p&gt;
&lt;h2 id=&quot;thing-to-note&quot; tabindex=&quot;-1&quot;&gt;Thing To Note&lt;/h2&gt;
&lt;p&gt;OpenCode used to be more attractive for Anthropic (Claude) subscription users because of the Claude Pro/Max auth plugin. That has changed. &lt;a href=&quot;https://x.com/thdxr/status/2034730036759339100?s=20&quot;&gt;dax (thdxr) posted on X&lt;/a&gt; that &lt;code&gt;opencode 1.3.0&lt;/code&gt; would &lt;em&gt;no longer autoload the Claude Pro/Max auth plugin&lt;/em&gt; after Anthropic pushed back legally. So if you use OpenCode with Anthropic today, think in terms of &lt;em&gt;API/provider pricing&lt;/em&gt;, not a convenient subscription based pricing.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;pi&lt;/em&gt; still officially lists &amp;quot;Anthropic Claude Pro/Max&amp;quot; under supported subscriptions, and &lt;em&gt;T3 Code&lt;/em&gt; now supports Claude too if you have &lt;em&gt;Claude Code CLI installed and signed in&lt;/em&gt; — &lt;a href=&quot;https://x.com/theo/status/2034831968463200359?s=20&quot;&gt;Theo, the creator of T3Code, confirmed this on X&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;table-wrapper&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;th&gt;What stands out&lt;/th&gt;
&lt;th&gt;Main catch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenCode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Terminal-first developers&lt;/td&gt;
&lt;td&gt;Build/Plan workflow, 75+ providers, local models&lt;/td&gt;
&lt;td&gt;Anthropic usage is API-priced now&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;pi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Heavy users who want control&lt;/td&gt;
&lt;td&gt;Most customizable, subscription support, provider flexibility&lt;/td&gt;
&lt;td&gt;Less opinionated out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T3 Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GUI-first users&lt;/td&gt;
&lt;td&gt;Clean visual layer, Claude via Claude Code CLI&lt;/td&gt;
&lt;td&gt;More constrained workflow, early project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kilo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Editor/platform-first users&lt;/td&gt;
&lt;td&gt;Modes, code reviews, cloud agents, local models&lt;/td&gt;
&lt;td&gt;Bigger surface, credits still matter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;final-thoughts&quot; tabindex=&quot;-1&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenCode&lt;/strong&gt; is the strongest ai coding agent offering the best TUI experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pi&lt;/strong&gt; is the best fit for heavy users who want more control (can use Claude subscription).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T3 Code&lt;/strong&gt; is the easiest GUI-first option, but more constrained (can use Claude subscription).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kilo&lt;/strong&gt; is a platform, good for integrations and team oriented workflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you think in terms of workflow instead of hype, the decision gets much easier.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/opensource-ai-coding-agents-to-try/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>A Million Token Context Window Isn&#39;t What You Think It Is</title>
    <link href="https://syntackle.com/blog/long-context-window-ai-model-catch/"/>
    <published>2026-03-15T05:08:07Z</published>
    <updated>2026-03-18T10:12:34Z</updated>
    <id>https://syntackle.com/blog/long-context-window-ai-model-catch/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Anthropic recently announced that &amp;quot;1 Million token context window&amp;quot; is now generally available to all users for Claude Opus 4.6 and Sonnet 4.6 models. It&#39;s amazing that in a couple of years, we went from GPT-3 with a 4K token context window (feels ancient), to Google becoming the first AI company to introduce a 1M token context window AI model, and Meta taking it as far as introducing a 10M token context window model &amp;quot;Llama 4 Scout&amp;quot;.&lt;/p&gt;
&lt;p&gt;Now all of this looks good on paper, but is it actually good or are the AI companies cashing in on the idea of a larger context window? There&#39;s a catch, let me explain.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;what-is-the-context-window%3F&quot; tabindex=&quot;-1&quot;&gt;What Is The Context Window?&lt;/h2&gt;
&lt;p&gt;A context window is the maximum amount of input (that includes responses) an AI model can &amp;quot;see&amp;quot; at once, both what I send it (the input) and what it generates (the output). It&#39;s measured in tokens (chunks of input/output), where the token length varies per AI model implementation.&lt;/p&gt;
&lt;p&gt;Think of it like a desk. Everything I want the model to work with (my ask, the documents I paste in, the conversation history) has to fit on that desk. If something doesn&#39;t fit, it gets left out entirely. The model has zero knowledge of anything outside its context window.&lt;/p&gt;
&lt;p&gt;When I send a prompt, the model reads the entire context window at once. It processes all tokens simultaneously using an attention mechanism. This mechanism decides which parts of the input are the most relevant to generating each word of the output.&lt;/p&gt;
&lt;p&gt;Every new message in a conversation gets appended to the existing context. Once the total (input + output) exceeds the window limit, the model forgets the oldest messages (however, modern &lt;a href=&quot;https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/&quot;&gt;AI agents&lt;/a&gt; do automatic &amp;quot;compaction&amp;quot;, which preserves just the summary of the conversation to try to fit it in). This is why long conversations can feel like the model &amp;quot;lost track&amp;quot; of something you said earlier.&lt;/p&gt;
&lt;h2 id=&quot;the-actual-good&quot; tabindex=&quot;-1&quot;&gt;The Actual Good&lt;/h2&gt;
&lt;p&gt;A larger context window has a lot of great use cases, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Feeding an &lt;a href=&quot;https://syntackle.com/blog/vibe-coding/&quot;&gt;entire codebase&lt;/a&gt; in one go so the model understands how everything connects.&lt;/li&gt;
&lt;li&gt;Analyzing long documents (legal contracts, research papers, books) without processing or splitting them into chunks.&lt;/li&gt;
&lt;li&gt;Maintaining long conversations where earlier context matters (e.g. a back-and-forth code debugging session).&lt;/li&gt;
&lt;li&gt;Reducing the need for complex retrieval pipelines (RAG). Instead of searching a vector database for relevant snippets, you just paste it in.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-catch&quot; tabindex=&quot;-1&quot;&gt;The Catch&lt;/h2&gt;
&lt;p&gt;The bigger the context, the higher the risk of the &amp;quot;lost in the middle&amp;quot; problem. The &amp;quot;lost in the middle&amp;quot; problem is where models pay strong attention to the &lt;em&gt;beginning&lt;/em&gt; and &lt;em&gt;end&lt;/em&gt; of the long context but degrade significantly at recalling information placed in the &lt;em&gt;middle&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This was documented by Liu et al. in their 2023 research paper &lt;a href=&quot;https://arxiv.org/abs/2307.03172&quot;&gt;&amp;quot;Lost in the Middle: How Language Models Use Long Contexts&amp;quot;&lt;/a&gt;. They tested models on multi-document question answering and key-value retrieval, placing the relevant information at different positions within the input. They found that the performance was highest when the answer was at the very beginning or very end, and dropped sharply when it was in the middle, even for models explicitly designed for long contexts.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1773547763/Syntackle/Posts/needle-in-haystack_rakteb.png&quot; alt=&quot;MRCR v2 benchmark with 8 needles&quot; height=&quot;854&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;The chart above shows long context retrieval performance across models using the MRCR v2 benchmark with 8 needles (kind of finding needles in a haystack), which is a more demanding multi-needle retrieval test.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Even the best model (Opus 4.6) drops from &lt;strong&gt;~92%&lt;/strong&gt; mean match ratio at 256K to &lt;strong&gt;~78%&lt;/strong&gt; at 1M tokens.&lt;/li&gt;
&lt;li&gt;GPT-5.4 falls from &lt;strong&gt;~80%&lt;/strong&gt; at 128K to &lt;strong&gt;~37%&lt;/strong&gt; at 1M (massive degradation).&lt;/li&gt;
&lt;li&gt;Gemini 3.1 Pro goes from &lt;strong&gt;~59%&lt;/strong&gt; at 256K down to &lt;strong&gt;~26%&lt;/strong&gt; at 1M.&lt;/li&gt;
&lt;li&gt;Sonnet 4.5 barely crosses &lt;strong&gt;~19%&lt;/strong&gt; at 1M.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But why? It&#39;s fundamental to how AI models work and how they are designed.&lt;/p&gt;
&lt;p&gt;The architecture behind every major LLM uses something called self-attention (&lt;a href=&quot;https://arxiv.org/abs/1706.03762&quot;&gt;Vaswani et al., &amp;quot;Attention Is All You Need,&amp;quot; 2017&lt;/a&gt;). Think of it this way, when the model is generating the next word, it looks back at the entire input and asks &amp;quot;which parts of this input matter the most for what I&#39;m about to generate?&amp;quot; It assigns a relevance score to every token in the input and uses those scores to decide what to focus on.&lt;/p&gt;
&lt;p&gt;The catch is that these scores have to add up to 100%. With a short input (for example, 4K tokens), it&#39;s easy to give meaningful attention to the important parts. But with 1M tokens, that same 100% gets spread across a million candidates. The important stuff (if it&#39;s in the middle) now has to compete with a massive amount of surrounding text for the model&#39;s focus, and it often loses.&lt;/p&gt;
&lt;p&gt;It&#39;s like being in a quiet room vs. a stadium. In the quiet room, I can hear someone whisper from across the table. In the stadium, that same whisper gets drowned out by the crowd noise, even though the person is saying something important.&lt;/p&gt;
&lt;blockquote class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;The more you use the context window, the worse outcomes you&#39;ll get. This leads to an academic concept called the &amp;quot;dumb zone&amp;quot;. Around the 40% line is where you&#39;re going to start to see some diminishing returns depending on your task.&lt;/em&gt; - &lt;a href=&quot;https://youtu.be/rmvDxxNubIg?t=355&quot;&gt;Dex Horthy, HumanLayer&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;rmvDxxNubIg&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also, AI models need to know the &lt;em&gt;order&lt;/em&gt; of tokens, i.e., which word comes first, which comes last. This is done through positional encodings, which are like invisible tags that say &amp;quot;this token is at position 1,&amp;quot; &amp;quot;this token is at position 500,000,&amp;quot; and so on. Popular methods like RoPE (Rotary Position Embedding, &lt;a href=&quot;https://arxiv.org/abs/2104.09864&quot;&gt;Su et al., 2021&lt;/a&gt;) encode how far apart two tokens are. This creates a &lt;em&gt;recency bias&lt;/em&gt; and the model naturally pays more attention to tokens that are closer to the end of the input (near where it&#39;s generating) and less attention to tokens that are far away.&lt;/p&gt;
&lt;p&gt;Peysakhovich and Lerer showed this directly in &lt;a href=&quot;https://arxiv.org/abs/2310.01427&quot;&gt;&amp;quot;Attention Sorting Combats Recency Bias In Long Context Language Models&amp;quot;&lt;/a&gt; (2023). Even when a relevant document is placed early in the context, the model pays &lt;em&gt;less&lt;/em&gt; attention to it, not because it doesn&#39;t recognize it as relevant, but because its position makes it inherently less &amp;quot;visible&amp;quot; to the attention mechanism. The model has a built-in preference for recent text, learned during training.&lt;/p&gt;
&lt;p&gt;All of these factors affect how AI models respond when given a long context window.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Larger context windows are a genuine advancement. Being able to feed an entire codebase or a bunch of novels into a single prompt is incredibly useful. But a model accepting 1M tokens is not the same as a model &lt;em&gt;using&lt;/em&gt; 1M tokens well.&lt;/p&gt;
&lt;p&gt;Don&#39;t blindly dump everything into the context window just because you can. For tasks that require finding specific details in large documents or documents which change frequently, a well-designed RAG pipeline will often outperform raw long context.&lt;/p&gt;
&lt;p&gt;Context windows will keep getting better as architectures improve, but for now, understanding the trade-offs is what matters.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/long-context-window-ai-model-catch/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Google Gemini OAuth Plugin for Opencode: Use Your Google AI Subscription Instead of API Pricing</title>
    <link href="https://syntackle.com/blog/google-gemini-ai-subscription-with-opencode/"/>
    <published>2026-01-25T17:43:41Z</published>
    <updated>2026-01-25T17:43:41Z</updated>
    <id>https://syntackle.com/blog/google-gemini-ai-subscription-with-opencode/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;&lt;a href=&quot;https://opencode.ai/&quot;&gt;Opencode&lt;/a&gt; is an open source AI coding agent similar to &lt;a href=&quot;https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/&quot;&gt;Claude Code&lt;/a&gt;, Gemini CLI, and Codex. It&#39;s an interactive terminal user interface (TUI) which connects with most of the AI model (LLM) &lt;a href=&quot;https://opencode.ai/docs/providers/&quot;&gt;providers&lt;/a&gt; out there, OpenRouter, Google, Anthropic, &lt;a href=&quot;https://syntackle.com/blog/openai-assistants-to-responses-api/&quot;&gt;OpenAI&lt;/a&gt;, Amazon Bedrock, Groq, Ollama, you name it.&lt;/p&gt;
&lt;p&gt;Out of the box, Opencode allows you to connect Google as a provider via an &lt;a href=&quot;https://syntackle.com/blog/github-copilot-with-custom-api-key/&quot;&gt;API key&lt;/a&gt;. But, what if you don&#39;t have a Google Cloud API key? What if you&#39;ve purchased a Google AI Pro/Ultra subscription, or received a free Google AI subscription (students and users in India often qualify for these offers), and want to use it with Opencode?&lt;/p&gt;
&lt;p&gt;To use a Google AI subscription, you need to sign in with your Google account in Opencode. The problem is, Opencode doesn&#39;t support this out of the box. I came across a plugin from a &lt;a href=&quot;https://github.com/anomalyco/opencode/issues/447#issuecomment-3476670907&quot;&gt;GitHub issue&lt;/a&gt; in the Opencode repository which solves this exact problem.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jenslys/opencode-gemini-auth&quot;&gt;&lt;code&gt;opencode-gemini-auth&lt;/code&gt;&lt;/a&gt; by Jens Lystad allows you to sign in using your Google account via OAuth and use any &lt;a href=&quot;https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/&quot;&gt;Gemini models&lt;/a&gt; accessible via your subscription with Opencode.&lt;/p&gt;
&lt;p&gt;In this tutorial, I&#39;ll walk you through setting up the &lt;code&gt;opencode-gemini-auth&lt;/code&gt; plugin with Opencode.&lt;/p&gt;
&lt;h2 id=&quot;pre-requisites&quot; tabindex=&quot;-1&quot;&gt;Pre-requisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Google account with a Google AI subscription (Pro, Ultra, or the free tier)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://opencode.ai/&quot;&gt;Opencode&lt;/a&gt; CLI installed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;installing-opencode&quot; tabindex=&quot;-1&quot;&gt;Installing Opencode&lt;/h2&gt;
&lt;p&gt;First, install Opencode if you haven&#39;t already using the simple shell script below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -fsSL&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; https://opencode.ai/install&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;locating-the-config-file&quot; tabindex=&quot;-1&quot;&gt;Locating the Config File&lt;/h2&gt;
&lt;p&gt;Opencode uses a JSON config file for configuration. I recommend using a global config for configuring providers, but you&#39;re free to use a local (project-scoped) config file (&lt;code&gt;opencode.json&lt;/code&gt;) instead.&lt;/p&gt;
&lt;p&gt;Find the global config file at these locations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;macOS/Linux:&lt;/strong&gt; &lt;code&gt;~/.config/opencode/opencode.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows:&lt;/strong&gt; Run &lt;a href=&quot;https://github.com/anomalyco/opencode/issues/1235#issuecomment-3109328778&quot;&gt;&lt;code&gt;opencode debug paths&lt;/code&gt;&lt;/a&gt; to check the config file location&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;If the global &lt;code&gt;opencode.json&lt;/code&gt; config file doesn&#39;t exist yet, create it at the respective location for your operating system.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;registering-the-plugin&quot; tabindex=&quot;-1&quot;&gt;Registering the Plugin&lt;/h2&gt;
&lt;p&gt;Add the following to your Opencode config file:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;$schema&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://opencode.ai/config.json&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;plugin&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;opencode-gemini-auth@latest&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s it. Opencode is now ready to use Google OAuth for authentication.&lt;/p&gt;
&lt;h2 id=&quot;connecting-your-google-account&quot; tabindex=&quot;-1&quot;&gt;Connecting Your Google Account&lt;/h2&gt;
&lt;p&gt;Once you&#39;ve updated the config file with the plugin, run this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;opencode&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; auth&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Choose &lt;strong&gt;Google&lt;/strong&gt; from the list of providers. You&#39;ll see an &lt;strong&gt;OAuth with Google&lt;/strong&gt; option. Selecting it will open a browser window and redirect you to the Google OAuth flow. After you sign in and grant access, Opencode can access any Gemini models associated with your subscription.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;If the browser doesn&#39;t open automatically (common in headless environments or when the port is in use), you can manually paste the callback URL or authorization code when prompted.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;troubleshooting&quot; tabindex=&quot;-1&quot;&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;To view detailed logs for debugging, run Opencode with the debug flag:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;OPENCODE_GEMINI_DEBUG&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; opencode&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will generate &lt;code&gt;gemini-debug-&amp;lt;timestamp&amp;gt;.log&lt;/code&gt; files in your working directory.&lt;/p&gt;
&lt;h2 id=&quot;updating-the-plugin&quot; tabindex=&quot;-1&quot;&gt;Updating the Plugin&lt;/h2&gt;
&lt;p&gt;Opencode doesn&#39;t automatically update plugins. To update to the latest version, clear the cached plugin and restart Opencode:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;rm&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -rf&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ~/.cache/opencode/node_modules/opencode-gemini-auth&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;opencode&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;wrapping-up&quot; tabindex=&quot;-1&quot;&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;opencode-gemini-auth&lt;/code&gt; plugin is for Opencode users who have a Google AI subscription but don&#39;t want to deal with API billing. It&#39;s a straightforward way to leverage your existing Gemini quota directly within Opencode&#39;s powerful &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/&quot;&gt;terminal&lt;/a&gt; user interface.&lt;/p&gt;
&lt;p&gt;Note that your usage is subject to the quotas and rate limits of your Google AI subscription tier.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/google-gemini-ai-subscription-with-opencode/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to Use Free Antigravity AI Models in Claude Code</title>
    <link href="https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/"/>
    <published>2026-01-02T14:47:41Z</published>
    <updated>2026-01-10T07:31:27Z</updated>
    <id>https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;AI development tools are evolving fast, but sometimes access to the most powerful models is gated behind expensive APIs or restricted platforms. That’s exactly what &lt;strong&gt;antigravity-claude-proxy&lt;/strong&gt;, an open-source project by &lt;a href=&quot;https://github.com/badrisnarayanan&quot;&gt;Badri Narayanan S&lt;/a&gt;, enables. It masterfully links Google’s Antigravity with Anthropic’s Claude Code, letting you run Claude models powered by your Antigravity tokens in Claude Code.&lt;/p&gt;
&lt;p&gt;These models are technically free to use as a part of &lt;a href=&quot;https://developers.googleblog.com/build-with-google-antigravity-our-new-agentic-development-platform/#:~:text=Google%20Antigravity%20is%20available%20today%20in%20public%20preview%2C%20at%20no%20cost%20for%20individuals&quot;&gt;Antigravity public preview&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;why-claude-code-instead-of-using-antigravity-or-other-ai-powered-ides-directly%3F&quot; tabindex=&quot;-1&quot;&gt;Why Claude Code Instead of Using Antigravity or Other AI-powered IDEs Directly?&lt;/h2&gt;
&lt;p&gt;With so many AI tools available, I wonder, why use Claude Code at all? It all comes down to &lt;strong&gt;workflow depth over raw model access&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Claude Code isn’t just an AI chat or autocomplete tool. It’s a coding agent designed to understand entire repositories, reason across multiple files, and execute multi-step development tasks. It fits naturally into real developer workflows such as version control (Git), CLI, scripts, instead of being locked to a specific editor.&lt;/p&gt;
&lt;p&gt;Most AI-based IDEs and copilots focus on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inline suggestions&lt;/li&gt;
&lt;li&gt;Editor-specific integrations&lt;/li&gt;
&lt;li&gt;Limited project context&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Claude Code, on the other hand:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works independently of your editor&lt;/li&gt;
&lt;li&gt;Understands full codebases&lt;/li&gt;
&lt;li&gt;Acts more like a pair-programmer than a helper (has Agency)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-is-antigravity-claude-proxy%3F&quot; tabindex=&quot;-1&quot;&gt;What is antigravity-claude-proxy?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;antigravity-claude-proxy&lt;/code&gt; is a lightweight proxy server that exposes AI models provided by Google Antigravity’s &lt;a href=&quot;https://cloud.google.com/code?hl=en&quot;&gt;Cloud Code&lt;/a&gt; behind an Anthropic compatible API.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;You can use Antigravity&#39;s Claude and Gemini models (including their “thinking” modes) with tools like Claude Code CLI without paying for a dedicated Claude Code plan.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;how-it-works&quot; tabindex=&quot;-1&quot;&gt;How It Works&lt;/h3&gt;
&lt;p&gt;Here’s the architecture in 3 steps:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1767360953/Syntackle/Posts/Gemini_Generated_Image_d2mlnwd2mlnwd2ml_zddk7m.png&quot; alt=&quot;internal working of antigravity claude code proxy&quot; height=&quot;828&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Behind the scenes, the proxy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Receives Claude Code requests (Anthropic messaging API).&lt;/li&gt;
&lt;li&gt;Transforms them to Google Generative AI API format.&lt;/li&gt;
&lt;li&gt;Sends them through Antigravity’s Cloud Code with OAuth tokens.&lt;/li&gt;
&lt;li&gt;Converts responses back to Anthropic format with stream support.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So you get end-to-end Claude or Gemini results without dealing with API discrepancies yourself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google One Plan&lt;/strong&gt; subscribers can get benefit from more generous rate limits for the Claude models. Even the free version works. Refer to &lt;a href=&quot;https://antigravity.google/pricing&quot;&gt;Antigravity&#39;s Pricing&lt;/a&gt; for more details. Also, students who have claimed a free Google One subscription, as well as Jio users in India who are now provided with free Google AI Pro subscription, can use antigravity at no cost.&lt;/p&gt;
&lt;h2 id=&quot;installation-and-setup&quot; tabindex=&quot;-1&quot;&gt;Installation and Setup&lt;/h2&gt;
&lt;p&gt;That being said, let me walk you through the installation and setup of &lt;a href=&quot;https://github.com/badri-s2001/antigravity-claude-proxy&quot;&gt;&lt;code&gt;antigravity-claude-proxy&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;prerequisites&quot; tabindex=&quot;-1&quot;&gt;Prerequisites&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18 or later&lt;/li&gt;
&lt;li&gt;HomeBrew for macOS/Linux&lt;/li&gt;
&lt;li&gt;Antigravity installed (for single-account mode) OR Google account(s) for multi-account mode&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;antigravity-claude-proxy&quot; tabindex=&quot;-1&quot;&gt;antigravity-claude-proxy&lt;/h3&gt;
&lt;p&gt;1] Open the terminal of your choice and run:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -g&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; antigravity-claude-proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2] Once the command is executed, ensure you are logged into your Google account within antigravity IDE.&lt;/p&gt;
&lt;p&gt;Alternatively, you can load balance by adding one or more Google accounts using OAuth. For that run this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; accounts&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; add&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This opens a browser tab for Google OAuth. Sign in and authorize access. Repeat for multiple accounts.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# List all accounts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; accounts&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# Verify accounts are working&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; accounts&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; verify&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# Interactive account management&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; accounts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This method benefits users without a Google One subscription by allowing them to switch between different accounts once they reach their daily quota.&lt;/p&gt;
&lt;p&gt;3] The next step after installing and logging into Google account is to start the proxy using the below command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;Remember to run &lt;code&gt;antigravity-claude-proxy start&lt;/code&gt; (starts the proxy server) before using Claude Code.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The server runs on port 8080 (&lt;code&gt;http://localhost:8080&lt;/code&gt;) by default.&lt;/p&gt;
&lt;p&gt;To check whether the server is working or not, run the below command in the terminal or hit the URL directly in the browser.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; http://localhost:8080/health&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, to check your account status or daily quota run this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;http://localhost:8080/account-limits?format=table&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;claude-code&quot; tabindex=&quot;-1&quot;&gt;Claude Code&lt;/h3&gt;
&lt;p&gt;After setting up &lt;code&gt;antigravity-claude-proxy&lt;/code&gt;, now it’s time to install Claude Code.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;If you’re already logged into Claude Code with another account, you need to clear that existing Claude Code authentication so the proxy setup works correctly. Run &lt;code&gt;claude&lt;/code&gt; and type &lt;code&gt;/logout&lt;/code&gt;. After logging out, go through the second step mentioned below.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;1] Install Claude Code, and run the following command in your terminal:&lt;/p&gt;
&lt;p&gt;For macOS/Linux (using &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#package-manager-homebrew&quot;&gt;Homebrew&lt;/a&gt;):&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;brew&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --cask&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; claude-code&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Windows:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;irm https:&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;claude.ai&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;install.ps1 | iex&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2] Check if you have a &lt;code&gt;settings.json&lt;/code&gt; file for Claude Code at the locations mentioned below. If you do, just edit the &lt;code&gt;settings.json&lt;/code&gt;, and if not, create one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;macOS/Linux:&lt;/strong&gt; &lt;code&gt;~/.claude/settings.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows:&lt;/strong&gt; &lt;code&gt;%USERPROFILE%&#92;.claude&#92;settings.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add this configuration to &lt;code&gt;settings.json&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;env&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_AUTH_TOKEN&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_BASE_URL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;http://localhost:8080&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_MODEL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;claude-opus-4-5-thinking&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;claude-opus-4-5-thinking&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;claude-sonnet-4-5-thinking&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;claude-sonnet-4-5&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;CLAUDE_CODE_SUBAGENT_MODEL&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;claude-sonnet-4-5-thinking&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3] After creating/editing the &lt;code&gt;settings.json&lt;/code&gt; file, next step is to load environment variables.&lt;/p&gt;
&lt;p&gt;Add the proxy settings to your shell profile:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For macOS / Linux:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;export ANTHROPIC_BASE_URL=&quot;http://localhost:8080&quot;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;~/.zshrc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;export ANTHROPIC_API_KEY=&quot;test&quot;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;~/.zshrc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ~/.zshrc&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # replace with `~/.bashrc` if you are using Bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;For Windows:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PowerShell:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;Add-Content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; $PROFILE &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;`n`$&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;env:ANTHROPIC_BASE_URL = &#39;http://localhost:8080&#39;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;Add-Content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; $PROFILE &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;`$&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;env:ANTHROPIC_API_KEY = &#39;test&#39;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;. $PROFILE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Command Prompt (CMD):&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;setx ANTHROPIC_BASE_URL &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;http://localhost:8080&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;setx ANTHROPIC_API_KEY &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Restart the terminal for changes to take effect.&lt;/p&gt;
&lt;p&gt;4] Before running Claude Code, make sure you add the following in the &lt;code&gt;claude.json&lt;/code&gt; file (&lt;strong&gt;macOS/Linux:&lt;/strong&gt; &lt;code&gt;~/.claude.json&lt;/code&gt;, &lt;strong&gt;Windows:&lt;/strong&gt; &lt;code&gt;%USERPROFILE%&#92;.claude.json&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;hasCompletedOnboarding&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, start the proxy server and run claude code:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;antigravity-claude-proxy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; start&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # Make sure the proxy is running first&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;claude&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # In another terminal, run Claude Code&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To manage models in Claude Code just type &lt;code&gt;/model&lt;/code&gt; and you can switch between different Claude models.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;For developers who love experimenting, building side projects, or exploring AI assisted coding without committing to expensive subscriptions, &lt;a href=&quot;https://github.com/badri-s2001/antigravity-claude-proxy&quot;&gt;&lt;code&gt;antigravity-claude-proxy&lt;/code&gt;&lt;/a&gt; is a game changer. It demonstrates how thoughtful engineering and open-source collaboration can unlock hidden potential in existing platforms. Projects like &lt;code&gt;antigravity-claude-proxy&lt;/code&gt; are shaping a more open and accessible future for AI development.&lt;/p&gt;
&lt;p&gt;That said, it’s important to use this tool responsibly and understand the terms of service, avoid production misuse, and treat it as a development and learning aid rather than a commercial dependency.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>React2Shell Vulnerabilities — What to do?</title>
    <link href="https://syntackle.com/blog/react2shell-vulnerabilities/"/>
    <published>2025-12-14T09:04:04Z</published>
    <updated>2025-12-14T09:04:04Z</updated>
    <id>https://syntackle.com/blog/react2shell-vulnerabilities/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;React2Shell (CVE-2025-55182) is a highly critical vulnerability reported by &lt;a href=&quot;https://github.com/lachlan2k&quot;&gt;Lachlan Davidson&lt;/a&gt; on November 29th, 2025. React2Shell has a CVSS score of 10.0 (most critical on the scale of 0-10), and is a pre-authentication remote code execution (RCE) vulnerability in which the vulnerable RSC (React Server Components) code unsafely deserializes payloads from HTTP requests to Server Function endpoints.&lt;/p&gt;
&lt;p&gt;In simple words, attackers can craft a special malicious HTTP request to a server function and can execute malicious code directly on the server resources.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;Even if you are &lt;em&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/em&gt; actively using React Server Components, but are bundling third-party packages which support React Server Components in your application, your application is &lt;em&gt;&lt;strong&gt;still&lt;/strong&gt;&lt;/em&gt; vulnerable to React2Shell vulnerabilities.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;And, there are a bunch of other vulnerabilities which came into light after the initial discovery of the main React2Shell (CVE-2025-55182) vulnerability. Here&#39;s a list of all currently discovered React2Shell linked vulnerabilities.&lt;/p&gt;
&lt;h2 id=&quot;currently-known-react2shell-vulnerabilities&quot; tabindex=&quot;-1&quot;&gt;Currently Known React2Shell Vulnerabilities&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2025-55182&quot;&gt;CVE-2025-55182&lt;/a&gt; - The first RCE vulnerability discovered, dubbed as React2Shell.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CVSS Score: 10.0 (Critical)&lt;/li&gt;
&lt;li&gt;Published on: 3rd December, 2025&lt;/li&gt;
&lt;li&gt;Description - A pre-authentication remote code execution vulnerability exists in React Server Components versions 19.0.0, 19.1.0, 19.1.1, and 19.2.0 including the following packages: react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack. The vulnerable code unsafely deserializes payloads from HTTP requests to Server Function endpoints.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2025-55183&quot;&gt;CVE-2025-55183&lt;/a&gt; - Unsafely returns the source code of the Server Function.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CVSS Score: 5.3 (Medium)&lt;/li&gt;
&lt;li&gt;Published on: 11th December, 2025&lt;/li&gt;
&lt;li&gt;Description - An information leak vulnerability exists in specific configurations of React Server Components versions 19.0.0, 19.0.1 19.1.0, 19.1.1, 19.1.2, 19.2.0 and 19.2.1, including the following packages: react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack. A specifically crafted HTTP request sent to a vulnerable Server Function may unsafely return the source code of any Server Function. Exploitation requires the existence of a Server Function which explicitly or implicitly exposes a stringified argument.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2025-55184&quot;&gt;CVE-2025-55184&lt;/a&gt; - Causes infinite loops while deserializing unsafe payloads and hangs the server process.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CVSS Score: 7.5 (High)&lt;/li&gt;
&lt;li&gt;Published on: 11th December, 2025&lt;/li&gt;
&lt;li&gt;Description: A pre-authentication denial of service vulnerability exists in React Server Components versions 19.0.0, 19.0.1 19.1.0, 19.1.1, 19.1.2, 19.2.0 and 19.2.1, including the following packages: react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack. The vulnerable code unsafely deserializes payloads from HTTP requests to Server Function endpoints, which can cause an infinite loop that hangs the server process and may prevent future HTTP requests from being served.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2025-67779&quot;&gt;CVE-2025-67779&lt;/a&gt; - Emerged as a failure to fix the previous vulnerability (CVE-2025-55184) in a specific use case.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CVSS Score: 7.5 (High)&lt;/li&gt;
&lt;li&gt;Published on: 11th December, 2025&lt;/li&gt;
&lt;li&gt;Description: It was found that the fix addressing CVE-2025-55184 in React Server Components was incomplete and does not prevent a denial of service attack in a specific case. React Server Components versions 19.0.2, 19.1.3 and 19.2.2 are affected, allowing unsafe deserialization of payloads from HTTP requests to Server Function endpoints. This can cause an infinite loop that hangs the server process and may prevent future HTTP requests from being served.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Original POC by Lachlan Davidson - &lt;a href=&quot;https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc&quot;&gt;React2Shell-CVE-2025-55182-original-poc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;affected-packages&quot; tabindex=&quot;-1&quot;&gt;Affected Packages&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Next.js - All versions from 15.0.0 through 16.0.6, as well as Next.js 14 canaries after 14.3.0-canary.76.&lt;/li&gt;
&lt;li&gt;react-server-dom-webpack - 19.0.0, 19.0.1, 19.0.2, 19.1.0, 19.1.1, 19.1.2, 19.1.3, 19.2.0, 19.2.1, 19.2.2&lt;/li&gt;
&lt;li&gt;react-server-dom-parcel - 19.0.0, 19.0.1, 19.0.2, 19.1.0, 19.1.1, 19.1.2, 19.1.3, 19.2.0, 19.2.1, 19.2.2&lt;/li&gt;
&lt;li&gt;react-server-dom-turbopack - 19.0.0, 19.0.1, 19.0.2, 19.1.0, 19.1.1, 19.1.2, 19.1.3, 19.2.0, 19.2.1, 19.2.2&lt;/li&gt;
&lt;li&gt;@vitejs/plugin-rsc - upgrade to latest&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are using React Router&#39;s unstable RSC APIs, Redwood SDK, or Waku, then you should definitely check and upgrade the above packages to their latest patched versions.&lt;/p&gt;
&lt;p&gt;If you are still unsure if your application contains these vulnerable packages or not, you can always use a vulnerability scanner or open source npm packages which detect those packages in your application. Two of such open source packages are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/burakeregar/react-rsc-vuln-scanner&quot;&gt;React RSC Vulnerability Scanner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vercel-labs/fix-react2shell-next&quot;&gt;fix-react2shell-next&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The only way to get rid off these React2Shell vulnerabilities is to upgrade the vulnerable packages in your application to their latest patched versions. This is still a developing story where hope not, but new vulnerabilities might emerge, so keep an eye on this space for a while.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/react2shell-vulnerabilities/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Google&#39;s Gemini 3 Pro, Nano Banana Pro, and Antigravity</title>
    <link href="https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/"/>
    <published>2025-11-23T10:20:51Z</published>
    <updated>2025-11-24T07:00:06Z</updated>
    <id>https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Google casually dropped three products — upgraded versions of two of their most popular products, Gemini and Nano Banana, and Antigravity — an IDE with agentic capabilities (a VSCode fork using Windsurf tech since Windsurf founders signed a $2.4 billion deal with Google and joined Google Deepmind along with some other Windsurf employees).&lt;/p&gt;
&lt;h2 id=&quot;gemini-3-pro&quot; tabindex=&quot;-1&quot;&gt;Gemini 3 Pro&lt;/h2&gt;
&lt;p&gt;According to benchmarks and &lt;a href=&quot;https://blog.google/products/gemini/gemini-3/#gemini-3&quot;&gt;Google&lt;/a&gt;, Gemini 3 Pro is the new state of the art model outperforming other AI models. This brings us back to the Gemini era in the cycle of SOTA (State-Of-The-Art) models. Not sure which model will outperform Gemini 3 Pro in the coming months (or maybe weeks), but for now Gemini 3 Pro seems to be the king.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1763797945/Syntackle/Posts/Gemini_Generated_Image_dru2lmdru2lmdru2_j1ypbd.png&quot; alt=&quot;SOTA (State of the art) Models Hype Cycle&quot; height=&quot;847&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;I built a full-stack app in ~3 days using Gemini 2.5 Pro in Firebase Studio.&lt;/p&gt;
&lt;section class=&quot;unfurl&quot;&gt;
    &lt;div class=&quot;unfurl__left&quot;&gt;
      &lt;small class=&quot;unfurl__meta&quot;&gt;
        &lt;img class=&quot;unfurl__logo&quot; src=&quot;https://syntackle.com/assets/favicon-96x96.png&quot; width=&quot;96&quot; height=&quot;96&quot; alt=&quot;Logo&quot; /&gt;
        &lt;span class=&quot;unfurl__publisher&quot;&gt;Syntackle&lt;/span&gt;
      &lt;/small&gt;
      &lt;h4 class=&quot;unfurl__heading&quot;&gt;
    &lt;a class=&quot;unfurl__link&quot; href=&quot;https://syntackle.com/blog/the-problem-with-ai-generated-code/&quot;&gt;The Problem With AI Generated Code And How To Deal With It&lt;/a&gt;
  &lt;/h4&gt;
      &lt;p class=&quot;unfurl__description&quot;&gt;AI models and tools are becoming more and more capable day by day, especially at generating code. In this post, I will walk you through my experience of creating a full-stack application using some of these AI coding assistants/agents and what are the implications of AI generated code.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class=&quot;unfurl__image&quot;&gt;
  &lt;img src=&quot;https://syntackle-og-screenshot.vercel.app/https%3A%2F%2Fautomated-og-image-syntackle.vercel.app%2F%3Ftitle%3DThe%20Problem%20With%20AI%20Generated%20Code%20And%20How%20To%20Deal%20With%20It%26author%3DMurtuzaali%20Surti/opengraph&quot; width=&quot;1200&quot; height=&quot;630&quot; alt=&quot;Page preview image&quot; /&gt;
&lt;/div&gt;
  &lt;/section&gt;
&lt;/div&gt;
&lt;p&gt;From what I saw and experienced, Gemini 3 Pro is really good at one-shot prompts and does a great job even if you don&#39;t provide it a lot of context. At the very least, it makes things functional and usable.&lt;/p&gt;
&lt;p&gt;People are sharing what they built using Gemini 3 Pro on X (Twitter). Here&#39;s what they are building:&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;I asked Gemini 3 Pro to create a 3D LEGO editor.
In one shot it nailed the UI, complex spatial logic, and all the functionality. We’re entering a new era.&lt;/p&gt;
&lt;p&gt;— Pietro Schirano on X&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-media-max-width=&quot;560&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I asked Gemini 3 Pro to create a 3D LEGO editor.&lt;br /&gt;In one shot it nailed the UI, complex spatial logic, and all the functionality. &lt;br /&gt;&lt;br /&gt;We’re entering a new era. &lt;a href=&quot;https://t.co/Y7OndCB8CK&quot;&gt;pic.twitter.com/Y7OndCB8CK&lt;/a&gt;&lt;/p&gt;&amp;mdash; Pietro Schirano (@skirano) &lt;a href=&quot;https://twitter.com/skirano/status/1990813093727789486?ref_src=twsrc%5Etfw&quot;&gt;November 18, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;I just vibe-coded a football game with Gemini 3. Insane times to be alive.&lt;/p&gt;
&lt;p&gt;— Jim Raptis on X&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-media-max-width=&quot;560&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I just vibe-coded a football game with Gemini 3. &lt;br /&gt;&lt;br /&gt;Insane times to be alive. &lt;a href=&quot;https://t.co/oLlfMIdbrR&quot;&gt;pic.twitter.com/oLlfMIdbrR&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jim Raptis (@d__raptis) &lt;a href=&quot;https://twitter.com/d__raptis/status/1991195534497849362?ref_src=twsrc%5Etfw&quot;&gt;November 19, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;gemini 3: build a jarvis HUD interface for tony stark
a quick experiment with mediapipe computer vision, threejs, and javascript&lt;/p&gt;
&lt;p&gt;— AA on X&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-media-max-width=&quot;560&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;gemini 3: build a jarvis HUD interface for tony stark&lt;br /&gt;&lt;br /&gt;a quick experiment with mediapipe computer vision, threejs, and javascript &lt;a href=&quot;https://t.co/QBlFYLgLJN&quot;&gt;pic.twitter.com/QBlFYLgLJN&lt;/a&gt;&lt;/p&gt;&amp;mdash; AA (@measure_plan) &lt;a href=&quot;https://twitter.com/measure_plan/status/1991166530952810514?ref_src=twsrc%5Etfw&quot;&gt;November 19, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Just built a manga storybook generator using Gemini 3.
Type your concept → get a complete manga-style storybook instantly&lt;/p&gt;
&lt;p&gt;— COLLINS on X&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-media-max-width=&quot;560&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Just built a manga storybook generator using Gemini 3.&lt;br /&gt;Type your concept → get a complete manga-style storybook instantly &lt;a href=&quot;https://t.co/BCGwTv0bI5&quot;&gt;pic.twitter.com/BCGwTv0bI5&lt;/a&gt;&lt;/p&gt;&amp;mdash; COLLINS⚡ (@Cubzy05) &lt;a href=&quot;https://twitter.com/Cubzy05/status/1991135883693637967?ref_src=twsrc%5Etfw&quot;&gt;November 19, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;h2 id=&quot;nano-banana-pro&quot; tabindex=&quot;-1&quot;&gt;Nano Banana Pro&lt;/h2&gt;
&lt;p&gt;&amp;quot;Nano Banana Pro&amp;quot; a.k.a &amp;quot;Gemini 3 Pro Image&amp;quot; is an AI model built on Gemini 3 Pro, and that allows Nano Banana Pro to utilize Gemini 3 Pro&#39;s reasoning and thinking capabilities.&lt;/p&gt;
&lt;p&gt;To use Nano Banana Pro, go to &lt;a href=&quot;https://gemini.google.com/&quot;&gt;gemini.google.com&lt;/a&gt; (or the Gemini App on your smartphone), click on the tools icon besides the plus(+) icon, and select &amp;quot;🍌 Create Images&amp;quot; option. Also, make sure you are on the &amp;quot;Thinking with 3 Pro&amp;quot; option in the model selection dropdown.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1763880576/Syntackle/Posts/Screenshot_2025-11-23_at_12.16.04_PM_qsfwel.png&quot; alt=&quot;Using Nano Banana Pro in Gemini App&quot; height=&quot;826&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;To me, the most amazing thing about Nano Banana Pro is its ability to generate accurate text. And the reason it is able to do so is Gemini 3 Pro, the AI model its built up on. There are &lt;a href=&quot;https://x.com/GeminiApp/status/1991570302720163988?s=20&quot;&gt;countless examples&lt;/a&gt; on the internet depicting the amazing ability of Nano Banana Pro to generate infographics, diagrams, banners, menus, etc. all with nearly accurate text.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Nano Banana Pro is wild.&lt;/p&gt;
&lt;p&gt;Here’s my favorite use case so far: take papers or really long articles and turn them into a detailed whiteboard photo.&lt;/p&gt;
&lt;p&gt;It’s basically the greatest compression algorithm in human history.&lt;/p&gt;
&lt;p&gt;— Pietro Schirano on X&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-media-max-width=&quot;560&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Nano Banana Pro is wild.&lt;br /&gt;&lt;br /&gt;Here’s my favorite use case so far: take papers or really long articles and turn them into a detailed whiteboard photo.&lt;br /&gt;&lt;br /&gt;It’s basically the greatest compression algorithm in human history. &lt;a href=&quot;https://t.co/9TEa5xnZzW&quot;&gt;pic.twitter.com/9TEa5xnZzW&lt;/a&gt;&lt;/p&gt;&amp;mdash; Pietro Schirano (@skirano) &lt;a href=&quot;https://twitter.com/skirano/status/1991527921316773931?ref_src=twsrc%5Etfw&quot;&gt;November 20, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Google’s Nano Banana Pro is by far the best image generation AI out there.&lt;/p&gt;
&lt;p&gt;I gave it a picture of a question and it solved it correctly in my actual handwriting.&lt;/p&gt;
&lt;p&gt;Students are going to love this.&lt;/p&gt;
&lt;p&gt;— sid on X&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://pbs.twimg.com/media/G6S3EBCa8AANqVU?format=jpg&amp;name=4096x4096&quot; alt=&quot;nano banana pro generated a pic solving a math question in users actual handwriting from the original pic. source: https://x.com/immasiddx&quot; height=&quot;826&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;source: &lt;a href=&quot;https://x.com/immasiddx/status/1991918223454003346&quot;&gt;x.com/immasiddx&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;In fact, the first image you saw in this post is generated by Nano Banana Pro.&lt;/p&gt;
&lt;p&gt;I did notice one thing though, it doesn&#39;t generate accurate readable text if the text is in the backdrop/background. I was iterating upon the first image you saw in this post and prompted Nano Banana to generate a slightly modified image with this prompt: &amp;quot;add some texts reflecting on the fragility and hype of these SOTA models and companies, don&#39;t overdo it, search the web for grounding the punch lines&amp;quot;, and it generated some gibberish text in newspapers in the background.&lt;/p&gt;
&lt;p&gt;Also, you can see repetitive text in the heading.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1763885541/Syntackle/Posts/Gemini_Generated_Image_itue1litue1litue_uzzhzg.png&quot; alt=&quot;nano banana pro generated a pic for prompt: add some texts reflecting on the fragility and hype of these SOTA models and companies, don&#39;t overdo it, search the web for grounding the punch lines&quot; height=&quot;847&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Another thing which I noticed is when you prompt Nano Banana Pro to iterate upon its own generated image, it actually degrades the quality of the image and you can clearly see that the image has been iterated upon. See the two images below.&lt;/p&gt;
&lt;img-comparison-slider class=&quot;coloured-slider&quot;&gt;
    &lt;div slot=&quot;first&quot;&gt;
    &lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1763888062/Syntackle/Posts/Gemini_Generated_Image_fftyjsfftyjsffty_psxuzl.png&quot; alt=&quot;nano banana pro generated a pic upon multiple iterations&quot; height=&quot;847&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
    &lt;/div&gt;
    &lt;div slot=&quot;second&quot;&gt;
    &lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1763797945/Syntackle/Posts/Gemini_Generated_Image_dru2lmdru2lmdru2_j1ypbd.png&quot; alt=&quot;nano banana pro generated a pic upon multiple iterations&quot; height=&quot;847&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
    &lt;/div&gt;
&lt;/img-comparison-slider&gt;
&lt;p&gt;The image on the left is a result of multiple iterations on the same image internally, while the image on the right is a new image generated from the same image (downloaded and then attached to the chat) with a prompt shown below.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-plain&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;take this image, and generate a new image out of it, don&#39;t iterate upon the same image, generate a new 4K image out of it&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;antigravity&quot; tabindex=&quot;-1&quot;&gt;Antigravity&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://antigravity.google/&quot;&gt;Antigravity&lt;/a&gt; is a VSCode fork using Windsurf technology developed by Google. It&#39;s an IDE with agentic capabilities, and browser access and preview support.&lt;/p&gt;
&lt;p&gt;You can use Gemini 3 Pro for free for now in Antigravity, but it&#39;s highly rate-limited. For me, the usage quota (for Gemini 3 Pro High) gets exhausted pretty quickly within a single agentic session. It&#39;s also quite buggy at this point, but we can ignore that as it will definitely improve in the near future.&lt;/p&gt;
&lt;p&gt;Antigravity is a direct competitor to Cursor, and it will be interesting to see which of the two gets the edge over the other.&lt;/p&gt;
&lt;p&gt;Exciting times.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Reflections on the AWS &amp; Azure Outages</title>
    <link href="https://syntackle.com/blog/reflections-on-the-aws-and-azure-outage/"/>
    <published>2025-10-31T14:55:10Z</published>
    <updated>2025-11-02T10:15:14Z</updated>
    <id>https://syntackle.com/blog/reflections-on-the-aws-and-azure-outage/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;AWS and Azure, two of the largest cloud providers having a market share of ~30% and ~23% respectively (as of 2025), experienced large scale outages recently. These outages affected multiple interdependent services. In this post, I will explore what are the implications of these outages, what can be done about them, and how fragile the web really is.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;aws-outage---october-19%2C-2025&quot; tabindex=&quot;-1&quot;&gt;AWS Outage - October 19, 2025&lt;/h2&gt;
&lt;p&gt;The AWS Outage on October 19, 2025 began with Amazon&#39;s Dynamo DB service — a serverless, managed, NoSQL database service — in the &lt;code&gt;us-east-1&lt;/code&gt; AWS region. As per the official &lt;a href=&quot;https://aws.amazon.com/message/101925/&quot;&gt;incident report&lt;/a&gt;, Dynamo DB&#39;s DNS management system published an &amp;quot;empty DNS record&amp;quot; for one of the endpoints (dynamodb.us-east-1.amazonaws.com), restricting any external/internal service to connect to it. In order to understand, you have to first understand what DNS is.&lt;/p&gt;
&lt;p&gt;DNS stands for &amp;quot;Domain Name Server&amp;quot; and is like a phone book that maps human readable addresses to IP addresses (machine addresses). For example, openai.com maps to 172.64.154.211, an IP address of the server/machine the website is hosted on.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;Run the following command to see it yourself:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;ping&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; openai.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;PING&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; openai.com&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (172.64.154.211): 56 data bytes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;14.347&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;15.783&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;13.898&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;14.241&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;13.575&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;14.347&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; bytes&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 172.64.154.211:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; icmp_seq=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ttl=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;57&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; time=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;15.144&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;---&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; openai.com&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ping&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; statistics&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; packets&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; transmitted,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 7&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; packets&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; received,&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 0.0%&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; packet&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; loss&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;round-trip&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; min/avg/max/stddev&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 13.575/14.476/15.783/0.696&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Press CTRL+C to exit&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So, if there&#39;s no address listed for a particular endpoint, other machines can&#39;t get to it because they don&#39;t know where it lives. Technically, that endpoint in now invisible. A similar thing happened with Meta (Facebook) in the past (October 4, 2021) where they had issues with the BGP protocol, in which Facebook stopped announcing their addresses (locations) which resulted in routers not able to find Facebook&#39;s servers.&lt;/p&gt;
&lt;p&gt;Coming back to the AWS outage, the Dynamo DB DNS resolution issue was just the beginning. It started a domino effect where after the DNS issue was fixed, the EC2 instances which were trying to connect to Dynamo DB via DWFM (Droplet Workflow Manager — an AWS Droplet is a physical server on which EC2 instances run) the whole down time, experienced &amp;quot;congestive collapse&amp;quot;, meaning DWFM was repeatedly trying to connect (the number of broken leases increased — &lt;em&gt;a lease is a logical assignment that maps a specific portion of physical server resources (CPU, RAM, etc.) to an EC2 instance for a certain period.&lt;/em&gt;), but when Dynamo DB was up, DWFM struggled to keep up with resolving the number of broken leases.&lt;/p&gt;
&lt;p&gt;In other words, the system entered a state where it kept on doing its job, but the inputs timed out before they were getting addressed.&lt;/p&gt;
&lt;blockquote class=&quot;&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Clients continue to send work, and the system continues to complete that work. Throughput is great. None of the work is useful, though, because clients aren’t waiting for the results, so goodput is zero. The system is mostly stable in this state, and without an external kick, could continue going along that way indefinitely. Up, but down. Working, but broken. - &lt;a href=&quot;https://brooker.co.za/blog/2021/05/24/metastable.html&quot;&gt;Marc Brooker&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The EC2 instances then impacted the Network Load Balancers (NLB).&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Want to get technical? Deep Dive into the AWS Outage with &lt;a href=&quot;https://thundergolfer.com/blog/aws-us-east-1-outage-oct20&quot;&gt;More Than DNS: The 14 hour AWS us-east-1 outage&lt;/a&gt; - by &lt;a href=&quot;https://thundergolfer.com/&quot;&gt;Jonathon Belotti&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;azure-outage---october-29%2C-2025&quot; tabindex=&quot;-1&quot;&gt;Azure Outage - October 29, 2025&lt;/h2&gt;
&lt;p&gt;In 2 weeks since the AWS outage, Azure, the second big cloud provider faced an outage on October 29, 2025, which Microsoft says was caused due to &lt;strong&gt;&amp;quot;inadvertent tenant configuration change&amp;quot;&lt;/strong&gt;. This change was made to the Azure Front Door service which is basically a CDN (Content Delivery Network). AFD (Azure Front Door) affected multiple services of Microsoft as it&#39;s a CDN, internal/external services depend on it for accessing stored blobs/files.&lt;/p&gt;
&lt;p&gt;Microsoft has not yet published a full report of how it exactly happened, but from &lt;a href=&quot;https://azure.status.microsoft/en-us/status/history/&quot;&gt;little do we know&lt;/a&gt;, there&#39;s an automated validation system which runs after such configuration change is made and it typically blocks such faulty configurations. But, in this case, it didn&#39;t. The automated validation system itself had issue with withholding the configuration change and that&#39;s how it by-passed the checkpoints.&lt;/p&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;These outages remind me how fragile the web really is. We think of these big tech corporations and wonder what&#39;s the worst thing that can happen to them? I mean, they have all of the resources, power, and money, so how can anything go wrong with them?&lt;/p&gt;
&lt;p&gt;The fact is that no matter how big the tech organization is, they all depend on basic technologies which make the web, world wide web. No matter how much they claim they are reliable, the truth is, nothing is reliable enough. All of these complex systems are just abstractions built on top of really basic technologies, and when those basic technologies are affected, disruptions happen.&lt;/p&gt;
&lt;p&gt;It all boils down to a mesh of interconnected systems which talk to each other, the only difference is, we don&#39;t see any of that. We are so glamorized by these complex software abstractions that we fail to see the very basic foundation they were built up on.&lt;/p&gt;
&lt;p&gt;At the end, we are all sitting on top of fibre optics.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1761922269/Syntackle/Posts/aaqzad_eyijgh.jpg&quot; alt=&quot;open source meme&quot; height=&quot;1928&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Zerodha, a brokerage firm, announced their FLOSS fund in 2024 to fund open source projects. Nithin Kamath, CEO of Zerodha, &lt;a href=&quot;https://x.com/Nithin0dha/status/1983790769283723472&quot;&gt;shared a post&lt;/a&gt; on why everyone should support and fund open source projects. He made a really good point that companies which earn billions of dollars relying on many small open source projects (without them their services would be rendered completely useless) are simply not willing to sponsor or fund them. Now, I know I am going a little off tangent with this, but the point is that if one of the underlying services fail, you start to see a domino effect where all of the above abstractions fail with it.&lt;/p&gt;
&lt;p&gt;So, as much as maintaining the complex systems is important, it&#39;s equally important to maintain and fund the small, miniscule-looking technologies which are basically the backbone of software abstractions.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/reflections-on-the-aws-and-azure-outage/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>[React] useEffectEvent: A New Hook For &#39;Events&#39; inside &#39;useEffect&#39;</title>
    <link href="https://syntackle.com/blog/useeffectevent-react/"/>
    <published>2025-10-13T14:16:54Z</published>
    <updated>2025-10-13T14:16:54Z</updated>
    <id>https://syntackle.com/blog/useeffectevent-react/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;With the release of version 19.2, a new hook named &lt;code&gt;useEffectEvent&lt;/code&gt; was introduced in React. As the name suggests, it is for the &amp;quot;events&amp;quot; defined inside &lt;code&gt;useEffect&lt;/code&gt;. But what exactly is an &amp;quot;Event&amp;quot; and how does it affect the &amp;quot;Effect&amp;quot;? That&#39;s what I intend to discuss here in this post.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;useEffectEvent&lt;/code&gt; hook addresses a very particular problem where because of exhaustive-deps rule of useEffect, dependencies which &lt;em&gt;aren&#39;t&lt;/em&gt; supposed to trigger the &lt;em&gt;&lt;strong&gt;&amp;quot;Effect&amp;quot;&lt;/strong&gt;&lt;/em&gt; trigger it. One option is to suppress the rule and only specify the dependencies on which I actually want to trigger the Effect, but what if I actually use &lt;em&gt;non-triggering&lt;/em&gt; dependencies inside the effect in some way or the other and always want their updated values? The values might be stale since I removed those &lt;em&gt;non-triggering&lt;/em&gt; dependencies from the dependency array.&lt;/p&gt;
&lt;h2 id=&quot;%22event%22-vs-%22effect%22&quot; tabindex=&quot;-1&quot;&gt;&amp;quot;Event&amp;quot; vs &amp;quot;Effect&amp;quot;&lt;/h2&gt;
&lt;p&gt;To understand this, the official React blog breaks down the code inside useEffect and puts it into two categories: Event and Effect.&lt;/p&gt;
&lt;p&gt;An &amp;quot;Event&amp;quot; is what happens when the user does something or performs an action in the application. An &amp;quot;Effect&amp;quot; is something which is dependent on the &lt;em&gt;reactive&lt;/em&gt; values in the application. I like to call the values which are &lt;em&gt;controlled&lt;/em&gt; by React, &lt;em&gt;reactive&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This distinction is crucial because it helps to extract Events from the useEffect code. Let me give an example.&lt;/p&gt;
&lt;p&gt;Lets say I have a component which does something once I receive the payment confirmation from the payment gateway. Here, the props are &lt;em&gt;reactive&lt;/em&gt; values, meaning they can change irrespective of the user input.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Payments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;cart&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;customerNote&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  useEffect&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;confirmed&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;      finalizeAndTrackOrder&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cart&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;customerNote&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }, [&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cart&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;customerNote&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;finalizeAndTrackOrder&lt;/code&gt; can be considered as an &#39;Event&#39; because it only happens at a specific time and when the user actually completes the payment. The issue here is the &lt;code&gt;cart&lt;/code&gt; and &lt;code&gt;customerNote&lt;/code&gt; dependencies in the dependency array. I don&#39;t want to track the final order every time the cart or customerNote changes. So, technically cart and customerNote deps should not trigger the &#39;Effect&#39;, but I also want their latest values passed to the &lt;code&gt;finalizeAndTrackOrder&lt;/code&gt; function (if they change).&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;finalizeAndTrackOrder&lt;/code&gt; function can be categorized as an &#39;Event&#39;, whereas the &lt;code&gt;paymentStatus&lt;/code&gt; condition can be categorized as an &#39;Effect&#39; which runs whenever the payment status updates.&lt;/p&gt;
&lt;h2 id=&quot;the-useeffectevent-hook&quot; tabindex=&quot;-1&quot;&gt;The &lt;code&gt;useEffectEvent&lt;/code&gt; Hook&lt;/h2&gt;
&lt;p&gt;Now that I know that the &#39;Event&#39; is the &lt;code&gt;finalizeAndTrackOrder&lt;/code&gt; function, I can take it out of the &lt;code&gt;useEffect&lt;/code&gt; hook and wrap it in the new &lt;code&gt;useEffectEvent&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Payments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;cart&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;customerNote&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; onPaymentConfirmed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useEffectEvent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    finalizeAndTrackOrder&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cart&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;customerNote&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  useEffect&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;confirmed&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;      onPaymentConfirmed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }, [&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;paymentStatus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code inside &lt;code&gt;useEffectEvent&lt;/code&gt; hook will always &lt;em&gt;access&lt;/em&gt; the latest &lt;em&gt;reactive&lt;/em&gt; values. However, there are two limitations on how to use &amp;quot;Effect Events&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&#39;t pass &amp;quot;Effect Events&amp;quot; to other components or hooks.&lt;/li&gt;
&lt;li&gt;They can only be called from inside the &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;useEffectEvent&lt;/code&gt; hook solves a very particular problem, but I am wondering, is the useEffect hook flawed by design? The need to introduce new hooks around it makes it evident to some extent. Or, is it that people don&#39;t know how to use it? That&#39;s a question to ask.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/useeffectevent-react/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Side Effect Import Issue in TypeScript</title>
    <link href="https://syntackle.com/blog/ts-side-effect-import-issue/"/>
    <published>2025-10-12T07:50:00Z</published>
    <updated>2025-10-12T07:50:00Z</updated>
    <id>https://syntackle.com/blog/ts-side-effect-import-issue/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Recently, typescript started giving me an error &lt;code&gt;Cannot find module or type declarations for side-effect import&lt;/code&gt; every time I load a CSS file or a font file in the entry module of a framework such as Astro(Vite)/Nextjs.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1760253018/Syntackle/Posts/Screenshot_2025-10-12_at_12.38.26_PM_htwn1z.png&quot; alt=&quot;Cannot find module or type declarations for side-effect import: Typescript issue&quot; height=&quot;479&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;The interesting part is, I didn&#39;t even change the typescript version of my project. It seemed like it was using some other version of &lt;a href=&quot;https://syntackle.com/blog/typescript-go-port/&quot;&gt;typescript&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then, I looked at the &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;VS Code&lt;/a&gt;&#39;s Status Bar and figured out the project was using typescript v6 rather that v5 which was defined in my project.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1760253561/Syntackle/Posts/Screenshot_2025-10-12_at_12.48.38_PM_haovap.png&quot; alt=&quot;Status bar of VS Code displaying typescript version used&quot; height=&quot;1176&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;But where was it coming from? It was coming from the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next&quot;&gt;&lt;code&gt;JavaScript and TypeScript Nightly&lt;/code&gt;&lt;/a&gt; &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/&quot;&gt;VS Code extension&lt;/a&gt;. It enables the nightly build of typescript to be used inside of VS Code so that you can try experimental features. I don&#39;t know why I had it installed and enabled in the first place because you don&#39;t need this extension for typescript support in VS Code.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1760254250/Syntackle/Posts/Screenshot_2025-10-12_at_1.00.23_PM_eemamm.png&quot; alt=&quot;JavaScript and TypeScript Nightly: VS Code Extension&quot; height=&quot;350&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;I uninstalled the extension and reloaded the VS Code window using &lt;code&gt;CMD/CTRL + Shift + P &amp;gt; Developer: Reload Window&lt;/code&gt; and now &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/&quot;&gt;VS Code&lt;/a&gt; was using the typescript version defined in my project (v5.9.3).&lt;/p&gt;
&lt;p&gt;If you want to keep this extension or have multiple typescript versions added to VS Code, you can select the exact version you want for your project by using &lt;code&gt;CMD/CTRL + Shift + P &amp;gt; Select Typescript Version&lt;/code&gt;. This also works if you have an explicit version of typescript defined in your packages.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1760254898/Syntackle/Posts/Screenshot_2025-10-12_at_1.05.57_PM_dtx0nt.png&quot; alt=&quot;Typescript version selection dialog in VS Code&quot; height=&quot;252&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;If you select the version of typescript installed as a package (in node_modules) from your dependencies, it will add a vscode setting &lt;code&gt;&amp;quot;typescript.tsdk&amp;quot;: &amp;quot;node_modules/typescript/lib&amp;quot;&lt;/code&gt; in the &lt;code&gt;settings.json&lt;/code&gt; file of your project (will create one if none).&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;typescript.tsdk&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;node_modules/typescript/lib&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;Reload window using &lt;code&gt;CMD/CTRL + Shift + P &amp;gt; Developer: Reload Window&lt;/code&gt; after typescript version change.&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/ts-side-effect-import-issue/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Fixing the overscroll &quot;bounce&quot; effect with CSS</title>
    <link href="https://syntackle.com/blog/overscroll-behavior-css/"/>
    <published>2025-10-09T17:16:32Z</published>
    <updated>2025-10-09T17:16:32Z</updated>
    <id>https://syntackle.com/blog/overscroll-behavior-css/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Ever noticed the &amp;quot;bounce&amp;quot; scroll effect after reaching the end of a page showing a white background especially for SPAs (Single Page Application)? That&#39;s the background color of the body (if white or not defined) appearing when the SPA root (mounted) element slides down.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1760029758/ScreenRecording2025-10-09at9.06.54PM-ezgif.com-video-to-gif-converter_zyncfb.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;scroll effect after reaching the end of a page showing a white background&quot; height=&quot;558&quot; width=&quot;800&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;I find it particularly annoying as it breaks the flow, look and feel of the website or application. Now you might say why not just add a &lt;a href=&quot;https://syntackle.com/blog/setting-background-color-of-body-dynamically-in-react-5tVYr3/&quot;&gt;background color to the body/html/root element&lt;/a&gt; and get away with it? You can but what if there&#39;s a header with a slightly different color shade? When you scroll up, you will get that color mismatch which is not pleasant to look at.&lt;/p&gt;
&lt;p&gt;The CSS property &lt;code&gt;overscroll-behavior&lt;/code&gt; defines what the browser will do once it reaches the end of the scroll area both vertically (Y-axes) and horizontally (X-axes). &lt;code&gt;overscroll-behavior&lt;/code&gt; can be broken down into &lt;code&gt;overscroll-behavior-x&lt;/code&gt; and &lt;code&gt;overscroll-behavior-y&lt;/code&gt; properties, allowing developers to control the X and Y scroll separately.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;overscroll-behavior-y&lt;/code&gt; controls the &amp;quot;bounce&amp;quot; effect and &amp;quot;pull-to-refresh&amp;quot; behavior and setting it to &lt;code&gt;none&lt;/code&gt; will disable those behaviors. &lt;code&gt;overscroll-behavior-x&lt;/code&gt; controls the prev/next gesture navigations, so they will be disabled if it is set to &lt;code&gt;none&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A quick fix for the vertical overscroll &amp;quot;bounce&amp;quot; effect for the page is to apply &lt;code&gt;overscroll-behavior-y: none;&lt;/code&gt; to the &lt;code&gt;body&lt;/code&gt; element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    overscroll-behavior-y: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;overscroll-behavior-y&lt;/code&gt; will only apply to vertical scroll and will have no effect on horizontal scrolls, which will preserve prev/next trackpad gesture navigations.&lt;/p&gt;
&lt;p&gt;I recommend applying the &lt;code&gt;overscroll-behavior&lt;/code&gt; property on the body (to apply it for the encompassing page) because some browsers don&#39;t support the property on &lt;code&gt;html&lt;/code&gt; or &lt;code&gt;root&lt;/code&gt; elements.&lt;/p&gt;
&lt;p&gt;Another use case for &lt;code&gt;overscroll-behavior&lt;/code&gt; is &lt;em&gt;&lt;strong&gt;isolating scrolling to the current scroll area&lt;/strong&gt;&lt;/em&gt;, meaning, it should not scroll the parent scroll area once it reaches the end of scroll area of the current target. For example, if you have a scrollable menu or an iframe overlaying on top of the body, and if you don&#39;t want the body to scroll once the user scrolls past the scrollable area of the menu/iframe, you can set &lt;code&gt;overscroll-behavior&lt;/code&gt; to &lt;code&gt;contain&lt;/code&gt; and it will not propagate the scroll outside of the target area.&lt;/p&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Don&#39;t sleep on the &lt;code&gt;overscroll-behavior&lt;/code&gt; CSS property, and use it according to your requirements. If the bounce effect doesn&#39;t get in the way of the user interface and it doesn&#39;t look off, then you have no reason to disable the default scroll behavior. Understanding the trade-offs is what makes the difference.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/overscroll-behavior-css/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>OpenAI&#39;s Assistants API is Deprecated: Migrate to the New Responses API</title>
    <link href="https://syntackle.com/blog/openai-assistants-to-responses-api/"/>
    <published>2025-10-06T17:14:28Z</published>
    <updated>2025-10-08T09:05:59Z</updated>
    <id>https://syntackle.com/blog/openai-assistants-to-responses-api/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;With the introduction of the new Responses API (which is an upgraded version of the Chat Completions API), OpenAI plans to sunset the Assistants API with effect from 26th August, 2026. The Chat Completions API will still be supported, but OpenAI recommends to use the new Responses API for all upcoming projects.&lt;/p&gt;
&lt;p&gt;Originally, the Assistants API was created for sophisticated tool calling and execution for agentic workflows, but it also supported thread-like persistent chats which was a huge help in maintaining chats and their context.&lt;/p&gt;
&lt;p&gt;Here&#39;s a step-by-step tutorial to migrate the existing Chat Completions and Assistants API code to the Responses API. For that, let me lay out the differences and the transition between the concepts of these two APIs.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;chat-completions-%3E%3E-responses&quot; tabindex=&quot;-1&quot;&gt;Chat Completions &amp;gt;&amp;gt; Responses&lt;/h2&gt;
&lt;p&gt;If your application only uses the &lt;a href=&quot;https://platform.openai.com/docs/api-reference/chat&quot;&gt;Chat Completions API&lt;/a&gt; for stateless, single-turn interactions, your migration path is straightforward.&lt;/p&gt;
&lt;p&gt;A response when used alone, also acts as a stateless entity which outputs according to the input.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Javascript SDK ---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; context&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;system&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;You are a generalist.&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;hey there&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; completion&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;completions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;gpt-5&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;messages&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;responses&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;gpt-5&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;context&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// API Endpoints ---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Chat Completions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; /&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;v1&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;completions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Responses&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; /&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;v1&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;responses&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If using structured outputs by specifying &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/#:~:text=the%20use%20of-,response%20format,-in%20the%20API&quot;&gt;&lt;code&gt;response_format&lt;/code&gt;&lt;/a&gt; and &lt;code&gt;zodResponseFormat&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Chat Completions API&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;response_format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;zodResponseFormat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;diffPayloadSchema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_diff_response&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You now have to specify it as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Responses API&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_schema&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_diff_response&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        schema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;zodResponseFormat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;diffPayloadSchema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_diff_response&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;json_schema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;schema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;assistants-api-%3E%3E-responses-api&quot; tabindex=&quot;-1&quot;&gt;Assistants API &amp;gt;&amp;gt; Responses API&lt;/h2&gt;
&lt;h3 id=&quot;assistants-api&quot; tabindex=&quot;-1&quot;&gt;Assistants API&lt;/h3&gt;
&lt;p&gt;The core architecture of the Assistants API revolved around four key entities: Assistants (configuration), Threads (messages), Runs (execution), and Run Steps (intermediate actions).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1. &lt;em&gt;&lt;strong&gt;Assistant&lt;/strong&gt;&lt;/em&gt; - The persistent object defining configuration. It bundled the core settings like the target model, system instructions, and tools (e.g., code_interpreter, file_search).
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Limitation&lt;/em&gt; - Management/Versioning was often cumbersome as it was defined programmatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2. &lt;em&gt;&lt;strong&gt;Thread&lt;/strong&gt;&lt;/em&gt; - The container for the conversation session. It stored the server-side conversation history, but strictly consisted of only messages.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Limitation&lt;/em&gt; - Limited storage capability, only storing messages.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3. &lt;em&gt;&lt;strong&gt;Run&lt;/strong&gt;&lt;/em&gt; - The asynchronous process responsible for executing the Assistant&#39;s actions against a Thread.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Limitation&lt;/em&gt; - Required complex asynchronous polling loops. Could enter states like &lt;code&gt;requires_action&lt;/code&gt; for tool execution, complicating client-side orchestration. The Thread was locked while a Run was in progress.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4. &lt;em&gt;&lt;strong&gt;Run Steps&lt;/strong&gt;&lt;/em&gt; - Detailed internal objects tracking the progress and intermediate actions of the Run.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Limitation&lt;/em&gt; - Generalized objects tied to the complex, asynchronous lifecycle of the Run, necessitating checks and event handling for tracking progress.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Assistants API was always in beta, in other words, it never transformed into something concrete. Here&#39;s how the Assistant API looks when implemented in javascript with the help of OpenAI&#39;s SDK.&lt;/p&gt;
&lt;h3 id=&quot;assistants-api-flow&quot; tabindex=&quot;-1&quot;&gt;Assistants API Flow&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1. Assistant Creation&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;openai&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    apiKey&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; assistant&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;beta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;assistants&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;gpt-4.1-2025-04-14&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;threadAssistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    instructions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Provide output in markdown format.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;2. Thread Creation&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; thread&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;beta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;threads&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;3. Adding a Message to the Thread&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; newThreadMessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;beta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;threads&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    threadId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;4. Running a thread by creating a Run&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;beta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;threads&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;runs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stream&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    threadId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        assistant_id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;assistantId&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;5. Listening to Run Events (Steps)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// while streaming is enabled&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;messageCreated&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;textDelta&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;textDelta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** ... ... ... **/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;end&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;responses-api&quot; tabindex=&quot;-1&quot;&gt;Responses API&lt;/h3&gt;
&lt;p&gt;The Responses API changes this flow a bit and gives new names to the core architectural entities of the Assistants API.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Assistants&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; -&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Prompts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Threads&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; -&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Conversations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Runs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; -&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Responses&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Run-Steps&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; -&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Items&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;1. &lt;em&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;/em&gt; - Prompts are designed to hold configuration like model choice, tools, and system guidance (instructions), allowing them to focus purely on high-level behavior and constraints. They can &lt;em&gt;strictly&lt;/em&gt; be accessed only from the &lt;a href=&quot;https://platform.openai.com/chat&quot;&gt;Dashboard&lt;/a&gt;, and there&#39;s no programmatic way to create them. You can grab the ID of the prompt to reference it from code. One awesome thing about them is in-built versioning support.&lt;/li&gt;
&lt;li&gt;2. &lt;em&gt;&lt;strong&gt;Conversation&lt;/strong&gt;&lt;/em&gt; - Conversations store generalized objects called Items, which represent a stream of data beyond just text messages, including tool calls, tool outputs, and other information. While creating a response, you can specify the conversation ID and the context and state of the conversation will be accessible and maintained.&lt;/li&gt;
&lt;li&gt;3. &lt;em&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;/em&gt; - The cumbersome asynchronous Run process is replaced by the simpler Response primitive. You send input items and get output items back, unifying the execution process. As per OpenAI, Responses benefit from lower costs due to substantially improved cache utilization (showing a 40% to 80% improvement in internal tests over Chat Completions).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;responses-api-flow-(for-persistent-conversations)&quot; tabindex=&quot;-1&quot;&gt;Responses API Flow (For Persistent Conversations)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1. Create a Prompt through the Dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1759767719/Screenshot_2025-10-06_at_9.39.46_PM_pzmznw.png&quot; alt=&quot;OpenAI API Platform Dashboard&quot; height=&quot;827&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: platform.openai.com&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;2. Create a Conversation&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;openai&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    apiKey&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; thread&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;conversations&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;3. Create a Response&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;responses&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        prompt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;prompt_id_from_dashboard&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        conversation&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;conversation_id&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        store&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        stream&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the prompt is configurable using the &lt;code&gt;Dashboard&lt;/code&gt;, so when you specify the &lt;code&gt;prompt_id&lt;/code&gt;, it will refer to the configuration of the prompt created via the dashboard, but if you want you can also override properties through code as well.&lt;/p&gt;
&lt;p&gt;However, the &lt;code&gt;input&lt;/code&gt; property extends, meaning, there are message input fields in the dashboard which allow you to define some default messages to start a conversation as well as a system message. And, the user message you send from the code gets concatenated to the messages defined in the prompt.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1759769011/Screenshot_2025-10-06_at_10.13.10_PM_xwnqgc.png&quot; alt=&quot;OpenAI API Platform Dashboard - Prompt Edit Mode&quot; height=&quot;782&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: platform.openai.com&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;4. Iterate over Response Events&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// while streaming is enabled (stream: true)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;responses&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        /** */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        stream&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; event&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;response.output_text.delta&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;response.output_item.added&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;item&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;in_progress&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    /** ... */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;response.failed&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;response.completed&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** */&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;The Assistants API was a huge help in bringing thread-like conversations to life and it worked to some extent. Now, OpenAI has decided to revamp and improve upon it in the form of the Responses API. As mentioned before, the Assistants API is deprecated and will be abandoned with effect from 26th August, 2026, so now is the time to plan a migration to the Responses API.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/openai-assistants-to-responses-api/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>The Minimal React App Setup You Need [2026]</title>
    <link href="https://syntackle.com/blog/the-minimal-react-setup-you-need/"/>
    <published>2025-09-15T17:24:25Z</published>
    <updated>2026-01-26T09:11:37Z</updated>
    <id>https://syntackle.com/blog/the-minimal-react-setup-you-need/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Deciding which tools to use while building a React web application is subjective, but in this post, I will propose a minimum set of tools needed to build a simple React application. This post will help you to build and get the React application up and running in just a few minutes.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;1.-vite-(for-bundling)&quot; tabindex=&quot;-1&quot;&gt;1. Vite (For Bundling)&lt;/h2&gt;
&lt;p&gt;Vite is now the go-to choice for most of the developers while building a React application from scratch. I wrote a detailed article about why is that the case — &lt;a href=&quot;https://syntackle.com/blog/create-react-app-deprecated/&quot;&gt;&amp;quot;Create React App (CRA) is Deprecated, Officially: What&#39;s Next?&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Vite will take care of the build process and bundle React in a javascript bundle ready to be deployed. As a matter of fact, Vite provides React templates which you can use to quickly spin-up a Vite/React repository — &lt;a href=&quot;https://vite.dev/guide/#scaffolding-your-first-vite-project&quot;&gt;&amp;quot;Scaffolding Your First Vite Project&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; vite@latest&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; my-react-app&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --template&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; react-ts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;All of the templates Vite provides - &lt;a href=&quot;https://github.com/vitejs/vite/tree/main/packages/create-vite&quot;&gt;create-vite&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;2.-react-router-(for-routing)&quot; tabindex=&quot;-1&quot;&gt;2. React Router (For Routing)&lt;/h2&gt;
&lt;p&gt;React Router might not be the best solution for routing in React, but it is one of the stable solutions out there. If you want a more modern solution, then there&#39;s Tanstack Router from the Tanstack ecosystem which is a great contender for React Router.&lt;/p&gt;
&lt;p&gt;Tanstack Router provides in-built type-safety (typescript support) with file based routing approach unlike React Router which has a more declarative component based approach.&lt;/p&gt;
&lt;h2 id=&quot;3.-shadcn-(for-ui-components)&quot; tabindex=&quot;-1&quot;&gt;3. Shadcn (For UI components)&lt;/h2&gt;
&lt;p&gt;Shadcn is the modern UI library which has almost every component you need. Not only that, those components are customizable and can be built up on. It works well with tailwindcss.&lt;/p&gt;
&lt;p&gt;Some other notable UI libraries include MUI, Ant Design, Chakra UI, and Mantine.&lt;/p&gt;
&lt;h2 id=&quot;4.-tanstack-query-(for-query-state-management)&quot; tabindex=&quot;-1&quot;&gt;4. Tanstack Query (For Query State Management)&lt;/h2&gt;
&lt;p&gt;Tanstack Query is by far the most important and useful tool in modern React applications. API query management is one of the most boilerplate-y tasks while building a React application. I always think about how to manage those API calls, their states, and how they impact the UI. All of that is solved by Tanstack Query (React Query) which is a complete and state-of-the-art solution for query state management.&lt;/p&gt;
&lt;p&gt;From maintaining, caching, refetching queries to having dependable and conditional queries, almost every query fetching problem is solved by Tanstack Query.&lt;/p&gt;
&lt;h2 id=&quot;5.-zustand-(for-global-state-management)&quot; tabindex=&quot;-1&quot;&gt;5. Zustand (For Global State Management)&lt;/h2&gt;
&lt;p&gt;I really don&#39;t like React Context API for top-level state management as it re-renders everything in between (even if it doesn&#39;t consume/use the context).&lt;/p&gt;
&lt;p&gt;And I don&#39;t blame React Context API for that. It is meant to trigger a re-render because we are wrapping the components under a Provider and it assumes that every child will be affected by it. So, the Context is attached to a parent and all of its children. But, true global state doesn&#39;t necessarily have to be attached to a React component. It has to be &lt;em&gt;truly&lt;/em&gt; global.&lt;/p&gt;
&lt;p&gt;In fact, React Redux also uses the React Context API internally to pass store data to deeply nested components, which doesn&#39;t make it truly global.&lt;/p&gt;
&lt;p&gt;That&#39;s where Zustand comes into action. Zustand provides global states which aren&#39;t attached to the React Component lifecycle. Another nice perf optimization one can do while using Zustand is using atomic selectors instead of selecting the entire store state at once.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ReactComponent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ❌ - returns a new object ever single time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;inventory&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;users&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useShopStore&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ✅ - atomic values which stay the same if unchanged&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; inventory&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useShopStore&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;inventory&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; users&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useShopStore&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;users&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;The above list is not exhaustive and it is the bare-minimum set of tools required to build a simple React application. I am not saying that this is the ultimate React setup which should be used for every application. You might not even need global state management for instance, and in that case you are free to skip Zustand. But it&#39;s a great start if you quickly want to get things running.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/the-minimal-react-setup-you-need/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Vibe Coding — The Fast Food of Coding</title>
    <link href="https://syntackle.com/blog/vibe-coding/"/>
    <published>2025-08-15T12:03:10Z</published>
    <updated>2025-09-07T07:41:21Z</updated>
    <id>https://syntackle.com/blog/vibe-coding/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;The usage of AI, especially in the software industry, has increased a lot lately, but everything has a downside — and that, is, &lt;em&gt;excess&lt;/em&gt;. Excess of anything is bad, and that includes the use of AI.&lt;/p&gt;
&lt;p&gt;&amp;quot;Vibe Coding&amp;quot; is a term coined by &lt;a href=&quot;https://karpathy.ai/&quot;&gt;Andrej Karpathy&lt;/a&gt; (founder of Eureka Labs and an ex-founding member at OpenAI) in his &lt;a href=&quot;https://x.com/karpathy/status/1886192184808149383?lang=en&quot;&gt;tweet&lt;/a&gt; posted on Feb 3, 2025. He states, &amp;quot;There&#39;s a new kind of coding I call &amp;quot;vibe coding&amp;quot;, where you fully give in to the vibes, embrace exponentials, and forget that the code even exists&amp;quot;.&lt;/p&gt;
&lt;p&gt;With that in mind, in this post, I explore the downsides of vibe coding and how to balance it.&lt;/p&gt;
&lt;p&gt;Recently, &lt;a href=&quot;https://www.linkedin.com/in/zen-van-riel&quot;&gt;Zen van Riel&lt;/a&gt; - a senior software engineer at &lt;a href=&quot;https://syntackle.com/blog/github-copilot-with-custom-api-key/&quot;&gt;GitHub&lt;/a&gt;, shared a linkedin post about the dark side of vibe coding. He describes a developer constantly trying to fix &amp;quot;simple things&amp;quot; using an AI model but, unfortunately, the AI model fails to do so every time. It&#39;s not only a waste of time, but a waste of money (credits) as well. Zen wonderfully describes this through an analogy of fast food (hence, the title of this post).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1755255123/Syntackle/Posts/Screenshot_2025-08-15_at_4.20.40_PM_fv0vdg.png&quot; alt=&quot;Zen van Riel&#39;s post on LinkedIn&quot; height=&quot;852&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;In my opinion, that&#39;s a brilliant analogy because it talks about balance. Let me draw some parallels between fast food and vibe coding.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;vibe-coding-%26-fast-food&quot; tabindex=&quot;-1&quot;&gt;Vibe Coding &amp;amp; Fast Food&lt;/h2&gt;
&lt;h3 id=&quot;1.-instant-gratification&quot; tabindex=&quot;-1&quot;&gt;1. Instant Gratification&lt;/h3&gt;
&lt;p&gt;When you send a prompt and see output in a matter of seconds, you feel good. It gives you a dopamine hit, a sense of accomplishment, but it&#39;s only a matter of time when it all fades away.&lt;/p&gt;
&lt;p&gt;When the AI model starts making mistakes and no matter which prompt you give, it still doesn&#39;t work, that&#39;s when you start feeling I could have done it myself.&lt;/p&gt;
&lt;p&gt;It starts becoming messy if you look at the bigger picture.&lt;/p&gt;
&lt;h3 id=&quot;2.-opinionated-ingredients&quot; tabindex=&quot;-1&quot;&gt;2. Opinionated Ingredients&lt;/h3&gt;
&lt;p&gt;If you don&#39;t know what you are building, AI model can use whatever it thinks is good to build your application and sometimes it&#39;s not the best for your application and use case. And, it can be very hard to refactor later.&lt;/p&gt;
&lt;p&gt;For you to be able to give enough context of what you are building and why, you need to be aware of the available tools and techniques needed to make that happen.&lt;/p&gt;
&lt;h3 id=&quot;3.-lacks-nutritional-value&quot; tabindex=&quot;-1&quot;&gt;3. Lacks Nutritional Value&lt;/h3&gt;
&lt;p&gt;Once you get the taste of it, you stop asking the &amp;quot;why&amp;quot;/&amp;quot;how&amp;quot; question. Questioning what the AI model does almost feels like a second thought. And you know what it does? It drains your ability to learn and grasp new things.&lt;/p&gt;
&lt;p&gt;That&#39;s the reason I never recommend beginners to rely solely on AI tools for coding/programming. Always questions things and ask the model why it did what it did.&lt;/p&gt;
&lt;h3 id=&quot;4.-looks-good-on-the-outside&quot; tabindex=&quot;-1&quot;&gt;4. Looks Good on the Outside&lt;/h3&gt;
&lt;p&gt;AI tools might get you the exact thing you want, but if you look closely at the code, (if you have decent knowledge about programming) you start seeing inconsistencies and tech debt.&lt;/p&gt;
&lt;h3 id=&quot;5.-forms-bad-habit-in-the-long-term&quot; tabindex=&quot;-1&quot;&gt;5. Forms Bad Habit in the Long Term&lt;/h3&gt;
&lt;p&gt;If you only vibe code, you never get to focus on the grilling part of programming, which is to sit patiently and think about the problem at hand. You never really learn how to dissect a problem and solve it incrementally.&lt;/p&gt;
&lt;p&gt;Some of the best solutions to software engineering problems I had occurred to me when I was asleep, walking or just wandering around with an open mind. Sometimes, all it takes is to take a step back and relax.&lt;/p&gt;
&lt;h2 id=&quot;correct-usage-of-ai-tools-for-coding&quot; tabindex=&quot;-1&quot;&gt;Correct Usage of AI tools for Coding&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Don&#39;t solely rely on AI of you are a beginner&lt;/strong&gt;&lt;/em&gt;. Read in-depth articles, watch YouTube videos explaining how stuff really works and practice, build something. Building something on your own is key and it will get you out of tutorial hell.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Familiarize yourself with what you are building and why.&lt;/strong&gt;&lt;/em&gt; It&#39;s easy to get lost in whatever the AI model generates, so it&#39;s necessary to have decent knowledge about technologies you want to use to build your project.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Use AI model in an incremental way.&lt;/strong&gt;&lt;/em&gt; Prompt the AI model to do small changes instead of giving it a complex task. Break down the problem yourself, or even better, prompt the AI model to generate a plan first, study the plan, and then tell it to implement. It will help you learn and break down the problem.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Ask the AI model why it did what it did.&lt;/strong&gt;&lt;/em&gt; AI models are great at explaining things, so use it to your own advantage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wrote about my experience of vibe coding an entire full stack application in this post — &lt;a href=&quot;https://syntackle.com/blog/the-problem-with-ai-generated-code/&quot;&gt;&amp;quot;The Problem With AI Generated Code And How To Deal With It&amp;quot;&lt;/a&gt;. Let me know if you found it useful.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/vibe-coding/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to Run SQL Server on a Mac: A Step By Step Guide</title>
    <link href="https://syntackle.com/blog/sql-server-on-macos-and-linux/"/>
    <published>2025-06-29T08:48:31Z</published>
    <updated>2025-07-01T06:58:52Z</updated>
    <id>https://syntackle.com/blog/sql-server-on-macos-and-linux/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;SQL Server is not natively supported on macOS and thus, there is only one option to use it on macOS, and that is via Docker. In this tutorial, I will setup and configure SQL Server database on macOS via Docker, demonstrate how to connect to the database, and also show how to backup and restore the DB.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-docker&quot; tabindex=&quot;-1&quot;&gt;Setting up Docker&lt;/h2&gt;
&lt;p&gt;If you haven&#39;t already, install &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker Desktop&lt;/a&gt; on your system and make sure to enable the following option in Docker Desktop settings (General &amp;gt; Apple Virtualization framework &amp;gt; Use Rosetta for x86_64/amd64 emulation on Apple Silicon).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751126908/Syntackle/Posts/Screenshot_2025-06-28_at_9.36.55_PM_dpmh6x.png&quot; alt=&quot;docker desktop emulator setting macos&quot; height=&quot;940&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;New to Docker? &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/&quot;&gt;Complete Guide To Docker&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;pulling-sql-server-docker-image&quot; tabindex=&quot;-1&quot;&gt;Pulling SQL Server Docker Image&lt;/h2&gt;
&lt;p&gt;Open the terminal of your choice and run:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pull&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; mcr.microsoft.com/mssql/server:2022-latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will pull the latest SQL Server docker image from docker hub.&lt;/p&gt;
&lt;h2 id=&quot;running-sql-server-image-in-a-container&quot; tabindex=&quot;-1&quot;&gt;Running SQL Server Image in a Container&lt;/h2&gt;
&lt;p&gt;To run the docker image of SQL Server in a docker container, run the following command inside your terminal:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;ACCEPT_EULA=Y&#39;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;MSSQL_SA_PASSWORD=&amp;#x3C;Strong_Password&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-p &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;8081:1433&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --name&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; sql-server-2022&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --hostname&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; sql-server-2022&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-v &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;your_host_di&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;r&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/data:/var/opt/mssql/data&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-v &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;your_host_di&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;r&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/log:/var/opt/mssql/log&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-v &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;your_host_di&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;r&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/secrets:/var/opt/mssql/secrets&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-v &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;your_host_di&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;r&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/backups:/var/opt/mssql/backups&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;-d &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;mcr.microsoft.com/mssql/server:2022-latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ACCEPT_EULA&lt;/code&gt; and &lt;code&gt;MSSQL_SA_PASSWORD&lt;/code&gt; are environment variables. You must provide a strong password as per the &lt;a href=&quot;https://learn.microsoft.com/en-us/sql/relational-databases/security/password-policy?view=sql-server-ver17&quot;&gt;password policy&lt;/a&gt; of SQL Server authentication.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-p&lt;/code&gt; flag is the port mapping of host and container ports. The default port at which SQL Server instance runs is 1433 which will be the port inside the container. So, port 1433 of the container will be mapped to port 8081 of the host machine (macOS). You can leave the port 1433 for the host as well, but I prefer to change it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; and &lt;code&gt;hostname&lt;/code&gt; are container identifiers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt; will ensure the container runs in a detached mode, meaning it won&#39;t block the terminal process, the terminal won&#39;t output anything except the container ID and the terminal process will exit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; represents mounting a host machine directory as a data volume. In simple words, it&#39;s a way to persist data across multiple container instances. The data won&#39;t go away when you remove a container and the new container instance can access the data left behind by the old one. Replace &lt;code&gt;&amp;lt;your_host_dir&amp;gt;&lt;/code&gt; with a directory of your choice (outside the container), for example, &lt;code&gt;~/Documents/mssql/data&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mcr.microsoft.com/mssql/server:2022-latest&lt;/code&gt; is the image identifier (name) which will run inside the container.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With that being done, SQL Server should now successfully run on your system.&lt;/p&gt;
&lt;h2 id=&quot;connecting-(accessing)-the-sql-server-instance&quot; tabindex=&quot;-1&quot;&gt;Connecting (Accessing) the SQL Server Instance&lt;/h2&gt;
&lt;p&gt;To connect to the running SQL Server instance there are multiple tools which you can use. The best one to use is the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;&lt;code&gt;mssql&lt;/code&gt;&lt;/a&gt; Visual Studio Code extension.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751130998/Syntackle/Posts/Screenshot_2025-06-28_at_4.46.18_PM_yftsbo.png&quot; alt=&quot;adding new connection in mssql vscode extension&quot; height=&quot;1909&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Make sure to go to Advanced Settings and set the port number to the port of the host machine on which you exposed SQL server instance of the container.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751180707/Screenshot_2025-06-28_at_4.46.55_PM_eeacv9.png&quot; alt=&quot;adding new connection in mssql vscode extension (advanced settings)&quot; height=&quot;1856&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Learn more about the &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/&quot;&gt;Visual Studio Code extension&lt;/a&gt; on &lt;a href=&quot;https://learn.microsoft.com/en-us/sql/tools/visual-studio-code-extensions/mssql/mssql-extension-visual-studio-code?view=sql-server-ver16&quot;&gt;Microsoft&#39;s documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want a full-fledged dedicated database explorer tool, then I would recommend &lt;a href=&quot;https://dbeaver.io/&quot;&gt;DBeaver&lt;/a&gt; which works well with most of the popular and established SQL database engines.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure-data-studio/what-is-azure-data-studio&quot;&gt;Azure Data Studio&lt;/a&gt; is another tool which you can use to interact with SQL Server database, but Microsoft announced that it will be &lt;em&gt;retiring&lt;/em&gt; in Feb 2026, meaning it will not receive any feature or security updates past Feb 2026, and Microsoft recommends to switch to Visual Studio Code&#39;s mssql extension which I demonstrated earlier in this post.&lt;/p&gt;
&lt;h2 id=&quot;backing-up-and-restoring-the-database&quot; tabindex=&quot;-1&quot;&gt;Backing Up and Restoring the Database&lt;/h2&gt;
&lt;p&gt;On Windows, it&#39;s easy to backup and restore SQL Server databases using SQL Server Management Studio (SSMS), but not so easy on MacOS. The host directories (specifically, &lt;code&gt;&amp;lt;host_dir&amp;gt;/mssql/backups&lt;/code&gt;) that I mounted as data volumes to the container while running it, will help to efficiently backup and restore the database.&lt;/p&gt;
&lt;p&gt;I am going to backup and restore the database using Transact-SQL queries which can be executed in any database management tool of your choice (the one which is used to connect to SQL Server instance).&lt;/p&gt;
&lt;h3 id=&quot;backing-up&quot; tabindex=&quot;-1&quot;&gt;Backing Up&lt;/h3&gt;
&lt;p&gt;To back up an existing database, run the following Transact SQL query:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;BACKUP&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; [db_name]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    TO&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DISK&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; N&#39;/var/opt/mssql/backups/db-name.bak&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    WITH&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; NOFORMAT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;NOINIT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;NAME&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; N&#39;db-name&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;SKIP&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;NOREWIND&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;NOUNLOAD&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;STATS&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;GO&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the disk path is of the &lt;em&gt;container&lt;/em&gt;, but since I mapped it to a host directory path (as a data volume), I can access the backup file on that host directory path as well, for me it&#39;s &lt;code&gt;&amp;lt;host_dir&amp;gt;/backups&lt;/code&gt; (see 👆 &lt;a href=&quot;https://syntackle.com/blog/sql-server-on-macos-and-linux/#running-sql-server-image-in-a-container&quot;&gt;Running SQL Server Image in a Container&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&quot;restoring&quot; tabindex=&quot;-1&quot;&gt;Restoring&lt;/h3&gt;
&lt;p&gt;If I want to restore a database from an existing backup file (&lt;code&gt;.bak&lt;/code&gt;) retrieved from a different environment, I have to put that file in a host directory which is mounted as a data volume to a container directory, in this case &lt;code&gt;&amp;lt;host_dir&amp;gt;/backups&lt;/code&gt; which is mapped to &lt;code&gt;/var/opt/mssql/backups&lt;/code&gt; inside the container.&lt;/p&gt;
&lt;p&gt;Once I put that file in &lt;code&gt;&amp;lt;host_dir&amp;gt;/backups&lt;/code&gt;, it becomes instantly available at &lt;code&gt;/var/opt/mssql/backups&lt;/code&gt; which will be used to restore the DB using a Transact SQL query.&lt;/p&gt;
&lt;p&gt;To restore from an existing &lt;code&gt;.bak&lt;/code&gt; backup file, run:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;RESTORE&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DATABASE&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; db_name &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DISK&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/backups/db_name.bak&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    WITH&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; MOVE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;db_name&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; TO&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/data/db_name.mdf&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    MOVE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;db_name_Log&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; TO&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/data/db_name_Log.ldf&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    REPLACE&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;GO&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;REPLACE keyword will overwrite the existing database (if it already exists). Without REPLACE, you will get a warning to backup the database if it already exists and the query will terminate.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If there are secondary files associated with the db you are restoring, you might end up encountering an error. To overcome that, list all of the associated files with the backup by running:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;RESTORE&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; FILELISTONLY&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; FROM&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DISK&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/backups/db_name.bak&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might get an output similar to the following:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;LogicalName         PhysicalName                                                                 ..............&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;------------------- ---------------------------------------------------------------------------- ---------------&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;YourDB              Z:&#92;Microsoft SQL Server&#92;MSSQL15.GLOBAL&#92;MSSQL&#92;Data&#92;YourDB&#92;YourDB.mdf          ..............&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;YourDB_Product      Z:&#92;Microsoft SQL Server&#92;MSSQL15.GLOBAL&#92;MSSQL&#92;Data&#92;YourDB&#92;YourDB_Product.ndf  ..............&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;YourDB_Customer     Z:&#92;Microsoft SQL Server&#92;MSSQL15.GLOBAL&#92;MSSQL&#92;Data&#92;YourDB&#92;YourDB_Customer.ndf ..............&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;YourDB_log          Z:&#92;Microsoft SQL Server&#92;MSSQL15.GLOBAL&#92;MSSQL&#92;Data&#92;YourDB&#92;YourDB_Log.ldf      ..............&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consider those secondary files and move them also using the &lt;code&gt;MOVE&lt;/code&gt; directive:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;RESTORE&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DATABASE&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; db_name &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; DISK&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/backups/db_name.bak&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    WITH&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; MOVE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;db_name&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; TO&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/data/db_name.mdf&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    MOVE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;db_name_Log&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; TO&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/data/db_name_Log.ldf&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    MOVE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;secondary_file_name_as_in_the_list&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; TO&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;/var/opt/mssql/data/secondary_file_name_as_in_the_list.&amp;#x3C;extension_as_printed_in_the_list&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    REPLACE&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;GO&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s how you can configure, run and manage SQL Server on macOS, but there&#39;s a quick way to setup a docker container using the mssql VS Code extension.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;NOTE: The following method does not allow much customization such as creating data volumes.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;the-quickest-way-to-create-sql-server-docker-container&quot; tabindex=&quot;-1&quot;&gt;The Quickest Way To Create SQL Server Docker Container&lt;/h2&gt;
&lt;p&gt;Install the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql&quot;&gt;mssql Visual Studio Code extension&lt;/a&gt; and while adding a new connection, select &lt;code&gt;Create local SQL Container&lt;/code&gt; option.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751185923/Screenshot_2025-06-29_at_2.01.36_PM_gs8feo.png&quot; alt=&quot;adding new connection in mssql vscode extension (local sql container)&quot; height=&quot;936&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751186168/Screenshot_2025-06-29_at_2.05.41_PM_j3jv4i.png&quot; alt=&quot;adding new connection in mssql vscode extension (local sql container). step 2: checks&quot; height=&quot;839&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Enter the configuration details to create a local docker container which runs SQL Server. The password you set will be the password for the SQL Server authentication (the SA user password).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751186589/Screenshot_2025-06-29_at_2.08.32_PM_lamra2.png&quot; alt=&quot;adding new connection in mssql vscode extension (local sql container). step 3: enter config details&quot; height=&quot;1136&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;With that being done, a new docker container will spin up and you can verify that by running &lt;code&gt;docker ps&lt;/code&gt; or by verifying it from the Docker Desktop dashboard.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/sql-server-on-macos-and-linux/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Vite 7.0 — All Major Changes</title>
    <link href="https://syntackle.com/blog/vite-7-is-here/"/>
    <published>2025-06-25T17:05:16Z</published>
    <updated>2025-10-18T09:20:52Z</updated>
    <id>https://syntackle.com/blog/vite-7-is-here/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;Vite team introduced &amp;quot;Vite+&amp;quot; (a superset of Vite) in Amsterdam ViteConf on October 13, 2025. It is in its development phase right now, with a preview scheduled to be released in early 2026, but &lt;a href=&quot;https://tally.so/r/nGWebL&quot;&gt;early access&lt;/a&gt; registrations are open.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Vite is my go to build tool for building modern frontend applications and it integrates well with top frontend libraries such as React. On June 24, 2025, the team behind Vite announced v7.0 which brings huge changes to the build tool. Here are 3 major changes which come with Vite 7.0.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;dropped-node.js-18&quot; tabindex=&quot;-1&quot;&gt;Dropped Node.js 18&lt;/h2&gt;
&lt;p&gt;Node.js v18 reached its &lt;a href=&quot;https://www.herodevs.com/blog-posts/node-js-18-end-of-life-what-it-means-and-how-to-prepare&quot;&gt;End-Of-Life (EOL)&lt;/a&gt; in April 2025 and hence, with the new version, Vite is dropping support for Node.js v18.&lt;/p&gt;
&lt;h2 id=&quot;support-for-baseline-widely-available-browser-features&quot; tabindex=&quot;-1&quot;&gt;Support for Baseline Widely Available Browser Features&lt;/h2&gt;
&lt;p&gt;Cross browser compatibility is a major issue when dealing with relative new web features and &lt;a href=&quot;https://web-platform-dx.github.io/web-features/&quot;&gt;Baseline&lt;/a&gt; addresses exactly that. If a web feature is marked as &amp;quot;baseline widely available&amp;quot;, its trusted that it will work on all major browsers (&lt;a href=&quot;https://web-platform-dx.github.io/web-features/#how-do-features-become-part-of-baseline%3F&quot;&gt;core browser set&lt;/a&gt;). Vite 7.0 adds &#39;baseline-widely-available&#39; as the default browser target.&lt;/p&gt;
&lt;h2 id=&quot;dropped-legacy-sass-api&quot; tabindex=&quot;-1&quot;&gt;Dropped Legacy Sass API&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://sass-lang.com/documentation/breaking-changes/legacy-js-api/&quot;&gt;Sass announced deprecation of its legacy JS API&lt;/a&gt; in Dart Sass 1.45.0, which will be completely removed in Dart Sass v2.0. In accordance with this, Vite 7.0 has dropped support for the legacy Sass API as well and will now default to the modern API only.&lt;/p&gt;
&lt;p&gt;Read the full &lt;a href=&quot;https://vite.dev/guide/migration&quot;&gt;Vite v6 to v7 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Vite&#39;s team has also been working on a new Rust-based bundler named &lt;code&gt;rolldown-vite&lt;/code&gt; which they plan to make the default Vite bundler in the near future. It will be interesting to see the performance improvements that come with it, considering the fact that Vite is already fast enough as compared to other build tools and bundlers.&lt;/p&gt;
&lt;p&gt;Recently, React also announced the &lt;a href=&quot;https://syntackle.com/blog/create-react-app-deprecated/&quot;&gt;deprecation of &amp;quot;Create React App&amp;quot;&lt;/a&gt; — its opinionated build setup, making Vite the defacto build tool for libraries like React.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/vite-7-is-here/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>5 Best Places To Learn React For Free</title>
    <link href="https://syntackle.com/blog/best-places-to-learn-react/"/>
    <published>2025-05-28T17:46:27Z</published>
    <updated>2025-06-07T07:50:39Z</updated>
    <id>https://syntackle.com/blog/best-places-to-learn-react/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;In this guide, I am sharing five of the best places to learn &lt;a href=&quot;https://syntackle.com/blog/create-react-app-deprecated/&quot;&gt;React&lt;/a&gt;. Doesn&#39;t matter if you are a newbie in React or advancing your journey as a React developer, these resources will help you at every step of your React journey. I wish I came across these resources while I was new to React.&lt;/p&gt;
&lt;p&gt;These React resources are completely free and you can always purchase a more in-depth, premium version of them. Most of the creators offer premium React courses along with free content.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;1.-josh-cameau&#39;s-blog&quot; tabindex=&quot;-1&quot;&gt;1. Josh Cameau&#39;s Blog&lt;/h2&gt;
&lt;p&gt;I was fascinated when I came across this blog by &lt;a href=&quot;https://www.joshwcomeau.com/&quot;&gt;Josh Cameau&lt;/a&gt; and its immensely satisfying animations. Turns out, not only the animations, but the content is also well laid out and easy to understand.&lt;/p&gt;
&lt;p&gt;This blog is useful for you if you want a deep understanding of how React works and what are the consequences of using it the wrong way. My favorite post from this blog is &lt;a href=&quot;https://www.joshwcomeau.com/react/why-react-re-renders/&quot;&gt;Why React Re-Renders&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Josh also offers a full paid course called &amp;quot;&lt;a href=&quot;https://www.joyofreact.com/&quot;&gt;The Joy of React&lt;/a&gt;&amp;quot; if you prefer a structured way of learning.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1748449583/Syntackle/Posts/Screenshot_2025-05-28_at_9.55.01_PM_wuod9x.png&quot; alt=&quot;Landing Page of Josh Cameau&#39;s Blog&quot; height=&quot;546&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://www.joshwcomeau.com/&quot;&gt;joshwcomeau.com&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;2.-scrimba&quot; tabindex=&quot;-1&quot;&gt;2. Scrimba&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://scrimba.com/t0react&quot;&gt;Scrimba&lt;/a&gt; is the only platform which offers truly interactive courses. I took their React course a while ago and was able to build a &lt;a href=&quot;https://contact-card.vercel.app/&quot;&gt;digital contact card generator&lt;/a&gt; using React.&lt;/p&gt;
&lt;p&gt;Scrimba&#39;s courses not only explain the concept theoretically, but they also have in-between challenges which you can complete on your own by pausing the video in the same editor which the instructor is on — yes it&#39;s pretty unique and fascinating. They offer a good amount of free courses so that you can explore.&lt;/p&gt;
&lt;p&gt;Scrimba has also &lt;a href=&quot;https://developer.mozilla.org/en-US/blog/mdn-scrimba-partnership/&quot;&gt;partnered with MDN&lt;/a&gt; to support producing these courses for the betterment of the developer community.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1748451208/Syntackle/Posts/scrimba_q4mt3e.png&quot; alt=&quot;Scrimba &amp; MDN as partners&quot; height=&quot;432&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://developer.mozilla.org/en-US/blog/mdn-scrimba-partnership/&quot;&gt;developer.mozilla.org&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;3.-robin-weiruch&#39;s-blog&quot; tabindex=&quot;-1&quot;&gt;3. Robin Weiruch&#39;s Blog&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.robinwieruch.de/categories/react/&quot;&gt;Robin&#39;s blog&lt;/a&gt; might not look attractive at first but trust me it has some of the best React content in it. I recommend going through this blog if you want more &lt;a href=&quot;https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/&quot;&gt;React&lt;/a&gt; tutorials and design implementations.&lt;/p&gt;
&lt;p&gt;Robin has written a book named &lt;a href=&quot;https://www.roadtoreact.com/&quot;&gt;&amp;quot;Road To React&amp;quot;&lt;/a&gt; which you can read to get a solid understanding of React. He has also published &lt;a href=&quot;https://www.road-to-next.com/&quot;&gt;&amp;quot;Road To Next&amp;quot;&lt;/a&gt; which is a book to get you started with Nextjs.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1748452287/Syntackle/Posts/Screenshot_2025-05-28_at_10.40.58_PM_tfw7xy.png&quot; alt=&quot;Robin Weiruch&#39;s Blog&quot; height=&quot;918&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://www.robinwieruch.de/categories/react/&quot;&gt;robinwieruch.de&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;4.-net-ninja&quot; tabindex=&quot;-1&quot;&gt;4. Net Ninja&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/@NetNinja&quot;&gt;Net Ninja&lt;/a&gt; YouTube channel by &lt;a href=&quot;https://www.udemy.com/user/47fd83f6-5e4a-4e87-a0f0-519ac51f91b6/&quot;&gt;Shaun Pelling&lt;/a&gt; is one of the most underrated coding related channels. Personally, I have found the content to be comprehensive and extremely easy to understand. Not only that, the content is structured unlike other youtube channels where you don&#39;t find structured content which reveals itself in a flow.&lt;/p&gt;
&lt;p&gt;You can go through its &lt;a href=&quot;https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d&quot;&gt;React&lt;/a&gt; playlist or explore other playlists on a ton of new technologies and frameworks such as Alpine.js, Pinia, HTMX, SolidJS, and more.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1748453083/Syntackle/Posts/Screenshot_2025-05-28_at_10.54.20_PM_a3sndb.png&quot; alt=&quot;Net Ninja&#39;s YouTube Channel&quot; height=&quot;857&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://www.youtube.com/@NetNinja&quot;&gt;youtube.com&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;5.-dan-abramov&#39;s-blog-%26-react&#39;s-official-documentation&quot; tabindex=&quot;-1&quot;&gt;5. Dan Abramov&#39;s Blog &amp;amp; React&#39;s Official Documentation&lt;/h2&gt;
&lt;p&gt;Dan Abramov is one of the core members of the React team and has his own blog &lt;a href=&quot;https://overreacted.io/&quot;&gt;overreacted.io&lt;/a&gt; on which he shares some highly technical and interesting things about React and the Web.&lt;/p&gt;
&lt;p&gt;And, there is no better place to explore React other than its official &lt;a href=&quot;https://react.dev/&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1748454151/Syntackle/Posts/Screenshot_2025-05-28_at_11.12.14_PM_hyjxpo.png&quot; alt=&quot;Dan Abramov&#39;s Blog - overreacted.io&quot; height=&quot;911&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://overreacted.io/&quot;&gt;overreacted.io&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/best-places-to-learn-react/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Ice — A Free Alternative To Bartender — Menu Bar Management Made Easy</title>
    <link href="https://syntackle.com/blog/the-most-useful-macos-app/"/>
    <published>2025-05-18T07:06:57Z</published>
    <updated>2025-09-19T15:54:19Z</updated>
    <id>https://syntackle.com/blog/the-most-useful-macos-app/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Ice won&#39;t work on macOS 26 Tahoe (macOS 26 made significant changes in APIs), a stable release is in the works, but there are &lt;a href=&quot;https://github.com/jordanbaird/Ice/releases/tag/0.11.13-dev.2&quot;&gt;beta releases&lt;/a&gt; (0.11.13-dev.x) which you can try.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I switched from Windows to macOS recently, and overall it has been a great experience so far, except for one thing — the menu bar icons.&lt;/p&gt;
&lt;p&gt;Some applications such as &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/&quot;&gt;Docker&lt;/a&gt;, have menu bar icons that allow you to do quick and useful actions such as quitting the app or restarting a background service &lt;em&gt;directly&lt;/em&gt; from the menu bar besides the control center.&lt;/p&gt;
&lt;p&gt;The problem arises when you have multiple applications adding their icons to the menu bar and taking up space. That&#39;s not the problem, the problem is that there&#39;s no way in macOS to show the complete list of all menu bar icons when the space is exhausted and the icons overflow. What happens is the latter icons are &lt;em&gt;hidden&lt;/em&gt; behind the notch (if your mac has one) or behind the menu bar items of the currently open application.&lt;/p&gt;
&lt;p&gt;It&#39;s as if someone applied &lt;code&gt;overflow: hidden&lt;/code&gt; to the menu bar icons container.&lt;/p&gt;
&lt;h2 id=&quot;ice---menu-bar-management-tool-for-macos&quot; tabindex=&quot;-1&quot;&gt;Ice - Menu Bar Management Tool For macOS&lt;/h2&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1746972554/Syntackle/Posts/Screenshot_2025-05-11_at_7.37.16_PM_rn01oq.png&quot; alt=&quot;menu bar layout tab under Ice&#39;s settings&quot; height=&quot;916&quot; width=&quot;1320&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Ice is a free and open source menu bar management tool for &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/&quot;&gt;macOS&lt;/a&gt; developed by Jordan Baird that allows you to view overflowing (hidden) menu bar icons as well as re-order them.&lt;/p&gt;
&lt;p&gt;Once you install Ice, you can access the settings by right-clicking on the empty space in the menu bar.&lt;/p&gt;
&lt;p&gt;If you go to the menu bar layout tab under Ice&#39;s settings, you see two sections — one for the &lt;em&gt;always&lt;/em&gt; visible icons, and one for the icons which can be accessed from a dropdown list. Note that it only shows the icons for active applications that have added their icons in the menu bar. To see the icon in Ice&#39;s settings, you may need to start the application that adds the icon to the menu bar once launched.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1747550785/Syntackle/Posts/ice-settings_mxivji.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;ice menu bar settings on macos&quot; height=&quot;450&quot; width=&quot;800&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h2 id=&quot;a-free-bartender-alternative&quot; tabindex=&quot;-1&quot;&gt;A Free Bartender Alternative&lt;/h2&gt;
&lt;p&gt;Ice is a free alternative to &lt;a href=&quot;https://www.macbartender.com/&quot;&gt;bartender&lt;/a&gt; — a similar menu bar management tool for macOS. The difference is, Ice is free and open source, while bartender is not.&lt;/p&gt;
&lt;p&gt;I would highly recommend folks to &lt;a href=&quot;https://buymeacoffee.com/jordanbaird&quot;&gt;donate&lt;/a&gt; and support Ice — the work of &lt;a href=&quot;https://github.com/jordanbaird&quot;&gt;Jordan Baird&lt;/a&gt;. As per a github discussion thread, the developer behind Ice intends to &lt;a href=&quot;https://github.com/jordanbaird/Ice/discussions/424&quot;&gt;slow down development on Ice&lt;/a&gt; to focus on their full time job.&lt;/p&gt;
&lt;h2 id=&quot;closing-thoughts&quot; tabindex=&quot;-1&quot;&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;There are a bunch of open source applications which provide a ton of value without asking anything in return, but it&#39;s our responsibility to give back to the open source community, even if it&#39;s just a shout out or a small monetary contribution.&lt;/p&gt;
&lt;p&gt;If you are a developer who recently switched to a Mac, check out this &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/&quot;&gt;guide&lt;/a&gt; on how to set it up and the first things you should do on it.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/the-most-useful-macos-app/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>The Problem With AI Generated Code And How To Deal With It</title>
    <link href="https://syntackle.com/blog/the-problem-with-ai-generated-code/"/>
    <published>2025-05-13T16:35:47Z</published>
    <updated>2025-11-24T07:00:06Z</updated>
    <id>https://syntackle.com/blog/the-problem-with-ai-generated-code/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;AI models and tools are becoming more and more capable day by day, especially at generating code. With tools like &lt;a href=&quot;https://capacity.so/?via=murtuzaali&quot;&gt;Capacity&lt;/a&gt;, &lt;a href=&quot;https://firebase.studio/&quot;&gt;Firebase Studio&lt;/a&gt;, &lt;a href=&quot;https://lovable.dev/&quot;&gt;Lovable&lt;/a&gt;, &lt;a href=&quot;https://v0.dev/&quot;&gt;v0&lt;/a&gt;, &lt;a href=&quot;https://www.augmentcode.com/&quot;&gt;Augment&lt;/a&gt;, one can create entire full stack applications by combining one or more of these tools. But, there&#39;s something off once you run the code generated by them.&lt;/p&gt;
&lt;p&gt;In this post, I will walk you through my experience of creating a full-stack application using some of these AI coding assistants/agents and share some of my observations.&lt;/p&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;tldr%3B&quot; tabindex=&quot;-1&quot;&gt;TLDR;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AI generated code can create a lot of tech debt if you are not aware of what the code does.&lt;/li&gt;
&lt;li&gt;If you are new to coding, only rely on AI agents/assistants for educational purposes.&lt;/li&gt;
&lt;li&gt;AI models hallucinate quite often — you need a skilled developer to get them back on track.&lt;/li&gt;
&lt;li&gt;Improve debugging skills to debug some nasty issues created by AI generated code (if any).&lt;/li&gt;
&lt;li&gt;AI generated code doesn&#39;t eradicate the need of a software developer, it only increases the productivity for now.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;developing-a-full-stack-application-using-ai&quot; tabindex=&quot;-1&quot;&gt;Developing A Full Stack Application Using AI&lt;/h2&gt;
&lt;p&gt;Recently, I developed a &lt;a href=&quot;https://mbuffs.vercel.app/&quot;&gt;full stack application&lt;/a&gt; using Lovable and Firebase Studio along with Gemini 2.5 Pro. It&#39;s a collaborative movie list which you can share with your friends and create collections which are editable by them.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/&quot;&gt;Gemini 3 Pro&lt;/a&gt; is out now!&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;frontend&quot; tabindex=&quot;-1&quot;&gt;Frontend&lt;/h3&gt;
&lt;p&gt;I vibe coded the frontend using Lovable and found out that it was great at generating frontend. I told Lovable my preferred tech stack, which is &lt;a href=&quot;https://syntackle.com/blog/create-react-app-deprecated/&quot;&gt;React + Vite + React Query&lt;/a&gt;, and it did a great job following that.&lt;/p&gt;
&lt;p&gt;Also, Lovable made its own decisions along the way, for example using Radix UI (&lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;shadcn&lt;/a&gt;) for components and lucide-react for icons which were actually good. Lovable was able to figure out &lt;em&gt;trivial&lt;/em&gt; things such as configuring eslint, tailwind and a couple of vite plugins which were required.&lt;/p&gt;
&lt;h3 id=&quot;backend&quot; tabindex=&quot;-1&quot;&gt;Backend&lt;/h3&gt;
&lt;p&gt;For backend, I tried Google&#39;s Firebase Studio and vibe coded the backend using Gemini 2.5 Pro and it did a pretty good job. I suggested it to use &lt;a href=&quot;https://syntackle.com/blog/node-http-server-using-hono/&quot;&gt;Node&lt;/a&gt;, Express, and Neon&#39;s &lt;a href=&quot;https://syntackle.com/blog/running-postgresql-using-docker/&quot;&gt;PostgreSQL&lt;/a&gt; instance along with the TMDB API.&lt;/p&gt;
&lt;p&gt;For authentication, I suggested gemini to use &lt;a href=&quot;https://lucia-auth.com/&quot;&gt;lucia-auth&lt;/a&gt; and &lt;a href=&quot;https://github.com/pilcrowonpaper/arctic&quot;&gt;arctic&lt;/a&gt; to implement an OAuth based authentication strategy and gemini 2.5 pro nailed it. One thing I like about gemini 2.5 pro is that it recognizes its mistakes and fixes them once realized. The auth strategy it implemented was session-based and although it worked fine locally, it wasn&#39;t meant to run on serverless functions. I needed something stateless - so I decided to go with JWT (JSON Web Tokens).&lt;/p&gt;
&lt;p&gt;I instructed gemini to re-work the auth strategy to use JWT instead of the session based implementation and it did a good job.&lt;/p&gt;
&lt;p&gt;I loved the fact that gemini 2.5 pro generated one-off DDL SQL queries for the neon postgresql instance to create initial schema, and they were perfect, more importantly, &lt;em&gt;in-sync&lt;/em&gt; with the &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/&quot;&gt;code&lt;/a&gt; it generated (thanks to the &lt;a href=&quot;https://ai.google.dev/gemini-api/docs/long-context&quot;&gt;larger context window&lt;/a&gt; of gemini 2.5 pro).&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;If you love Lovable, you might want to try &lt;a href=&quot;https://capacity.so/?via=murtuzaali&quot;&gt;Capacity&lt;/a&gt; which lets you create, clone, and redesign web applications. Capacity offers a &lt;a href=&quot;https://capacity.so/pricing/?via=murtuzaali&quot;&gt;free plan&lt;/a&gt; that includes 5 credits per month, ability to create public projects, and Claude 3.7 Sonnet.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1751781830/Syntackle/Posts/Screenshot_2025-07-06_at_11.32.29_AM_qqyg12.png&quot; alt=&quot;Capacity.so landing page&quot; height=&quot;805&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://capacity.so/?via=murtuzaali&quot;&gt;capacity.so&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h3 id=&quot;running-the-genai-code&quot; tabindex=&quot;-1&quot;&gt;Running the GenAI Code&lt;/h3&gt;
&lt;p&gt;It wasn&#39;t a success on the first try. Ran into multiple type-errors and API layer issues, so went back to firebase studio and told it to build the project using CLI commands, look at the type errors and fix them. It fixed most of them but not the ones which were a little bit complex and required human intervention.&lt;/p&gt;
&lt;p&gt;I observed that gemini went into a loop sometimes, where it tried one thing, didn&#39;t work, switched to do something new, and when that also didn&#39;t work, it was back at square one.&lt;/p&gt;
&lt;h3 id=&quot;deployment&quot; tabindex=&quot;-1&quot;&gt;Deployment&lt;/h3&gt;
&lt;p&gt;Deploying the code was &lt;em&gt;mostly&lt;/em&gt; a manual thing. I used Vercel to deploy both frontend and backend. This and debugging were the only two things I had to do myself.&lt;/p&gt;
&lt;h2 id=&quot;the-consequences&quot; tabindex=&quot;-1&quot;&gt;The Consequences&lt;/h2&gt;
&lt;p&gt;Vibe coding an entire full stack app from start to finish in an &lt;em&gt;extremely&lt;/em&gt; less amount of time looks good on paper, but if I look closely, I can see a significant amount of tech debt in the code — things like unused code, unnecessary abstractions, unrelated and inconsistent code, etc.&lt;/p&gt;
&lt;p&gt;If someone who is completely new to coding vibe codes and develops an application, they will have no idea what the AI model is doing. It&#39;s kind of a black box for a newbie in code. Worst thing is that they won&#39;t be able to debug issues on their own and will have to solely rely on AI to debug, which can take more time than someone who has decent programming knowledge and can navigate through those issues easily.&lt;/p&gt;
&lt;p&gt;Another issue is that AI models still hallucinate and can go off track. If you don&#39;t know how to bring them back on track, you might spend more time giving prompts than you would have spent coding the application on your own.&lt;/p&gt;
&lt;h2 id=&quot;the-right-way&quot; tabindex=&quot;-1&quot;&gt;The Right Way&lt;/h2&gt;
&lt;p&gt;Until AI coding agents and tools do something magical and are able to generate clean, to the point and production-ready code, I recommend generating and using AI code responsibly and wisely. If you are new to programming, I suggest using AI tools as helpers only — to help you learn along the way, and not sole reliers that you blindly trust.&lt;/p&gt;
&lt;p&gt;Also, I recommend to generate code incrementally — moving on to the next step once you have tested and verified the previous one.&lt;/p&gt;
&lt;p&gt;To summarize:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI generated code can create a lot of tech debt if you are not aware of what the code does.&lt;/li&gt;
&lt;li&gt;If you are new to coding, only rely on AI agents/assistants for educational purposes.&lt;/li&gt;
&lt;li&gt;AI models hallucinate quite often — you need a skilled developer to get them back on track.&lt;/li&gt;
&lt;li&gt;Improve debugging skills to debug some nasty issues created by AI generated code (if any).&lt;/li&gt;
&lt;li&gt;AI generated code doesn&#39;t eradicate the need of a software developer, it only increases the productivity for now.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;closing-thoughts&quot; tabindex=&quot;-1&quot;&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;If you think AI can independently generate production-ready code, I don&#39;t think we are there yet. And I don&#39;t think AI will completely eradicate software jobs, in fact, software engineers will undergo a transformation where they will have to work along with AI. Software engineers will be more like architect-level decision makers. AI won&#39;t come for their job, it will &lt;em&gt;be&lt;/em&gt; their job.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/the-problem-with-ai-generated-code/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>MCP (Model Context Protocol) Explained — All You Need To Know</title>
    <link href="https://syntackle.com/blog/model-context-protocol/"/>
    <published>2025-04-20T10:09:49Z</published>
    <updated>2025-09-27T13:32:39Z</updated>
    <id>https://syntackle.com/blog/model-context-protocol/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;MCP (Model Context Protocol) can be called as a buzzword of 2025, except it&#39;s not just that. It&#39;s a communication protocol launched by &lt;a href=&quot;https://anthropic.com/&quot;&gt;Anthropic&lt;/a&gt; — the company behind the family of Claude AI models. Almost all major AI companies including Google and OpenAI have embraced MCP and it&#39;s on its way to become a standardized way of communication for AI models.&lt;/p&gt;
&lt;p&gt;This post is about me exploring what MCP is, building a really basic MCP server, how it works, and why there was a need for it. I&#39;ll try to keep the terminology as simple as it gets.&lt;/p&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;what-is-mcp-(model-context-protocol)%3F&quot; tabindex=&quot;-1&quot;&gt;What is MCP (Model Context Protocol)?&lt;/h2&gt;
&lt;p&gt;MCP, a.k.a, Model Context Protocol in terms of AI, is a standardized way for &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/&quot;&gt;AI&lt;/a&gt; models to communicate with external tools and applications. As the name suggests, it&#39;s a protocol — a way of communication and a set of rules, just like what you have in other protocols, such as HTTP or TCP.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.&amp;quot;&lt;/em&gt; - &lt;a href=&quot;https://modelcontextprotocol.io/introduction&quot;&gt;modelcontextprotocol.io&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;mcp-components&quot; tabindex=&quot;-1&quot;&gt;MCP Components&lt;/h3&gt;
&lt;p&gt;MCP follows a client-server architecture, and hence there are two building blocks which are required to facilitate MCP communication: MCP Client and MCP Server.&lt;/p&gt;
&lt;h4 id=&quot;mcp-client&quot; tabindex=&quot;-1&quot;&gt;MCP Client&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;It is what talks to an MCP server using the Model Context Protocol.&lt;/li&gt;
&lt;li&gt;An MCP client is often a part of the AI tool you use to interact with an AI model (if it supports MCP, of course).&lt;/li&gt;
&lt;li&gt;You can think of it as a tool which helps in spinning up a connection to the MCP server and talk to it using MCP.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;mcp-server&quot; tabindex=&quot;-1&quot;&gt;MCP Server&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;An MCP server is what handles the requests coming from the AI model (MCP client) and maps them to appropriate tasks which are defined in the server.&lt;/li&gt;
&lt;li&gt;MCP server defines which actions the AI model can perform on the server/tool and which resources it has access to.&lt;/li&gt;
&lt;li&gt;Think of it as a mapper which maps the request with an appropriate action.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I send a prompt to an AI tool which supports MCP, for instance, &lt;a href=&quot;https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/&quot;&gt;Claude&lt;/a&gt; Desktop, the MCP client will go to the AI model (Claude for example), the AI model will think how to proceed with the request and explore all of the available tools and resources, and then it will decide which tools/resources to use and tell the MCP client to talk to the external MCP server to fetch/execute those. Once the MCP client gets the response from the MCP server, it will send that data to the AI model which will re-structure it in a human readable way.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745154633/Syntackle/Posts/mcp-client-server.excalidraw_hjsdf9.png&quot; alt=&quot;mcp client server communication&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Up until now, I used to ask, well is it any different from an actual &lt;a href=&quot;https://syntackle.com/blog/github-copilot-with-custom-api-key/&quot;&gt;API&lt;/a&gt;? It&#39;s not, but at the same time it is. Let me explain.&lt;/p&gt;
&lt;h2 id=&quot;why-do-we-need-mcp%3F&quot; tabindex=&quot;-1&quot;&gt;Why Do We Need MCP?&lt;/h2&gt;
&lt;p&gt;As an AI model, if I want to connect to external tools or &lt;a href=&quot;https://syntackle.com/blog/best-apps-to-use-in-2025/&quot;&gt;applications&lt;/a&gt;, I need to build an API for it so that the AI model can communicate with the tool or application — that&#39;s easy, but note that it&#39;s specific to that particular tool or application. If there&#39;s another tool which I would like my AI model to use, I have to build a custom interface (API) for that as well.&lt;/p&gt;
&lt;p&gt;So, traditionally, what happens is the number of APIs I have to build is directly proportional to the number of tools/applications I want my AI model to use. That&#39;s quite cumbersome for an AI company to build and manage. And here&#39;s where Anthropic played a smart move.&lt;/p&gt;
&lt;p&gt;What &lt;a href=&quot;https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/&quot;&gt;Anthropic&lt;/a&gt; did was offload the task of building APIs to the developer community, i.e., the external tools and applications. They were like, &amp;quot;Hey, why don&#39;t we create a universal protocol that&#39;ll be AI model-and-tool-agnostic? Meaning, any AI model supporting it can communicate to any external tool/application which supports the protocol.&amp;quot;&lt;/p&gt;
&lt;p&gt;That way, AI model providers just have to support MCP and their AI models can communicate with any external tool which also supports MCP. The task of integrating MCP with the application became a job of the application &lt;a href=&quot;https://syntackle.com/blog/looking-at-a-problem-as-a-developer/&quot;&gt;developer&lt;/a&gt; and not the AI model provider. It&#39;s a win-win for both because they only have to maintain a single interface, that is MCP.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745055129/Syntackle/Posts/Untitled-2025-01-15-2229.excalidraw_gz87l7.png&quot; alt=&quot;a comparison of MCP approach with non-MCP approach for AI models&quot; height=&quot;635&quot; width=&quot;759&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Not only that, third party MCP servers can also be built for a given application. This encourages the developer community to build solutions on top of existing applications using AI without the need to know the specifics about the AI model or platform and vice-versa.&lt;/p&gt;
&lt;h2 id=&quot;how-to-build-an-mcp-server&quot; tabindex=&quot;-1&quot;&gt;How to Build An MCP Server&lt;/h2&gt;
&lt;p&gt;An MCP server can define three components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tools: Used to perform an action, execute a function. Similar to PUT/PATCH/DELETE HTTP requests.&lt;/li&gt;
&lt;li&gt;Resources: Data that can be read by MCP clients. Similar to GET HTTP request.&lt;/li&gt;
&lt;li&gt;Pre-defined Prompts: Prompt templates that can be used by LLMs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MCP servers can be built using Python, Node, Java, Kotlin, and C#. In this tutorial, I am building a basic MCP server using Node (TypeScript).&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;Install Typescript and Node, if you haven&#39;t done that already.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;install-the-mcp-sdk-%26-setup-application&quot; tabindex=&quot;-1&quot;&gt;Install the MCP SDK &amp;amp; Setup Application&lt;/h3&gt;
&lt;p&gt;Initialize a Node application using &lt;code&gt;npm init -y&lt;/code&gt;. Then, install the appropriate SDK depending on your programming language or framework. For me it will be:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @modelcontextprotocol/sdk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modify the &lt;code&gt;package.json&lt;/code&gt; file to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make the node application a module.&lt;/li&gt;
&lt;li&gt;Including an executable file in the &lt;code&gt;bin&lt;/code&gt; folder using the &lt;code&gt;bin&lt;/code&gt; script.&lt;/li&gt;
&lt;li&gt;Set the permissions for the executable file in the &lt;code&gt;build&lt;/code&gt; script.&lt;/li&gt;
&lt;li&gt;If necessary, include a &lt;code&gt;files&lt;/code&gt; script to define which files are included in the final build.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;mcp-demo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;bin&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;mcp-demo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;./dist/index.js&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;ts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npx tsc&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;rootFile&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;chmod 755 ./dist/index.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;build&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npm-run-all -s ts rootFile&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;files&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;    &quot;dist&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;dependencies&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;@modelcontextprotocol/sdk&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;^1.10.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;npm-run-all&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;^4.1.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;typescript&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;^5.8.3&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Creating a &lt;code&gt;tsconfig.json&lt;/code&gt; file at the root of the project folder is recommended.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;compilerOptions&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;target&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;ES2022&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;module&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Node16&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;moduleResolution&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Node16&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;outDir&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;./dist&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;rootDir&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;./src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;strict&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;esModuleInterop&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;skipLibCheck&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;forceConsistentCasingInFileNames&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;include&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;src/**/*&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;exclude&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;node_modules&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;create-an-mcp-server-instance&quot; tabindex=&quot;-1&quot;&gt;Create an MCP Server Instance&lt;/h3&gt;
&lt;p&gt;Create an &lt;code&gt;src&lt;/code&gt; folder and in that an &lt;code&gt;index.ts&lt;/code&gt; file (you are free to define your own folder structure but make sure to update &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;tsconfig.json&lt;/code&gt; accordingly).&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// index.ts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;McpServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@modelcontextprotocol/sdk/server/mcp.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;StdioServerTransport&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@modelcontextprotocol/sdk/server/stdio.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; McpServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;mcp-demo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    version&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    capabilities&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        resources&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        tools&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        prompts&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; transport&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; StdioServerTransport&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;transport&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Server started and connected to transport.&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A transport type is required by the MCP server to communicate with the MCP client, and that&#39;s why the &lt;code&gt;stdio&lt;/code&gt; transport type is used. Note that this transport type is only available in &lt;a href=&quot;https://syntackle.com/blog/nvm-node-issue-command-not-found/&quot;&gt;Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;configure-an-mcp-client&quot; tabindex=&quot;-1&quot;&gt;Configure an MCP Client&lt;/h3&gt;
&lt;p&gt;For this tutorial, I am using &lt;a href=&quot;https://claude.ai/download&quot;&gt;Claude Desktop App&lt;/a&gt; as an MCP client to communicate with my MCP server, but you are free to use any MCP client you prefer.&lt;/p&gt;
&lt;p&gt;First, I need to inform Claude Desktop about my MCP server and give it the path to find it. To do that, I need to modify a configuration file of Claude Desktop. That file exists on the following paths for the following operating systems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MacOS &amp;amp; Linux: &lt;code&gt;~/Library/Application&#92; Support/Claude/claude_desktop_config.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;AppData&#92;Claude&#92;claude_desktop_config.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Open that file using VSCode from the terminal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MacOS &amp;amp; Linux: &lt;code&gt;code ~/Library/Application&#92; Support/Claude/claude_desktop_config.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;code $env:AppData&#92;Claude&#92;claude_desktop_config.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, once you are able to access and view that file, add a mention of your MCP server as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;mcpServers&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;mcp-demo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;command&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;args&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                &quot;/Users/murtuzaalisurti/Documents/Development/MCP Servers/demo/dist/index.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// absolute path to your MCP server build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the file and restart Claude Desktop. If you encounter an error, go to the &lt;code&gt;Claude App Settings &amp;gt; Developer &amp;gt; Logs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the MCP server is correctly configured and registered in Claude Desktop, you wouldn&#39;t get any errors and you can verify the MCP server is running by going to &lt;code&gt;Claude App Settings &amp;gt; Developer &amp;gt; [MCP Server Name]&lt;/code&gt; — it should have a &lt;code&gt;running&lt;/code&gt; status.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745139998/Syntackle/Posts/Screenshot_2025-04-20_at_2.34.38_PM_kcgxxp.png&quot; alt=&quot;claude desktop app settings&#39; developer section (to verify MCP server is properly configured and running)&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h3 id=&quot;use-the-mcp-server&quot; tabindex=&quot;-1&quot;&gt;Use the MCP Server&lt;/h3&gt;
&lt;p&gt;In Claude Desktop, after you connect your MCP server, you should see a plug icon if you have defined resources in your MCP server. That allows you to attach the data from those resources to the AI model context.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745141070/Syntackle/Posts/Screenshot_2025-04-20_at_2.43.52_PM_fcgd3k.png&quot; alt=&quot;claude desktop app mcp resources context icon (plug icon)&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745141159/Syntackle/Posts/Screenshot_2025-04-20_at_2.44.59_PM_hmtkxq.png&quot; alt=&quot;claude desktop app mcp resources context icon click (plug icon)&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Once you attach a resource to the chat context and tell Claude to retrieve that info in normal human language, it will do so.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745141412/Syntackle/Posts/Screenshot_2025-04-20_at_2.59.54_PM_kncbvs.png&quot; alt=&quot;attaching mcp resource to chat context in Claude Desktop&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;If you define &lt;code&gt;tools&lt;/code&gt; in your MCP server, you will see a hammer icon in Claude Desktop depicting that those tools are available to use.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745142520/Syntackle/Posts/Screenshot_2025-04-20_at_3.18.15_PM_jgkdqr.png&quot; alt=&quot;attaching mcp tool to chat context in Claude Desktop&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;For example, I added a tool which modifies the age of a user in my MCP server and used it in combination with the existing resource which provides a list of users to Claude. Note that you need to attach the resource to the chat context. Also, Claude will ask your permission to modify the data.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; users&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Charlie&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;35&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;tool&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;    &quot;modify-user-age&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;    &quot;Modify user age&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(), &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// install zod: npm i zod&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; users&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`User &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; not found`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; age&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`User &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; updated to age &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745143352/Syntackle/Posts/Screenshot_2025-04-20_at_3.22.38_PM_labs5o.png&quot; alt=&quot;using mcp server resource and tool together in Claude Desktop (asking permission)&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745142985/Syntackle/Posts/Screenshot_2025-04-20_at_3.23.17_PM_xq2p26.png&quot; alt=&quot;using mcp server resource and tool together in Claude Desktop&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Now, if I ask it again to fetch the list of users (after attaching the resource to chat context), Claude responds with the updated data.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1745143338/Syntackle/Posts/Screenshot_2025-04-20_at_3.32.00_PM_mobqlj.png&quot; alt=&quot;using mcp server resource and tool together in Claude Desktop (fetching updated user list)&quot; height=&quot;1084&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;That was all about me building a basic and simple MCP server and integrating it with Claude Desktop (an MCP client).&lt;/p&gt;
&lt;h2 id=&quot;list-of-mcp-servers&quot; tabindex=&quot;-1&quot;&gt;List of MCP Servers&lt;/h2&gt;
&lt;p&gt;Here&#39;s an inexhaustive list of MCP servers you can try:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/git&quot;&gt;Git MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/github/github-mcp-server&quot;&gt;GitHub MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/google-maps&quot;&gt;Google Maps MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Hawstein/mcp-server-reddit&quot;&gt;Reddit MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ahujasid/blender-mcp&quot;&gt;Blender MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/samuelgursky/davinci-resolve-mcp&quot;&gt;Da Vinci Resolve MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/gdrive&quot;&gt;Google Drive MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GLips/Figma-Context-MCP&quot;&gt;Figma MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://glama.ai/mcp/servers/@prisma/prisma&quot;&gt;Prisma MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/gitlab&quot;&gt;GitLab MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem&quot;&gt;FileSystem MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/slack&quot;&gt;Slack MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search&quot;&gt;Brave Search MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite&quot;&gt;SQLite MCP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;mcp-server-directories-(registries)&quot; tabindex=&quot;-1&quot;&gt;MCP Server Directories (Registries)&lt;/h3&gt;
&lt;p&gt;If you want to explore more MCP servers, check out these MCP server directories/registries — they contain a compilation of variety of MCP servers, including community and official MCP servers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/registry/tree/main/docs&quot;&gt;Official MCP Registry&lt;/a&gt; - One can publish/retrieve MCP servers and also build public/private sub-registries.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://glama.ai/mcp/servers&quot;&gt;Glama&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cursor.directory/mcp&quot;&gt;Cursor MCP Directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/blog/lynn-mikami/awesome-mcp-servers&quot;&gt;HuggingFace MCP Server List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/punkpeye/awesome-mcp-servers&quot;&gt;punkpeye/awesome-mcp-servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#-third-party-servers&quot;&gt;modelcontextprotocol MCP server list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mcp.so/&quot;&gt;MCP.so&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;MCP feels like the &lt;a href=&quot;https://syntackle.com/blog/node-http-server-using-hono/&quot;&gt;HTTP&lt;/a&gt; for AI, not in a technical sense, but in a more universal sense. In fact, HTTP is itself a transport method used by MCP. MCP doesn&#39;t solve every AI model communication problem, but certainly makes it easier. Some also term MCP as the &amp;quot;USB-C&amp;quot; for AI.&lt;/p&gt;
&lt;p&gt;Other protocols such as &lt;a href=&quot;https://google.github.io/A2A/#/&quot;&gt;A2A&lt;/a&gt; (Agent to Agent Protocol) make communication between AI agents built using different frameworks easier. This is just the beginning of AI communication protocols and I hope we will see some more powerful, better and privacy-focused AI protocols.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/model-context-protocol/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to Use Custom Models with API Keys in GitHub Copilot (VSCode) — Bring Your Own Key (BYOK)</title>
    <link href="https://syntackle.com/blog/github-copilot-with-custom-api-key/"/>
    <published>2025-04-04T18:01:18Z</published>
    <updated>2025-12-28T07:58:06Z</updated>
    <id>https://syntackle.com/blog/github-copilot-with-custom-api-key/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;With the &amp;quot;March 2025 (v1.99.0)&amp;quot; Visual Studio Code release, GitHub Copilot supports BYOK (Bring Your Own Keys), meaning, I can now use my own custom API key and use any models associated with it in GitHub Copilot VSCode extension.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that BYOK feature is not available to Copilot Business or Enterprise users yet. - &lt;a href=&quot;https://code.visualstudio.com/docs/copilot/customization/language-models#_bring-your-own-language-model-key&quot;&gt;code.visualstudio.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;GitHub Copilot Chat supports API keys generated from major AI platforms/providers, namely, Anthropic, Azure, &lt;a href=&quot;https://syntackle.com/blog/deepseek-ai-model-and-openrouter/&quot;&gt;OpenRouter&lt;/a&gt;, OpenAI, Gemini and Ollama.&lt;/p&gt;
&lt;p&gt;In this tutorial, I will demonstrate how you can use custom API keys from multiple AI providers and use any models associated with them in GitHub Copilot Chat VSCode extension.&lt;/p&gt;
&lt;h2 id=&quot;1.-open-github-copilot-chat&quot; tabindex=&quot;-1&quot;&gt;1. Open GitHub Copilot Chat&lt;/h2&gt;
&lt;p&gt;Go to the GitHub Copilot Chat window by clicking the copilot icon besides the search bar in VSCode. You can also access github copilot chat by using the shortcut &lt;code&gt;Ctrl + Alt + I&lt;/code&gt; (Windows) or &lt;code&gt;Ctrl + Command + I&lt;/code&gt; (MacOS).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1743783893/Syntackle/Posts/Screenshot_2025-04-04_at_9.54.32_PM_hpttng.png&quot; alt=&quot;github copilot chat vscode window panel&quot; height=&quot;1476&quot; width=&quot;780&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;2.-manage-models&quot; tabindex=&quot;-1&quot;&gt;2. Manage Models&lt;/h2&gt;
&lt;p&gt;Click on the model name dropdown (&lt;code&gt;claude-3-5-sonnet-202041022&lt;/code&gt; in the image below) and select &amp;quot;Manage Models...&amp;quot;.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1766239952/Syntackle/Posts/manage-models-ghcp.png&quot; alt=&quot;github copilot chat vscode window panel (manage models)&quot; height=&quot;948&quot; width=&quot;778&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat Manage Models Feature&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;3.-configuring-ai-provider&quot; tabindex=&quot;-1&quot;&gt;3. Configuring AI Provider&lt;/h2&gt;
&lt;p&gt;Once you click on &#39;Manage Models...&#39;, a window will appear, listing all of the configured AI model providers. The manage models feature supports &lt;a href=&quot;https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/&quot;&gt;Anthropic&lt;/a&gt;, OpenAI, OpenRouter, Ollama, Azure, Groq, xAI, and Google. If you want to configure another available AI model provider which is not yet configured, click on &#39;Add Models&#39; button.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1766242198/Syntackle/Posts/Screenshot_2025-12-20_at_8.19.14_PM_z0rq5x.png&quot; alt=&quot;github copilot chat vscode dialog (manage models &gt; configure AI provider)&quot; height=&quot;400&quot; width=&quot;1198&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat Manage Models Feature (Configuring AI Provider)&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;4.-add-your-api-key&quot; tabindex=&quot;-1&quot;&gt;4. Add Your API Key&lt;/h2&gt;
&lt;p&gt;Once you add a new AI platform/provider or modify a configured one, you will be asked to provide an API key (or you will be asked to sign in to microsoft account if you select Azure).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1766907771/Syntackle/Posts/Screenshot_2025-12-28_at_1.11.14_PM_zoarya.png&quot; alt=&quot;github copilot chat vscode dialog (manage models &gt; select AI provider &gt; insert API key)&quot; height=&quot;174&quot; width=&quot;1198&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat Manage Models Feature (Adding API keys)&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;5.-select-ai-models&quot; tabindex=&quot;-1&quot;&gt;5. Select AI Models&lt;/h2&gt;
&lt;p&gt;Once you enter the API key, the window listing configured AI model providers/platforms will refresh, and you can hide/show models which you plan to use with GitHub Copilot.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1766908144/Syntackle/Posts/Screenshot_2025-12-28_at_1.18.22_PM_i3vhat.png&quot; alt=&quot;github copilot chat vscode dialog (manage models &gt; select AI provider &gt; insert API key &gt; show/hide models to be used)&quot; height=&quot;771&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat Manage Models Feature (Selecting Models)&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;using-the-ai-models&quot; tabindex=&quot;-1&quot;&gt;Using the AI Models&lt;/h2&gt;
&lt;p&gt;For instance, if I selected a total of five AI models across two AI providers, all of those five models will be listed in the model selection dropdown.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1766908437/Syntackle/Posts/Screenshot_2025-12-28_at_1.21.59_PM_atlj0v.png&quot; alt=&quot;github copilot chat vscode panel (selecting AI model)&quot; height=&quot;1877&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;GitHub Copilot Chat (Selecting Model)&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;One thing that&#39;s missing in this Manage Models feature is the ability to show the AI platform/provider besides the model name. It will be really helpful to differentiate models based on providers, for example, OpenRouter and Anthropic both provide claude-3-5-sonnet model, so it will be helpful to know if I am using a claude model through OpenRouter or Anthropic directly.&lt;/p&gt;
&lt;p&gt;I hope they add this in the future, considering the fact that the Manage Models feature in GitHub Copilot is still in preview.&lt;/p&gt;
&lt;p&gt;UPDATE: Now, the models are categorized clearly. I can see the default Copilot provided models at the top and models from other providers below that with the name of the provider listed on the left side in a distinctive way.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1766908437/Syntackle/Posts/Screenshot_2025-12-28_at_1.21.59_PM_atlj0v.png&quot; alt=&quot;github copilot chat vscode panel (selecting AI model) now updated with model categorization&quot; height=&quot;1877&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Updated GitHub Copilot Chat (Selecting Model)&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/github-copilot-with-custom-api-key/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>TypeScript Switches To Go — What Does This Mean for Developers?</title>
    <link href="https://syntackle.com/blog/typescript-go-port/"/>
    <published>2025-03-13T17:49:30Z</published>
    <updated>2025-03-15T05:32:47Z</updated>
    <id>https://syntackle.com/blog/typescript-go-port/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Microsoft (the company behind TypeScript) and its TypeScript team unveiled the biggest update yet, &lt;a href=&quot;https://devblogs.microsoft.com/typescript/typescript-native-port/&quot;&gt;announcing a switch from JavaScript to Go&lt;/a&gt; on March 11th, 2025. This means TypeScript will receive up to 10x performance gain than its current implementation.&lt;/p&gt;
&lt;p&gt;This is a huge win for developers as it will drastically cut down editor start-up time for significantly large projects as well as improve build time.&lt;/p&gt;
&lt;h2 id=&quot;why-go-(golang)%3F&quot; tabindex=&quot;-1&quot;&gt;Why Go (Golang)?&lt;/h2&gt;
&lt;p&gt;The Typescript team was considering Rust as well as C#, but according to Anders Hejlsberg — lead architect of TypeScript — porting to Go (Golang) was the way of least resistance.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;C# was a top contender for the port, as was Rust. But both would have been a rewrite more than a port. We picked Go because it was the path of least resistance to 10x for &lt;em&gt;&lt;strong&gt;this&lt;/strong&gt;&lt;/em&gt; particular code base. It&#39;s a win for OSS. We couldn&#39;t have done this in the past!&amp;quot;&lt;/em&gt; - &lt;a href=&quot;https://x.com/ahejlsberg/status/1899624685396181031&quot;&gt;Anders Hejlsberg on X (formerly Twitter)&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Also, Go is structurally similar to the implementation of TypeScript and it closely resembles existing patterns in the TypeScript code. That&#39;s why they are calling it a port than a rewrite. Read &lt;a href=&quot;https://github.com/microsoft/typescript-go/discussions/411#discussion-8043589&quot;&gt;this discussion&lt;/a&gt; to know more on why Go was the preferred choice among many other suitable programming languages.&lt;/p&gt;
&lt;h2 id=&quot;a-win-for-developers&quot; tabindex=&quot;-1&quot;&gt;A Win for Developers&lt;/h2&gt;
&lt;p&gt;Here&#39;s what the TypeScript port to Go a.k.a Golang means for software developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improved Editor Startup&lt;/li&gt;
&lt;li&gt;Reduced Memory Usage&lt;/li&gt;
&lt;li&gt;Faster Builds&lt;/li&gt;
&lt;li&gt;Improved Overall Efficiency&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1741887827/Syntackle/Posts/Screenshot_2025-03-13_at_11.13.17_PM_x8zhah.png&quot; alt=&quot;Time taken to compile typescript (running tsc) for listed codebases: vscode, playwright, typeorm, date-fns, trpc, and rxjs.&quot; height=&quot;584&quot; width=&quot;974&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Time taken to compile typescript (running tsc) for listed codebases. Source: &lt;a href=&quot;https://devblogs.microsoft.com/typescript/typescript-native-port/&quot;&gt;devblogs.microsoft.com&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;As shown in the image above, the typescript-go version of TypeScript drastically improved build times when running &lt;code&gt;tsc&lt;/code&gt; on the listed codebases.&lt;/p&gt;
&lt;p&gt;I have worked with significantly large projects involving TypeScript and I can say that it takes a ton of time to load Visual Studio Code and get the TypeScript interpreter running (especially on Windows). The RAM usage is off the charts as well with larger TypeScript codebases.&lt;/p&gt;
&lt;p&gt;Microsoft claims that using the go-based typescript version, it takes 8 times less than what it currently takes to load the editor (for VSCode codebase), i.e, an 8x performance improvement in the editor start-up time.&lt;/p&gt;
&lt;h2 id=&quot;when-will-it-be-released%3F&quot; tabindex=&quot;-1&quot;&gt;When will it be released?&lt;/h2&gt;
&lt;p&gt;The most recent version of TypeScript is 5.8, and it will not be until version 7.0 that the Go port will be released. So, the last JavaScript based TypeScript version will be version 6 (6.x series) which they call it by the codename &amp;quot;Strada&amp;quot;. The codename for the Go based TypeScript version (7.0) is &amp;quot;Corsa&amp;quot;.&lt;/p&gt;
&lt;p&gt;So, in the future, there will be two versions of TypeScript written in two different languages — TypeScript 6 (JS based) and TypeScript 7 (Go based). Note that TypeScript does not follow semantic versioning.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/typescript-go-port/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Eleventy Image Disk Caching Approach — @11ty/eleventy-img</title>
    <link href="https://syntackle.com/blog/eleventy-image-html-transform-plugin-disk-cache/"/>
    <published>2025-03-08T02:24:52Z</published>
    <updated>2025-04-12T13:27:42Z</updated>
    <id>https://syntackle.com/blog/eleventy-image-html-transform-plugin-disk-cache/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;I use the HTML transform method of the &lt;a href=&quot;https://www.npmjs.com/package/@11ty/eleventy-img&quot;&gt;&lt;code&gt;@11ty/eleventy-img&lt;/code&gt;&lt;/a&gt; plugin to post process any &lt;code&gt;img&lt;/code&gt; or &lt;code&gt;picture&lt;/code&gt; tags in my html. I find this method easy and universal. In this guide, I&#39;ll walk you through an approach of utilizing disk cache while using the HTML transform method of the eleventy image plugin.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;tldr&quot; tabindex=&quot;-1&quot;&gt;TLDR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tell the plugin to store the optimized images in the &lt;code&gt;.cache&lt;/code&gt; folder which can be preserved between builds, instead of the build output directory which you might want to clear before each build.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;eleventyImageTransformPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;   formats&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;avif&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;   outputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.cache/@11ty/img/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;   urlPath&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/img/built/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// relative to the build output dir (&amp;#x3C;img&gt; src)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Copy the built images from the &lt;code&gt;.cache&lt;/code&gt; folder to the build output after eleventy has finished processing. Here, &lt;code&gt;public&lt;/code&gt; is the build output directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;eleventy.after&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    cpSync&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;.cache/@11ty/img/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;public/img/built/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// &quot;public&quot; is the build output dir&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;recursive&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;If you are using Vercel to build and host your 11ty site, then you might encounter this issue — &lt;code&gt;ENOENT: no such file or directory, open &#39;/vercel/path0/.cache/eleventy-fetch-fbe00b3353051d063b093fb7cd28fe.buffer&#39;&lt;/code&gt; — see the resolution &lt;a href=&quot;https://syntackle.com/blog/eleventy-image-html-transform-plugin-disk-cache/#11ty-fetch-plugin-exception&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;eleventy-image-plugin-cache&quot; tabindex=&quot;-1&quot;&gt;Eleventy Image Plugin Cache&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/#build-performance&quot;&gt;Eleventy&#39;s image plugin&lt;/a&gt; has primarily two caching options — in-memory cache and disk cache.&lt;/p&gt;
&lt;h3 id=&quot;in-memory-cache&quot; tabindex=&quot;-1&quot;&gt;In-Memory Cache&lt;/h3&gt;
&lt;p&gt;The in-memory cache (as well as disk cache) is controlled by the &lt;code&gt;useCache&lt;/code&gt; config option which is enabled by default. While in &lt;a href=&quot;https://www.11ty.dev/docs/watch-serve/&quot;&gt;watch/serve mode&lt;/a&gt;, identical requests to the same source and with the same config options will get cached and subsequent requests will return that cached response.&lt;/p&gt;
&lt;p&gt;This is a temporary cache which only persists during the current running process. If the process is killed (i.e. 11ty stops running), the cache is gone.&lt;/p&gt;
&lt;p&gt;Also, while using the HTML transform method and doing local development, the images will not be optimized beforehand — instead, they will be optimized on demand/request.&lt;/p&gt;
&lt;p&gt;It means if you open a page containing a single image, no other image except that single image will be optimized until it is requested. The transformOnRequest option governs this behavior and is enabled by default for 11ty&#39;s &lt;code&gt;serve&lt;/code&gt; mode.&lt;/p&gt;
&lt;h3 id=&quot;disk-cache&quot; tabindex=&quot;-1&quot;&gt;Disk Cache&lt;/h3&gt;
&lt;p&gt;Disk cache is a persistent cache which allows me to not re-optimize every single image at every single build. However, there are some caveats which I ran into while using it with the HTML transform method and which you should be aware of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTML transform method co-locates optimized images by default, so your images don&#39;t go to a single directory.&lt;/li&gt;
&lt;li&gt;Disk cache requires you to check-in and persist images in your output directory across builds. This doesn&#39;t work if you clean your output directory before every new build.&lt;/li&gt;
&lt;li&gt;Even if the &lt;a href=&quot;https://www.11ty.dev/docs/deployment/#persisting-cache&quot;&gt;&lt;code&gt;.cache&lt;/code&gt; folder is preserved&lt;/a&gt; by your hosting provider, if you clean your output directory between builds, the images will be re-fetched and re-optimized.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I typically clean the output directory before generating a new build and that&#39;s why I needed a workaround to ensure the existing images are cached and persistent across builds while using the HTML transform method of the eleventy image plugin.&lt;/p&gt;
&lt;p&gt;So, I posted my observations on &lt;a href=&quot;https://mastodon.social/@murtuzaalisurti/114013032233612697&quot;&gt;Mastodon&lt;/a&gt; and, thankfully, got a response from &lt;a href=&quot;https://mastodon.social/@zachleat@zachleat.com&quot;&gt;@zachleat&lt;/a&gt; regarding a potential workaround.&lt;/p&gt;
&lt;h4 id=&quot;approach&quot; tabindex=&quot;-1&quot;&gt;Approach&lt;/h4&gt;
&lt;p&gt;Firstly, instead of storing the images in the 11ty output directory, you tell the eleventy image plugin to optimize and store the images directly to the &lt;code&gt;.cache&lt;/code&gt; folder which you can &lt;a href=&quot;https://www.11ty.dev/docs/deployment/#persisting-cache&quot;&gt;preserve across builds&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;eleventyImageTransformPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@11ty/eleventy-img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** &lt;/span&gt;&lt;span style=&quot;color:#C678DD;font-style:italic&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt; {(import(&quot;@11ty/eleventy&quot;).UserConfig)}&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; persistentImageOutputDir&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;.cache/@11ty/img/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; pathRelativeToBuildOutputDir&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;/img/built/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;eleventyImageTransformPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        formats&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;avif&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        outputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;persistentImageOutputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        urlPath&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pathRelativeToBuildOutputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s important to specify the URL path (&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; src path) as you will be copying the optimized images from the &lt;code&gt;.cache&lt;/code&gt; folder to the build output directory.&lt;/p&gt;
&lt;p&gt;Next, you can copy the optimized images from the &lt;code&gt;.cache&lt;/code&gt; folder to a directory in the build output directory after they have been optimized using the &lt;code&gt;eleventy.after&lt;/code&gt; event.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cpSync&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;node:fs&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;eleventyImageTransformPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@11ty/eleventy-img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** &lt;/span&gt;&lt;span style=&quot;color:#C678DD;font-style:italic&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt; {(import(&quot;@11ty/eleventy&quot;).UserConfig)}&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; persistentImageOutputDir&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;.cache/@11ty/img/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; pathRelativeToBuildOutputDir&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;/img/built/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;eleventyImageTransformPlugin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        formats&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;avif&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        outputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;persistentImageOutputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        urlPath&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pathRelativeToBuildOutputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;eleventy.after&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        cpSync&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            persistentImageOutputDir&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;            `public&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pathRelativeToBuildOutputDir&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// &quot;public&quot; is the build output dir&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;recursive&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s pretty much it. Now, it doesn&#39;t matter if you clear your build output directory before every build, the only thing you need to do is preserve the &lt;code&gt;.cache&lt;/code&gt; folder between builds and that is already configured by default by &lt;a href=&quot;https://www.11ty.dev/docs/deployment/#persisting-cache&quot;&gt;some of the hosting providers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use Vercel and they provide a zero configuration support for preserving the &lt;code&gt;.cache&lt;/code&gt; folder — I just have to select 11ty as a preset/framework. It works until and unless the hosting provider invalidates and discards the &lt;code&gt;.cache&lt;/code&gt; folder for some reason. With Vercel, I have seen that it gets discarded when you do package upgrades (&lt;code&gt;package-lock.json&lt;/code&gt; gets updated).&lt;/p&gt;
&lt;p&gt;There is an &lt;a href=&quot;https://github.com/11ty/eleventy-img/issues/285&quot;&gt;open issue on the &lt;code&gt;eleventy-image&lt;/code&gt; github repo&lt;/a&gt; which lists the exact workaround. Hop in there if you face any issues.&lt;/p&gt;
&lt;h2 id=&quot;11ty-fetch-plugin-exception&quot; tabindex=&quot;-1&quot;&gt;Eleventy&#39;s Fetch Plugin Errors Out If A Cache File Is Missing&lt;/h2&gt;
&lt;p&gt;I recently encountered an issue (&lt;a href=&quot;https://github.com/11ty/eleventy-img/issues/285#issuecomment-2723912288&quot;&gt;&lt;code&gt;ENOENT: no such file or directory, open &#39;/vercel/path0/.cache/eleventy-fetch-fbe00b3353051d063b093fb7cd28fe.buffer&#39;&lt;/code&gt;&lt;/a&gt;) where Vercel was removing buffer files randomly from the &lt;code&gt;.cache&lt;/code&gt; directory, and that lead to an unhandled exception in &lt;a href=&quot;https://github.com/11ty/eleventy-fetch&quot;&gt;@11ty/eleventy-fetch&lt;/a&gt; package which is used internally by the @11ty/eleventy-img plugin.&lt;/p&gt;
&lt;p&gt;Vercel doesn&#39;t guarantee or allow me to &lt;a href=&quot;https://vercel.com/docs/deployments/troubleshoot-a-build#managing-build-cache:~:text=It%20is%20not%20possible%20to%20manually%20configure%20which%20files%20are%20cached%20at%20this%20time.&quot;&gt;configure which files are cached across builds&lt;/a&gt; and which are not, so it&#39;s hard to say why the issue was happening. However, you can overcome this issue by switching to &lt;a href=&quot;https://github.com/11ty/eleventy-fetch/releases/tag/v5.1.0-beta.2&quot;&gt;@11ty/eleventy-fetch v5.1.0-beta.2&lt;/a&gt; — this release includes the handling of a missing but valid cache.&lt;/p&gt;
&lt;p&gt;Note that, @11ty/eleventy-fetch is a package used by @11ty/eleventy-img internally and comes pre-bundled with it, and so it doesn&#39;t include the beta version of eleventy-fetch. To resolve this issue, you must override the @11ty/eleventy-fetch package version in package.json file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// package.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;overrides&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        &quot;@11ty/eleventy-fetch&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;5.1.0-beta.2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Read &lt;a href=&quot;https://github.com/11ty/eleventy-img/issues/285&quot;&gt;this discussion&lt;/a&gt; for more information about this issue.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/eleventy-image-html-transform-plugin-disk-cache/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Claude 3.7 Sonnet, OpenAI&#39;s GPT 4.5 and Microsoft&#39;s Quantum Chip</title>
    <link href="https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/"/>
    <published>2025-03-03T03:44:51Z</published>
    <updated>2025-03-07T14:00:43Z</updated>
    <id>https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;This week was bonkers in terms of tech announcements in the field of AI and quantum computing.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Anthropic announced its latest and best Claude model yet — Claude 3.7 Sonnet on February 25, 2025.&lt;/li&gt;
&lt;li&gt;OpenAI jumped on the bandwagon and announced GPT 4.5 — its latest and largest model on February 27, 2025.&lt;/li&gt;
&lt;li&gt;To make things more interesting, Microsoft unveiled its first quantum chip — Majorana 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;claude-3.7-sonnet-and-claude-code&quot; tabindex=&quot;-1&quot;&gt;Claude 3.7 Sonnet and Claude Code&lt;/h2&gt;
&lt;p&gt;Anthropic leveled up their game by introducing Claude 3.7 Sonnet and &lt;a href=&quot;https://x.com/lexfridman/status/1894116700070481985&quot;&gt;people are satisfied&lt;/a&gt; with it. It&#39;s a reasoning model with thinking capabilities which works almost every time. Some &lt;a href=&quot;https://x.com/catalinmpit/status/1895062658703048716&quot;&gt;users are not satisfied with it because of prompting issues&lt;/a&gt;, but I think you can get away with it by tweaking your prompt.&lt;/p&gt;
&lt;p&gt;Claude 3.7 Sonnet is priced at $3 per million input tokens and $15 per million output tokens — including reasoning tokens.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1740934340/Syntackle/Posts/Screenshot_2025-03-02_at_10.20.24_PM_oenwry.png&quot; alt=&quot;claude 3.7 sonnet SWE benchmarks&quot; height=&quot;1208&quot; width=&quot;1868&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://www.anthropic.com/news/claude-3-7-sonnet&quot;&gt;anthropic.com&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Along with Claude 3.7 Sonnet, Anthropic also announced its new product &amp;quot;Claude Code&amp;quot; — a CLI tool to assist you locally in your project. It can create/edit files, debug, fix/write tests, work with git to commit and create PRs, and provide suggestions based on your repository. More like cursor, but inside terminal.&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;AJpK3YTTKZ4&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;However, it comes with certain technical overhead. Here are the minimum requirements to run Claude Code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimum 4 gigs (GB) of RAM&lt;/li&gt;
&lt;li&gt;Internet Connectivity&lt;/li&gt;
&lt;li&gt;Supports macOS 10.15+ and Ubuntu 20.04+/Debian 10+. For Windows, it requires WSL (Windows Subsystem For Linux).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that it&#39;s in research preview. File any bugs you find on their &lt;a href=&quot;https://github.com/anthropics/claude-code&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;openai&#39;s-gpt-4.5&quot; tabindex=&quot;-1&quot;&gt;OpenAI&#39;s GPT-4.5&lt;/h2&gt;
&lt;p&gt;OpenAI claims GPT-4.5 is their largest and expensive model yet. And yes, at $200 a month, it&#39;s crazy expensive. The API pricing for GPT-4.5 is also expensive, with $75 per million input tokens and a whopping $150 per million output tokens. But, does it stay true to its pricing?&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1740973993/Syntackle/Posts/Screenshot_2025-03-03_at_9.22.48_AM_kq14qr.png&quot; alt=&quot;openai&#39;s GPT 4.5 API pricing&quot; height=&quot;1072&quot; width=&quot;1752&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: openai.com/api/pricing&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;I haven&#39;t personally tried it yet, but having read first impressions from people who tried it on X (twitter), it seems to me that GPT 4.5 really good at creative tasks such as &lt;a href=&quot;https://x.com/theo/status/1895221872540950818&quot;&gt;writing&lt;/a&gt;, but &lt;a href=&quot;https://x.com/theo/status/1895220930173116747&quot;&gt;not so good at coding&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Just like Claude Code, GPT-4.5 is still in research preview, so it may get better over time.&lt;/p&gt;
&lt;h2 id=&quot;microsoft&#39;s-majorana-1&quot; tabindex=&quot;-1&quot;&gt;Microsoft&#39;s Majorana 1&lt;/h2&gt;
&lt;p&gt;With the unveiling of Majorana 1 — Microsoft&#39;s Quantum Chip, Microsoft is now in the game of quantum supremacy along with Google and IBM.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1740971632/Syntackle/Posts/Screenshot_2025-03-03_at_8.42.58_AM_u2r851.png&quot; alt=&quot;microsoft&#39;s new quantum chip — majorana 1&quot; height=&quot;522&quot; width=&quot;998&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://azure.microsoft.com/en-us/blog/quantum/2025/02/19/microsoft-unveils-majorana-1-the-worlds-first-quantum-processor-powered-by-topological-qubits/&quot;&gt;azure.microsoft.com&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Microsoft claims to have achieved quantum breakthrough by discovering a new state of matter known as topological superconductivity.&lt;/p&gt;
&lt;p&gt;Majorana 1 works with &lt;a href=&quot;https://quantum.microsoft.com/en-us/insights/education/concepts/topological-qubits&quot;&gt;&amp;quot;topological qubits&amp;quot;&lt;/a&gt; which store information in topological properties of a physical system, instead of properties of a single particle.&lt;/p&gt;
&lt;p&gt;I am more interested in seeing the practical use cases of it, especially in the world of AI. The integration of quantum computing with the AI world is yet to be seen.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/claude-3-7-sonnet-openai-gpt-4-5-majorana-1/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Leveraging Deep Research by Building Your Online Presence</title>
    <link href="https://syntackle.com/blog/leveraging-deep-research-by-building-an-online-presence/"/>
    <published>2025-02-23T09:02:48Z</published>
    <updated>2025-02-23T09:45:24Z</updated>
    <id>https://syntackle.com/blog/leveraging-deep-research-by-building-an-online-presence/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Deep research is one of the aspects AI companies are willing to implement and integrate with their current AI systems. The use cases of deep research are massive in nature — medical research, general knowledge, biography, finding something you don&#39;t remember but have enough context about it, statistical analysis — and it saves you a lot of time skimming through countless articles to generate a comprehensive report.&lt;/p&gt;
&lt;p&gt;One such use case can be in the recruitment industry where, in my opinion, if a recruiter finds a profile relevant enough, they can go to an &lt;a href=&quot;https://syntackle.com/blog/deepseek-ai-model-and-openrouter/&quot;&gt;AI&lt;/a&gt; platform, use deep research to get a biography of that individual and take it from there. This only works if that person has a strong online presence or has done something meaningful and put it out there on the internet.&lt;/p&gt;
&lt;p&gt;That brings me to my next point, i.e. building an online presence in the world of AI.&lt;/p&gt;
&lt;h2 id=&quot;building-your-online-presence&quot; tabindex=&quot;-1&quot;&gt;Building Your Online Presence&lt;/h2&gt;
&lt;p&gt;I come from a software development background, and if I talk about the software industry taking into consideration its current landscape, I think we are going to see such cases where a strong online presence can land you a decent job.&lt;/p&gt;
&lt;p&gt;The question is, how to build an online presence in the first place? It&#39;s actually quite simple. Here are some of the steps which you can take to establish yourself on the internet.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Share what you find interesting.&lt;/li&gt;
&lt;li&gt;Start a &lt;a href=&quot;https://syntackle.com/write/&quot;&gt;blog&lt;/a&gt; of your own.&lt;/li&gt;
&lt;li&gt;Build tools which saved you a ton of time and open source them so that they can do the same for others.&lt;/li&gt;
&lt;li&gt;Share what you learn and how that helped you to grow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;deep-researching-yourself&quot; tabindex=&quot;-1&quot;&gt;Deep Researching Yourself&lt;/h2&gt;
&lt;p&gt;Once you build a good enough online presence, go to any of the AI platforms, be it Grok, Perplexity, or OpenAI, and search about yourself and see what information the AI model has gathered for you.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.perplexity.ai/hub/blog/introducing-perplexity-deep-research&quot;&gt;Perplexity&lt;/a&gt;, &lt;a href=&quot;https://x.ai/blog/grok-3&quot;&gt;xAI&#39;s Grok 3&lt;/a&gt;, and &lt;a href=&quot;https://openai.com/index/introducing-deep-research/&quot;&gt;OpenAI&#39;s ChatGPT&lt;/a&gt;, all have integrated the deep research (deep search) functionality and they do pretty well.&lt;/p&gt;
&lt;p&gt;I used perplexity&#39;s deep research functionality to research about myself and it does a good job of summarizing you based on what you put out there:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1740297196/Syntackle/Posts/Screenshot_2025-02-23_at_1.22.11_PM_n2xden.png&quot; alt=&quot;deep research about murtuzaali surti using perplexity ai&quot; height=&quot;1288&quot; width=&quot;990&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://www.perplexity.ai/search/who-is-murtuzaali-surti-Ke_Ax8fdRRCbDDngbkA80Q&quot;&gt;perplexity.ai&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;the-future-of-recruiting&quot; tabindex=&quot;-1&quot;&gt;The Future Of Recruiting&lt;/h2&gt;
&lt;p&gt;In my opinion, companies might start integrating deep research functionalities of platforms such as Grok, Perplexity, OpenAI, etc. and use them to do a quick research about the person that they are willing to hire. Now I am not sure up to what extent they might use it but I see at least some use of it in the near future.&lt;/p&gt;
&lt;p&gt;Similarly, you as a candidate can also research about the company you are interested in using deep research. It&#39;ll help you know if you are a right fit for that company, or if the company is a right fit for you. It works both ways.&lt;/p&gt;
&lt;h2 id=&quot;the-flip-side&quot; tabindex=&quot;-1&quot;&gt;The Flip Side&lt;/h2&gt;
&lt;p&gt;On the other hand, it&#39;s important to not overshare yourself on the internet as these same tools can backfire knowing an awful lot about you including the information that you don&#39;t want to share. And that&#39;s not completely on you, that&#39;s also on these companies — they must ensure they don&#39;t give up any of the personal information about someone, and I guess that&#39;s where we get into a grey area where we have to decide what&#39;s shareable and what&#39;s not.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/leveraging-deep-research-by-building-an-online-presence/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Create React App (CRA) is Deprecated, Officially: What&#39;s Next?</title>
    <link href="https://syntackle.com/blog/create-react-app-deprecated/"/>
    <published>2025-02-15T11:28:58Z</published>
    <updated>2025-10-18T09:59:24Z</updated>
    <id>https://syntackle.com/blog/create-react-app-deprecated/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Create React App a.k.a CRA is a tool (setup tool I would say) which provides an opinionated architecture combining a set of tools required to configure, transpile JSX and bundle React.&lt;/p&gt;
&lt;p&gt;React team announced the &lt;a href=&quot;https://react.dev/blog/2025/02/14/sunsetting-create-react-app&quot;&gt;deprecation of Create React App&lt;/a&gt; on February 14, 2025. Before it was official, CRA was already considered a &amp;quot;no-longer-to-be-used&amp;quot; tool to build modern React applications. The disadvantages of using create-react-app kept increasing with the advent of new tools which were faster and efficient.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1739618490/Syntackle/Posts/Screenshot_2025-02-15_at_4.50.20_PM_q2wp5l.png&quot; alt=&quot;create react app deprecation warning&quot; height=&quot;602&quot; width=&quot;1562&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: github.com/facebook/create-react-app&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;limitations&quot; tabindex=&quot;-1&quot;&gt;Limitations Of Create React App (CRA)&lt;/h2&gt;
&lt;p&gt;One limitation of using &lt;a href=&quot;https://github.com/facebook/create-react-app&quot;&gt;&amp;quot;Create React App&amp;quot;&lt;/a&gt; is that whenever you want to have full control of the build process and do some advanced customizations to the bundler used by it i.e. Webpack, you have to eject the CRA. In other words, you are now out of the default setup of the CRA, and you now have to manually handle everything &lt;em&gt;(that&#39;s a pain — not to mention rewiring packages like &lt;a href=&quot;https://github.com/timarney/react-app-rewired&quot;&gt;react-app-rewired&lt;/a&gt; and &lt;a href=&quot;https://github.com/dilanx/craco&quot;&gt;craco&lt;/a&gt;)&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Find a complete list of &lt;a href=&quot;https://react.dev/blog/2025/02/14/sunsetting-create-react-app#limitations-of-create-react-app&quot;&gt;Create React App limitations&lt;/a&gt; on the React Blog which includes data fetching, code splitting and more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;alternatives&quot; tabindex=&quot;-1&quot;&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;The alternatives of CRA are not only better but faster and efficient. I stopped using Create React App for my personal projects a long time ago and also migrated my old projects which were built using &lt;a href=&quot;https://www.robinwieruch.de/vite-create-react-app/&quot;&gt;CRA to Vite&lt;/a&gt;. Yes, &lt;a href=&quot;https://vite.dev/guide/#scaffolding-your-first-vite-project:~:text=vue%2Dts%2C-,react,-%2C%20react%2Dts&quot;&gt;Vite&lt;/a&gt; is a worthy alternative to build and run React applications.&lt;/p&gt;
&lt;p&gt;If you have a legacy application built using CRA, then I suggest you migrate to one of the below options as soon as possible, but note that it can take a while depending on the size of your project.&lt;/p&gt;
&lt;h3 id=&quot;1.-vite&quot; tabindex=&quot;-1&quot;&gt;1. Vite&lt;/h3&gt;
&lt;p&gt;Vite uses Rollup and ESbuild to bundle the React application. It is much much faster than Webpack which is used by Create React App as a bundler. Also, Vite&#39;s configuration API is simple and easy to understand. Vite claims to be a framework agnostic tool which can be used to build any framework on top of it.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://vite.dev/guide/why.html&quot;&gt;Why Vite&lt;/a&gt;? — vite.dev&lt;/p&gt;
&lt;p&gt;Vite team introduced &lt;a href=&quot;https://syntackle.com/blog/vite-7-is-here/&quot;&gt;&amp;quot;Vite+&amp;quot;&lt;/a&gt; (a superset of Vite) in Amsterdam ViteConf on October 13, 2025. It is in its development phase right now, with a preview scheduled to be released in early 2026, but &lt;a href=&quot;https://tally.so/r/nGWebL&quot;&gt;early access&lt;/a&gt; registrations are open.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;2.-tanstack-start&quot; tabindex=&quot;-1&quot;&gt;2. Tanstack Start&lt;/h3&gt;
&lt;p&gt;Tanstack Start is a framework, an alternative to Next.js, which combines tools from the Tanstack ecosystem such as Tanstack Router and Tanstack Query, and it&#39;s built on top of Vite.&lt;/p&gt;
&lt;p&gt;Tanstack Start is currently in the &lt;a href=&quot;https://tanstack.com/blog/announcing-tanstack-start-v1&quot;&gt;&amp;quot;RC (release candidate)&amp;quot;&lt;/a&gt; stage, with v1 dropping soon. The primary focus is on type-safe file-based routing, isomorphic server functions, URL-as-state, and RSC (React Server Components) support.&lt;/p&gt;
&lt;p&gt;RSC (React Server Components) will not be a part of Tanstack Start v1 RC, but it is in active development and will be released as a later v1 minor (v1.x) version release.&lt;/p&gt;
&lt;h3 id=&quot;nextjs&quot; tabindex=&quot;-1&quot;&gt;3. Next.js&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://nextjs.org/learn&quot;&gt;Next.js&lt;/a&gt; by Vercel is a full-fledged framework built on top on React which provides it&#39;s own routing, data fetching patterns, optimization techniques, bundler (turbopack), compiler and much more. With the introduction of Server Components, React kept pushing hard on using Next.js for building modern React applications because of its support and implementation of React Server Components.&lt;/p&gt;
&lt;p&gt;If you want to build a complex React application with a focus on React Server Components and you are okay with the techniques and patterns used by Next.js, then you are good to go with it.&lt;/p&gt;
&lt;h3 id=&quot;4.-expo&quot; tabindex=&quot;-1&quot;&gt;4. Expo&lt;/h3&gt;
&lt;p&gt;If you want to build cross-platform native applications (runs on iOS, Android and the Web) using React Native, then Expo (an open-source framework) is the way to go.&lt;/p&gt;
&lt;h3 id=&quot;5.-create-tsrouter-app-(tanstack)&quot; tabindex=&quot;-1&quot;&gt;5. create-tsrouter-app (Tanstack)&lt;/h3&gt;
&lt;p&gt;If you love Tanstack ecosystem, &lt;a href=&quot;https://bsky.app/profile/tannerlinsley.com&quot;&gt;Tanner Linsley&lt;/a&gt; (Creator of Tanstack) suggests using &lt;a href=&quot;https://www.npmjs.com/package/create-tsrouter-app&quot;&gt;&lt;code&gt;create-tsrouter-app&lt;/code&gt;&lt;/a&gt; which comes bundled with Tanstack router and React Query (Tanstack Query).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1739689443/Syntackle/Posts/Screenshot_2025-02-16_at_12.33.11_PM_nepsao.png&quot; alt=&quot;create react app deprecation warning&quot; height=&quot;1196&quot; width=&quot;956&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: bsky.app&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;thoughts&quot; tabindex=&quot;-1&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;In the deprecation blog released by the React team, they emphasized on using frameworks built on top of &lt;a href=&quot;https://syntackle.com/blog/form-handling-in-react-19/&quot;&gt;React&lt;/a&gt; which do things in their own opinionated way. I don&#39;t know if it&#39;s good or bad, but too much reliance on a framework can sometimes feel restrictive because you cannot do anything outside of which your framework allows you to.&lt;/p&gt;
&lt;p&gt;That&#39;s why, for building small React applications, I would consider letting go of the overhead of frameworks and start with a tool like Vite, do routing with React Router, manage complex state with Redux Toolkit or Zustand, and implement data fetching with something like React Query (Tanstack Query).&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/create-react-app-deprecated/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to Use DeepSeek-R1 AI Model: A Comprehensive Guide</title>
    <link href="https://syntackle.com/blog/deepseek-ai-model-and-openrouter/"/>
    <published>2025-02-04T16:56:24Z</published>
    <updated>2025-03-01T05:45:23Z</updated>
    <id>https://syntackle.com/blog/deepseek-ai-model-and-openrouter/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;DeepSeek&#39;s AI model &amp;quot;DeepSeek-R1&amp;quot; (a.k.a deepseek-reasoner) is the most talked about AI model at the time of this writing. I recently integrated it with &lt;a href=&quot;https://github.com/murtuzaalisurti/better&quot;&gt;better&lt;/a&gt; — a code reviewer github action powered by AI — which I developed during a hackathon.&lt;/p&gt;
&lt;p&gt;In this guide, I will walk you through ways in which you can integrate deepseek models in your tools and also talk about structured JSON outputs.&lt;/p&gt;
&lt;p&gt;[&lt;strong&gt;TLDR&lt;/strong&gt; — For JSON outputs with stick to a given schema, along with specifying the &lt;code&gt;response_format&lt;/code&gt; as &lt;code&gt;json_object&lt;/code&gt; and explicitly specifying the word JSON in the prompt, append the following prompt in your use prompt for better and consistent json outputs: &amp;quot;IMP: give the output in a valid JSON string (it should be not be wrapped in markdown, just plain json object) and stick to the schema mentioned here: &lt;code&gt;&amp;lt;json_schema&amp;gt;&lt;/code&gt;&amp;quot;.]&lt;/p&gt;
&lt;h2 id=&quot;using-deepseek&#39;s-api&quot; tabindex=&quot;-1&quot;&gt;Using DeepSeek&#39;s API&lt;/h2&gt;
&lt;p&gt;The primary way to use any of the deepseek AI models is to go to their API platform, get an API key and use the &lt;a href=&quot;https://github.com/openai/openai-node&quot;&gt;OpenAI SDK&lt;/a&gt; to make calls to the API.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;DeepSeek&#39;s API is compatible with OpenAI SDK (it&#39;s available for &lt;a href=&quot;https://github.com/openai/openai-python&quot;&gt;python&lt;/a&gt; and &lt;a href=&quot;https://github.com/openai/openai-node&quot;&gt;javascript&lt;/a&gt; both).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The problem with this is, currently at the time of this writing, DeepSeek&#39;s API platform &lt;s&gt;is &lt;a href=&quot;https://status.deepseek.com/&quot;&gt;down&lt;/a&gt; (throwing a 503 service unavailable)&lt;/s&gt; is up, but they have disabled API recharges for now — you can use your existing balance to use paid models. [&lt;strong&gt;UPDATE&lt;/strong&gt;: &lt;em&gt;DeepSeek has enabled new API subscriptions/recharges now.&lt;/em&gt;] And that forced me to go another route which involves &lt;a href=&quot;https://openrouter.ai/&quot;&gt;OpenRouter&lt;/a&gt; — which basically routes your request to appropriate providers for the model you specify.&lt;/p&gt;
&lt;p&gt;If you do have existing balance in your DeepSeek account to use &lt;code&gt;deepseek-r1&lt;/code&gt;, you can use OpenAI&#39;s SDK with your &lt;a href=&quot;https://platform.deepseek.com/api_keys&quot;&gt;DeepSeek API key&lt;/a&gt; and change the &lt;code&gt;base_url&lt;/code&gt; to &lt;code&gt;https://api.deepseek.com&lt;/code&gt;. Note that the alias for &lt;code&gt;deepseek-r1&lt;/code&gt; is &lt;code&gt;deepseek-reasoner&lt;/code&gt; when interacting with DeepSeek&#39;s API.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    apiKey&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&amp;#x3C;deepseek-api-key&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    baseURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://api.deepseek.com&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;completions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;deepseek-reasoner&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&amp;#x3C;the-system-prompt&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&amp;#x3C;user-prompt&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;choices&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;using-openrouter&quot; tabindex=&quot;-1&quot;&gt;Using OpenRouter&lt;/h2&gt;
&lt;p&gt;OpenRouter too is compatible with the OpenAI SDK — you just have to change the base URL. That&#39;s genius because it makes the adoption rate go high. To use any of the models through OpenRouter, you need to generate an &lt;a href=&quot;https://openrouter.ai/settings/keys&quot;&gt;API key&lt;/a&gt; from their platform. And, credits need to be loaded for you to be able to use any of the paid AI models.&lt;/p&gt;
&lt;p&gt;There&#39;s also a free version of deepseek-r1 model, named &lt;a href=&quot;https://openrouter.ai/deepseek/deepseek-r1:free&quot;&gt;&lt;code&gt;deepseek/deepseek-r1:free&lt;/code&gt;&lt;/a&gt;, available on OpenRouter. Good option if you want to just try it out.&lt;/p&gt;
&lt;p&gt;Once you get the API key, initialize the OpenAI SDK and implement it as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openai&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; OpenAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    apiKey&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&amp;#x3C;open-router-api-key&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    baseURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://openrouter.ai/api/v1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;completions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;deepseek/deepseek-r1&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&amp;#x3C;the-system-prompt&gt;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&amp;#x3C;user-prompt&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;choices&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The best thing about OpenRouter is if you append &lt;strong&gt;&lt;code&gt;:floor&lt;/code&gt;&lt;/strong&gt; to any model name (e.g. deepseek/deepseek-r1:floor), you can get the &lt;a href=&quot;https://openrouter.ai/docs/features/provider-routing#floor-price-shortcut&quot;&gt;cheapest price in the market for that model&lt;/a&gt;. This is done by sorting the providers of that model. It is the same as setting &lt;code&gt;provider.sort&lt;/code&gt; to &lt;code&gt;price&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;structured-json-output&quot; tabindex=&quot;-1&quot;&gt;Structured JSON Output&lt;/h2&gt;
&lt;p&gt;I was experimenting with the deepseek-r1 model to make it produce an output which sticks to a schema. It seems that you have to do more than just define a &lt;code&gt;response_format&lt;/code&gt; as &lt;code&gt;json_object&lt;/code&gt;. I got it working by specifying the following as a part of the user prompt:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&amp;#x3C;primary_prompt&gt; - IMP: give the output in a valid JSON string (it should be not be wrapped in markdown, just plain json object) and stick to the schema mentioned here: &amp;#x3C;json_schema&gt;.`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then specifying the &lt;code&gt;response_format&lt;/code&gt; as &lt;code&gt;json_object&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;completions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;deepseek/deepseek-r1&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;the-system-prompt&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&amp;#x3C;primary_prompt&gt; - IMP: give the output in a valid JSON string (it should be not be wrapped in markdown, just plain json object) and stick to the schema mentioned here: &amp;#x3C;json_schema&gt;.`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    response_format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_object&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the model might generate empty content sometimes according to the official documentation. So, try to implement a retry mechanism to mitigate this problem.&lt;/p&gt;
&lt;h2 id=&quot;using-deepseek-in-a-vscode-extension&quot; tabindex=&quot;-1&quot;&gt;Using DeepSeek in a VSCode Extension&lt;/h2&gt;
&lt;p&gt;In my opinion, the best VSCode extension you can use deepseek-r1 with is &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#cline&quot;&gt;Cline&lt;/a&gt;. The most useful thing about this extension is its plan-then-act mode which when in planning mode, gives you suggestions and approaches you can try. And then, when you switch to act mode, it implements and refactors the actual code. I have talked more about Cline in my VSCode &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/&quot;&gt;extensions 2025 list&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev&quot;&gt;Install&lt;/a&gt; the Cline extension.&lt;/li&gt;
&lt;li&gt;Select a deepseek model (&lt;strong&gt;deepseek-reasoner&lt;/strong&gt; for &lt;strong&gt;deepseek-r1&lt;/strong&gt;) and a provider like OpenRouter or DeepSeek as shown below.&lt;/li&gt;
&lt;li&gt;Provide the API key and start using the extension. 👇&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1738860609/Syntackle/Posts/Screen_Cast_2025-02-06_at_10.18.49_PM_nrhnla.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;deepseek model with a vscode extension named cline&quot; height=&quot;1444&quot; width=&quot;672&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;running-it-locally&quot; tabindex=&quot;-1&quot;&gt;Running it locally&lt;/h2&gt;
&lt;p&gt;If you have enough computing power to run deepseek-r1 locally, you can do that using &lt;a href=&quot;https://ollama.com/&quot;&gt;Ollama&lt;/a&gt;. Here&#39;s a &lt;a href=&quot;https://www.datacamp.com/tutorial/deepseek-r1-ollama&quot;&gt;quick guide by DataCamp to run deepseek-r1 locally&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/deepseek-ai-model-and-openrouter/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>React Compiler Integration With Astro (Vite)</title>
    <link href="https://syntackle.com/blog/integrating-react-compiler-with-astro/"/>
    <published>2025-01-26T18:49:40Z</published>
    <updated>2025-10-11T16:14:09Z</updated>
    <id>https://syntackle.com/blog/integrating-react-compiler-with-astro/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;&lt;a href=&quot;https://react.dev/learn/react-compiler&quot;&gt;React compiler&lt;/a&gt; was introduced to tackle massive re-rendering issues within a react application. What it does is that it looks at the code and figures out if a certain component or a value can be memoized or not to limit its re-rendering. Does that mean you should not use &lt;code&gt;useCallback()&lt;/code&gt;, &lt;code&gt;useMemo()&lt;/code&gt; or &lt;code&gt;React.memo()&lt;/code&gt; from now? Not really.&lt;/p&gt;
&lt;p&gt;You should do manual memoization wherever you are certain that you don&#39;t want to re-render a particular component or value until something changes. React compiler is more of a safeguard in case you forgot to memoize something which should be memoized.&lt;/p&gt;
&lt;p&gt;Now that I gave a shallow explanation of what the react compiler is and what it does, let me tell you how to integrate it with an Astro project which uses React components.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;React Compiler &lt;a href=&quot;https://react.dev/learn/react-compiler#what-kind-of-memoization-does-react-compiler-add&quot;&gt;Deep Dive&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;installing-react-compiler&quot; tabindex=&quot;-1&quot;&gt;Installing React Compiler&lt;/h2&gt;
&lt;p&gt;React compiler is compatible with versions of React above 17 and is &lt;a href=&quot;https://react.dev/blog/2025/10/07/react-compiler-1&quot;&gt;stable&lt;/a&gt; (v1 was released on Oct 7, 2025). It is available as a babel plugin, so to install it, install the &lt;code&gt;babel-plugin-react-compiler&lt;/code&gt; package:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; babel-plugin-react-compiler@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For folks who are not yet on React 19 and are using versions 17 or 18, you need to install one more package named &lt;code&gt;react-compiler-runtime@latest&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; react-compiler-runtime@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;integrating-with-astro&quot; tabindex=&quot;-1&quot;&gt;Integrating with Astro&lt;/h2&gt;
&lt;p&gt;Once you install the compiler, go to the astro config file (usually &lt;code&gt;astro.config.mjs&lt;/code&gt;) and add the babel plugin to the &lt;code&gt;@astrojs/react&lt;/code&gt; package.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; react&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;@astrojs/react&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// https://astro.build/config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  integrations&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;react&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    babel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;babel-plugin-react-compiler&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  })],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For React 17+ users, after installing the &lt;code&gt;react-compiler-runtime@latest&lt;/code&gt; package, you need to set a target key in the compiler config. Set it to the major version of React which you are using.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; react&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;@astrojs/react&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; compilerConfig&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  target&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;19&#39;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // can be &#39;17&#39; | &#39;18&#39; | &#39;19&#39;, default is 19&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// https://astro.build/config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  integrations&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;react&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    babel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // make sure this is first in the plugins list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;babel-plugin-react-compiler&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;compilerConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  })],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s it, react compiler is now integrated with Astro. You can follow a similar approach to integrate react compiler with any frameworks which use Vite. You just need to add the babel plugin to the react adapter/plugin you are using for Vite.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;If you are using &lt;code&gt;vite&lt;/code&gt; + &lt;code&gt;react&lt;/code&gt; via the &lt;code&gt;@vitejs/plugin-react&lt;/code&gt; package with no meta-framework, you can configure the compiler in a similar way in vite&#39;s config file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// vite.config.{js,ts}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;vite&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; react&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;@vitejs/plugin-react&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; compilerConfig&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  target&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;19&#39;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // can be &#39;17&#39; | &#39;18&#39; | &#39;19&#39;, default is 19&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    react&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      babel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;babel-plugin-react-compiler&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;compilerConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;linting-with-eslint&quot; tabindex=&quot;-1&quot;&gt;Linting with ESLint&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;eslint-plugin-react-hooks&lt;/code&gt; provides rules for identifying violations of the Rules of React.&lt;/p&gt;
&lt;blockquote class=&quot;&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;When the ESLint rule reports an error, it means the compiler will skip optimizing that specific component or hook. - &lt;a href=&quot;https://react.dev/learn/react-compiler/installation&quot;&gt;react.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Install the eslint plugin and configure it based on your eslint config as documented &lt;a href=&quot;https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation&quot;&gt;here in the react repository docs&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -D&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; eslint-plugin-react-hooks@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;Want to check the performance post integration? That can be done using a package named &lt;a href=&quot;https://github.com/aidenybai/react-scan&quot;&gt;&lt;code&gt;react-scan&lt;/code&gt;&lt;/a&gt; by &lt;a href=&quot;https://github.com/aidenybai&quot;&gt;Aiden Bai&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Add the script tag in your index layout file and it will be ready to use.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;doctype&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;myai&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;width=device-width&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;generator&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;{Astro.generator}&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://unpkg.com/react-scan/dist/auto.global.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;{title}&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/integrating-react-compiler-with-astro/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>11 VSCode Extensions I Use [2025]</title>
    <link href="https://syntackle.com/blog/vscode-extensions-2025/"/>
    <published>2025-01-25T17:59:39Z</published>
    <updated>2025-04-04T18:01:18Z</updated>
    <id>https://syntackle.com/blog/vscode-extensions-2025/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 MD034 --&gt;
&lt;p&gt;Visual Studio Code (VSCode) is an editor which is simple on it&#39;s own but enriched when combined with extensions. So, in this article, I will tell you some vscode extensions I personally use which might be beneficial to you.&lt;/p&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;blockquote&gt;
&lt;p&gt;Download &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cline&quot; tabindex=&quot;-1&quot;&gt;1. Cline &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#cline&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev&quot;&gt;Cline&lt;/a&gt; is the best vscode extension for AI assistance. What I like about it the most is it&#39;s plan-then-act mode. While it plans (in plan mode), it walks you through the steps showing what&#39;s possible and what&#39;s not. Once you agree with the approach, switch to the act mode wherein it implements that approach in your editor.&lt;/p&gt;
&lt;p&gt;That&#39;s good because unlike other AI coding assistants, it gives you the time to think and then implement. It does not churn out code for you instantly — that&#39;s helpful if you want to implement an approach yourself before letting AI do it.&lt;/p&gt;
&lt;p&gt;Not only that, it also shows the tokens and the usage cost, which for me is incredibly helpful to track how much I use each model.&lt;/p&gt;
&lt;p&gt;Here&#39;s a little demo for you to see it yourself.&lt;/p&gt;
&lt;p&gt;&lt;video controls=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;&lt;source src=&quot;https://res.cloudinary.com/dfue3cfts/video/upload/q_auto:eco/v1739002703/cline_dgyuzz.mp4&quot; /&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/p&gt;
&lt;h2 id=&quot;filesize&quot; tabindex=&quot;-1&quot;&gt;2. Filesize &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#filesize&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=mkxml.vscode-filesize&quot;&gt;Filesize&lt;/a&gt; is a simple extension which enables me to see the size of a file in VSCode&#39;s status bar. It&#39;s really handy if I want to see size of a build file (especially if I am dealing with javascript).&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737794524/Syntackle/Posts/Screenshot_2025-01-25_at_2.10.25_PM_s4q1x8.png&quot; alt=&quot;filesize vscode extension banner&quot; height=&quot;592&quot; width=&quot;1466&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://marketplace.visualstudio.com/&quot;&gt;visual studio marketplace&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;better-comments&quot; tabindex=&quot;-1&quot;&gt;3. Better Comments &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#better-comments&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments&quot;&gt;Better Comments&lt;/a&gt;, as the name suggests, allows me to tag my comments and colorize them according to the type. For example, if you specify &lt;code&gt;TODO:&lt;/code&gt; before a comment it will colorize it in yellow to indicate that this is pending. If a method is deprecated, I can use an exclamation mark to color it in red.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737796532/Syntackle/Posts/Screenshot_2025-01-25_at_2.45.12_PM_knv9ie.png&quot; alt=&quot;better comments vscode extension demo&quot; eleventy:ignore=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To customize the tags, I can edit this property the &lt;code&gt;settings.json&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;better-comments.tags&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;!&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;color&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#FF2D00&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;strikethrough&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;underline&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;backgroundColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;transparent&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;bold&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;italic&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;color&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#98C379&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;strikethrough&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;underline&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;backgroundColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;transparent&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;bold&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            &quot;italic&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;code-spell-checker&quot; tabindex=&quot;-1&quot;&gt;4. Code Spell Checker &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#code-spell-checker&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The use case of this &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker&quot;&gt;extension&lt;/a&gt; is reduced after the advent of AI extensions, but I still keep it around in case I misspell a variable unknowingly. The part where it shines is detection of camelCase or any other coding case words because it splits the words and then spells check them.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737797356/Syntackle/Posts/Screenshot_2025-01-25_at_2.58.50_PM_s61vpi.png&quot; alt=&quot;code spell checker vscode extension demo&quot; height=&quot;176&quot; width=&quot;838&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h2 id=&quot;git-graph&quot; tabindex=&quot;-1&quot;&gt;5. Git Graph &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#git-graph&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph&quot;&gt;Git Graph&lt;/a&gt; is one of those extensions which you definitely need of you don&#39;t want to pay for GitLens and other similar extensions. I use it because it&#39;s completely free and provides all of the useful insights about your git repo. It&#39;s a near perfect git extension.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737798249/Syntackle/Posts/Screenshot_2025-01-25_at_3.13.48_PM_z9lwgp.png&quot; alt=&quot;git graph vscode extension demo&quot; height=&quot;1428&quot; width=&quot;1030&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h2 id=&quot;markdownlint&quot; tabindex=&quot;-1&quot;&gt;6. Markdownlint &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#markdownlint&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I &lt;a href=&quot;https://syntackle.com/author/murtuzaalisurti/&quot;&gt;write&lt;/a&gt; blogs, and so &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint&quot;&gt;markdownlint&lt;/a&gt; is a useful extension for me as I write my posts in markdown. It&#39;s a decent extension allowing me to properly structure content inside a markdown file.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737823645/Syntackle/Posts/Screenshot_2025-01-25_at_10.16.16_PM_rulchq.png&quot; alt=&quot;markdownlint vscode extension banner&quot; height=&quot;580&quot; width=&quot;1586&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://marketplace.visualstudio.com/&quot;&gt;visual studio marketplace&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;total-typescript&quot; tabindex=&quot;-1&quot;&gt;7. Total Typescript &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#total-typescript&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is one of the most useful extensions if you are new to typescript and learning it while working on an existing project. &lt;a href=&quot;https://www.totaltypescript.com/vscode-extension&quot;&gt;Total Typescript&lt;/a&gt;&#39;s vscode extension annotates typescript keywords and operations, and when you hover over it, it describes what it is and how it can be used. For example, if there is a union of types, it will highlight that and provide a description upon hovering.&lt;/p&gt;
&lt;p&gt;Not only that, if there is a typescript error, it will try to explain it in a more meaningful and human readable way.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737824615/Syntackle/Posts/Screenshot_2025-01-25_at_10.32.21_PM_rgjjsv.png&quot; alt=&quot;total typescript vscode extension demo&quot; height=&quot;786&quot; width=&quot;1974&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h2 id=&quot;pretty-typescript-errors&quot; tabindex=&quot;-1&quot;&gt;8. Pretty TypeScript Errors &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#pretty-typescript-errors&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I recommend using this &lt;a href=&quot;https://github.com/yoavbls/pretty-ts-errors&quot;&gt;extension&lt;/a&gt; along with the above extension (i.e. total typescript extension). Why? Because not only do you get meaningful explanation of the error, you also get the error prettified and formatted nicely. If you haven&#39;t seen those ugly unformatted typescript errors yet, you will likely come across them in the future and you will get to know the importance of this extension.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737825374/Syntackle/Posts/Screenshot_2025-01-25_at_10.45.56_PM_gpfjkt.png&quot; alt=&quot;pretty typescript errors vscode extension demo&quot; height=&quot;688&quot; width=&quot;1338&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://github.com/yoavbls/pretty-ts-errors&quot;&gt;github.com/yoavbls/pretty-ts-errors&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;auto-rename-tag&quot; tabindex=&quot;-1&quot;&gt;9. Auto Rename Tag &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#auto-rename-tag&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I only listed this &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag&quot;&gt;extension&lt;/a&gt; to let you know that the functionality of Auto Rename Tag is now built in to VSCode. To turn on this feature, simply set the &lt;code&gt;editor.linkedEditing&lt;/code&gt; key to &lt;code&gt;true&lt;/code&gt; in your settings.json file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;editor.linkedEditing&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;sql-tools&quot; tabindex=&quot;-1&quot;&gt;10. SQL Tools &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#sql-tools&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I use &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools&quot;&gt;SQL Tools&lt;/a&gt; (a database management extension) only when I don&#39;t want to go outside of my editor to query a database and to perform simple operations and lookups. It allows me to connect to a specific database from within my editor but keep in mind that you need to install driver extensions separately in order to connect to a database.&lt;/p&gt;
&lt;p&gt;I don&#39;t recommend this extension for complex use cases. In that case, you can look for a standalone database management tool like pgAdmin or DBeaver.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1737826785/Syntackle/Posts/Screenshot_2025-01-25_at_11.09.29_PM_tdhnwd.png&quot; alt=&quot;sql tools vscode extension banner&quot; height=&quot;640&quot; width=&quot;1614&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://marketplace.visualstudio.com/&quot;&gt;visual studio marketplace&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;codeium-is-now-windsurf&quot; tabindex=&quot;-1&quot;&gt;11. Codeium (Windsurf) &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/#codeium-is-now-windsurf&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Codeium (now Windsurf) is an AI auto-completion and chat tool for coding similar to GitHub Copilot. At work I use GitHub Copilot, but for my personal projects &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=Codeium.codeium&quot;&gt;Codeium (now Windsurf)&lt;/a&gt; does a good enough job. I listed it here because it&#39;s free to use and provides features which are decent enough.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/v1743790492/Syntackle/Posts/Screenshot_2025-01-25_at_11.20.49_PM_xunbfr.png&quot; alt=&quot;codeium (windsurf) vscode extension banner&quot; height=&quot;730&quot; width=&quot;1852&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: &lt;a href=&quot;https://marketplace.visualstudio.com/&quot;&gt;visual studio marketplace&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Some more &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;visual studio code extensions&lt;/a&gt; which you should definitely try.&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/vscode-extensions-2025/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Issue With NVM Node Version Across Terminals: Command Node Not Found</title>
    <link href="https://syntackle.com/blog/nvm-node-issue-command-not-found/"/>
    <published>2025-01-12T09:41:54Z</published>
    <updated>2025-01-12T09:41:54Z</updated>
    <id>https://syntackle.com/blog/nvm-node-issue-command-not-found/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;If you use a unix based operating system like macOS or Linux, you might have encountered this issue with switching node versions with nvm - where if you do &lt;code&gt;nvm use &amp;lt;version&amp;gt;&lt;/code&gt;, the version is switched correctly in the current terminal shell, but if you try to use &lt;code&gt;node&lt;/code&gt; on a new terminal shell or in a different terminal, you get a command node not found error.&lt;/p&gt;
&lt;p&gt;I recently experienced this issue myself, and will try to consolidate the fixes here in this post as a reference to my future self as well as for all of you folks.&lt;/p&gt;
&lt;p&gt;First thing I did was, I checked the &lt;code&gt;~/.zprofile&lt;/code&gt; file on my system - for you it may be &lt;code&gt;~/.bash_profile&lt;/code&gt; or &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt; depending on your shell - and then moved the following lines at the bottom of the file, so that no other application overrides them. For me, it was VS Code, which was overriding the PATH variable at the end of the file. - &lt;a href=&quot;https://stackoverflow.com/a/47883587/17241798&quot;&gt;https://stackoverflow.com/a/47883587/17241798&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$HOME&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/.nvm&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[ &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/nvm.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ] &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;&#92;.&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/nvm.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  # This loads nvm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[ &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/bash_completion&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ] &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;&#92;.&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/bash_completion&quot;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  # This loads nvm bash_completion&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# -- end of file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second thing you should do is set the &lt;code&gt;default&lt;/code&gt; alias of nvm to a node version which you would like to use by default. I set it to &lt;code&gt;lts/*&lt;/code&gt; which is the latest long term support version of node. But before you do that, make sure you install the &lt;code&gt;lts/*&lt;/code&gt; version by running (&lt;a href=&quot;https://github.com/nvm-sh/nvm/issues/1217#issuecomment-471274995&quot;&gt;wrap lts/* in single quotes for zsh&lt;/a&gt;):&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nvm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;lts/*&#39;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # wrap lts/* in single quotes for zsh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;If you don&#39;t have it installed, you might run into:&lt;/p&gt;
&lt;p&gt;! WARNING: Version &#39;lts/*&#39; does not exist. default -&amp;gt; lts/* (-&amp;gt; N/A)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;And then, setting the &lt;code&gt;default&lt;/code&gt; alias:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nvm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; alias&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;lts/*&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, when you switch to a different node version using &lt;code&gt;nvm use&lt;/code&gt;, you can use the new version in the current terminal session (verify it by &lt;code&gt;node -v&lt;/code&gt;), but on a new terminal instance, it will fallback to the default node version you just set using the default alias.&lt;/p&gt;
&lt;h2 id=&quot;tldr&quot; tabindex=&quot;-1&quot;&gt;TLDR&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Go to your &lt;code&gt;~/.zprofile&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt; or &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt; file, locate these nvm lines, and move them at the end of the file:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$HOME&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/.nvm&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[ &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/nvm.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ] &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;&#92;.&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/nvm.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  # This loads nvm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[ &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/bash_completion&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ] &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;&#92;.&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;$NVM_DIR&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/bash_completion&quot;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  # This loads nvm bash_completion&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# -- end of file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Install the &lt;code&gt;lts/*&lt;/code&gt; node version by running:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nvm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;lts/*&#39;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # wrap lts/* in single quotes for zsh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Set the &lt;code&gt;default&lt;/code&gt; alias of nvm to a node version which you would like to use by default.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nvm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; alias&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;lts/*&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If any of the above solutions don&#39;t work, try uninstalling nvm and any other node version you have pre-installed and then re-install nvm. That should fix the issue.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/nvm-node-issue-command-not-found/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>App Defaults 2025 - with some AI stuff</title>
    <link href="https://syntackle.com/blog/best-apps-to-use-in-2025/"/>
    <published>2025-01-11T09:41:22Z</published>
    <updated>2025-01-11T10:47:20Z</updated>
    <id>https://syntackle.com/blog/best-apps-to-use-in-2025/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Continuing my spree of app &lt;strong&gt;defaults&lt;/strong&gt;, &lt;a href=&quot;https://syntackle.com/blog/app-defaults-2023-what-i-use-by-murtuzaali-surti-qhifV/&quot;&gt;which I started in 2023 with this post&lt;/a&gt;, here&#39;s a slightly changed list of all the apps I use and will probably keep using for the rest of 2025:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI Models/Chat Apps&lt;/strong&gt; - Claude 3.5 Sonnet (for coding), ChatGPT (for general use), Perplexity (for search)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📨 &lt;strong&gt;Mail Client&lt;/strong&gt; - Gmail&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📝 &lt;strong&gt;Notes&lt;/strong&gt; - Notion, Obsidian, &lt;a href=&quot;https://bear.app/&quot;&gt;Bear&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📆 &lt;strong&gt;Calendar&lt;/strong&gt; - Google Calendar&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📁 &lt;strong&gt;Cloud&lt;/strong&gt; - Google Cloud, OneDrive, Cloudinary (for images)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;strong&gt;RSS&lt;/strong&gt; - &lt;a href=&quot;https://www.goldenhillsoftware.com/unread/&quot;&gt;Unread&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌐 &lt;strong&gt;Browser&lt;/strong&gt; - Chrome (for daily use), Brave (private browsing), Arc (just to feel nice)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💬 &lt;strong&gt;Chat&lt;/strong&gt; - WhatsApp, Discord&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔖 &lt;strong&gt;Bookmarks&lt;/strong&gt; - &lt;a href=&quot;https://www.notion.so/web-clipper&quot;&gt;Notion Web Clipper&lt;/a&gt;, Chrome Bookmarks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🎤 &lt;strong&gt;Podcasts&lt;/strong&gt; - PocketCasts&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔐 &lt;strong&gt;Password Management&lt;/strong&gt; - &lt;a href=&quot;https://bitwarden.com/&quot;&gt;Bitwarden&lt;/a&gt; (still OG)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🧑‍💻 &lt;strong&gt;Code Editor&lt;/strong&gt; - VS Code, Cursor (for AI stuff), Zed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✈️ &lt;strong&gt;VPN&lt;/strong&gt; - ProtonVPN&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💸 &lt;strong&gt;Quick Financial Calculations&lt;/strong&gt; - &lt;a href=&quot;https://numbr.dev/&quot;&gt;numbr&lt;/a&gt; - useful for quick note taking with calculations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Some of my open source apps which I use regularly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/murtuzaalisurti/better&quot;&gt;better&lt;/a&gt; - AI-powered Code Reviewer GitHub Action&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/murtuzaalisurti/rssed&quot;&gt;rssed&lt;/a&gt; - RSS Feed Collection Of 150+ Developer Feeds&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/best-apps-to-use-in-2025/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>3 Steps To Think Like A Software Developer</title>
    <link href="https://syntackle.com/blog/looking-at-a-problem-as-a-developer/"/>
    <published>2024-12-31T07:46:22Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/looking-at-a-problem-as-a-developer/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;If someone were to ask me, what does a software engineer do on a basic level and what makes a good software engineer? I would say, problem solving. Yes, it’s the most basic and the most important skill to have as a software developer/engineer, yet most people don’t think about it before getting into software.&lt;/p&gt;
&lt;p&gt;But, it’s not that hard. In this post, I will list down three steps to better approach the problem given at hand, find the solution, and then improve upon it. It will also help you achieve a developer mindset.&lt;/p&gt;
&lt;h2 id=&quot;1.-break-it-down&quot; tabindex=&quot;-1&quot;&gt;1. Break it down&lt;/h2&gt;
&lt;p&gt;The first step to understand what’s going on is to understand it on a granular level. Given a complex problem, try to dissect it into smaller parts which are meaningful on their own, yet when put together, give you the final bigger picture.&lt;/p&gt;
&lt;p&gt;Think of it like the component architecture where everything is broken down into pieces which function on their own but also serves a higher purpose.&lt;/p&gt;
&lt;h2 id=&quot;2.-find-a-solution-that-just-works&quot; tabindex=&quot;-1&quot;&gt;2. Find a solution that just works&lt;/h2&gt;
&lt;p&gt;You don’t have to nail the perfect solution every time on the very first try. No. To be honest, if that happens to you, then you are not learning anything new and there’s no growth. Instead, find a solution that gets the work done even if it’s naive and inefficient.&lt;/p&gt;
&lt;p&gt;By doing so, you at least get a working prototype which you can test and iterate upon.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Prepare for coding interviews on &lt;a href=&quot;https://www.greatfrontend.com/prepare/coding?fpr=murtuzaali48&quot;&gt;GreatFrontEnd&lt;/a&gt; - a platform on which the interview resources are prepared by engineers from world&#39;s largest tech companies and core maintainers of open source projects.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;3.-refactor-and-iterate&quot; tabindex=&quot;-1&quot;&gt;3. Refactor and Iterate&lt;/h2&gt;
&lt;p&gt;For me, this is the most interesting and challenging part where you have already figured out the solution, but now you are looking for edge cases, performance improvements, potential bugs and implementation details in your solution.&lt;/p&gt;
&lt;p&gt;This is your chance to improve the solution according to your business needs along with maintaining best coding practices. Also, it gives you more depth to add to the documentation - you can add different approaches you took to arrive at the final solution, their advantages as well as shortcomings and much more.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.in/Refactoring-Improving-Existing-Addison-wesley-Signature/dp/0134757599?crid=35Y0LKUTFAQIC&amp;amp;dib=eyJ2IjoiMSJ9.VZZKbia-IvrlmziPsI_P1GrgVbHXyigvQIjsFIMyKYDl8uphVVo25yba_Xz9OX2c_o_cEXijHP0k105EPYy2gQH_8PoMVAqen0cszfJidAg.5lD6MHpwfWbQr4XSQpa11aC8n-baI8AJGalccpdXdC0&amp;amp;dib_tag=se&amp;amp;keywords=refactoring+improving+the+design+of+existing+code&amp;amp;nsdOptOutParam=true&amp;amp;qid=1736069489&amp;amp;sprefix=Refactoring%3A+Improving+the+Design+of+Existing+Code%2Caps%2C277&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=e6d6c1cc4dc373bff0538902a3488f63&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt; by Martin Fowler is a must read if you are struggling with refactoring existing/legacy code.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is what I learned in my experience as a software engineer up until now and I like to keep experimenting with this flow. If you have some more thoughts to share, let me know and I will add it here.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/looking-at-a-problem-as-a-developer/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Mac Setup For Developers [2026]</title>
    <link href="https://syntackle.com/blog/mac-setup-for-developers/"/>
    <published>2024-11-30T16:36:15Z</published>
    <updated>2026-01-22T09:35:35Z</updated>
    <id>https://syntackle.com/blog/mac-setup-for-developers/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Setting up a new Mac for development can be a daunting task, especially if you are new to MacOS or don&#39;t know where to start. In this guide, I&#39;ll tell you about some tools, apps and tips which are essential for a decent developer experience on a Mac.&lt;/p&gt;
&lt;p&gt;To keep it simple, I will break them down into categories such as terminals, editors, and other developer tools. But first, let me tell you some Mac settings which I prefer.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;The version of MacOS at the time of this writing is 15.1 (MacOS Sequoia). If you are on a newer version (MacOS 26 Tahoe), the settings may be different. This article is updated with MacOS 26 Tahoe settings as well.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;macos-settings&quot; tabindex=&quot;-1&quot;&gt;MacOS Settings &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#macos-settings&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Desktop &amp;amp; Dock &amp;gt; Dock&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;macOS 15 Sequoia
&lt;ul&gt;
&lt;li&gt;Position on screen: Left&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;macOS 26 Tahoe
&lt;ul&gt;
&lt;li&gt;Dock position on screen: Left&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Automatically hide and show the Dock: On&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Desktop &amp;amp; Stage Manager&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Show Items
&lt;ul&gt;
&lt;li&gt;On Desktop: Off&lt;/li&gt;
&lt;li&gt;In Stage Manager: On&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Show Desktop
&lt;ul&gt;
&lt;li&gt;macOS 15 Sequoia
&lt;ul&gt;
&lt;li&gt;Click wallpaper to show desktop: Only in Stage Manager&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;macOS 26 Tahoe
&lt;ul&gt;
&lt;li&gt;Click Wallpaper to move windows out of the way, revealing your desktop items and widgets: Only in Stage Manager on Click&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stage Manager: Off&lt;/li&gt;
&lt;li&gt;Mission Control: Turn everything on&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Displays&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;True Tone: Off&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you don&#39;t want the new liquid glass effect on macOS 26 Tahoe, go to &lt;strong&gt;Accessibility&lt;/strong&gt; &amp;gt; &lt;strong&gt;Display&lt;/strong&gt; &amp;gt; &lt;strong&gt;Reduce transparency&lt;/strong&gt; and turn it on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;package-manager-homebrew&quot; tabindex=&quot;-1&quot;&gt;Package Manager - Homebrew &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#package-manager-homebrew&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt; is the all-in-one package manager for MacOS. It can also install apps and fonts using homebrew cask. Installing it is the first thing you should do when setting up a new Mac.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1735491623/Syntackle/Posts/homebrew.jpg&quot; alt=&quot;homebrew banner&quot; height=&quot;498&quot; width=&quot;1080&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: brew.sh&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Install script:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-zsh&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;/bin/bash&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -c&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;$(&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -fsSL&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Do you know you can use multiple paid apps on macOS with just one subscription? Yes, you can. With &lt;a href=&quot;https://setapp.sjv.io/aOKWRY&quot;&gt;Setapp&lt;/a&gt; you can get access to curated apps with just one subscription.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;version-control-git&quot; tabindex=&quot;-1&quot;&gt;Version Control - Git &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#version-control-git&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To install git, I can use &lt;a href=&quot;https://formulae.brew.sh/formula/git&quot;&gt;Homebrew&lt;/a&gt; and it works like a charm:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-zsh&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;brew&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1735492456/Syntackle/Posts/git-hero.jpg&quot; alt=&quot;git hero banner&quot; height=&quot;1012&quot; width=&quot;808&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: git-scm.com&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;I recommend configuring and adding an &lt;code&gt;ssh&lt;/code&gt; key for dealing with repositories on GitHub. Refer the &lt;a href=&quot;https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account&quot;&gt;official documentation&lt;/a&gt; for more information.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.in/Pro-Git-Scott-Chacon-ebook/dp/B01ISNIKES?crid=1PHAAXUFTB5ON&amp;amp;dib=eyJ2IjoiMSJ9.URWGbI4GCTU8W1afvgWnh4HY2IMtAJ5Gqbje0aOJXqJSm42K5GoRUaeASMxlw8K7inXxT4og3qxIuT4rUP0w0QtyN6294YPjOZ7ACjlerz89YWAqTTJqplX_gHq182YO6asdDTR9_kVmhCrBeqKe20kwmBPtCrP3KwCCUOR2N10uaCjRJ91GJnldJwta6X0CISQgWdaJD2VbImPy79cb_5xmNWyGiXgTTH3l7idaXqs.4EloNNVh1b5R3AugzOK8rpIfgy-eNG1reyMxyHll08A&amp;amp;dib_tag=se&amp;amp;keywords=git+book&amp;amp;qid=1736065945&amp;amp;sprefix=git+book%2Caps%2C234&amp;amp;sr=8-4&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=e1121acd785d6e20b2924e6e562f8b8a&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;Pro Git&lt;/a&gt; is a great book for developing a solid understanding of Git and perhaps mastering it. And it&#39;s free.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;terminal&quot; tabindex=&quot;-1&quot;&gt;Terminal &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#terminal&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default terminal shell on MacOS is zsh and it&#39;s good, but it&#39;s even better with frameworks such as &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/wiki&quot;&gt;oh-my-zsh&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;1.-oh-my-zsh&quot; tabindex=&quot;-1&quot;&gt;1. Oh My Zsh&lt;/h3&gt;
&lt;p&gt;True power of oh-my-zsh comes with its plugins. The most popular ones are:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1735493551/Syntackle/Posts/oh-my-zsh.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1735493551/Syntackle/Posts/oh-my-zsh.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1735493551/Syntackle/Posts/oh-my-zsh.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1735493551/Syntackle/Posts/oh-my-zsh.jpg&quot; alt=&quot;oh my zsh&quot; height=&quot;604&quot; width=&quot;1010&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: github.com/ohmyzsh/ohmyzsh&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-autosuggestions&quot;&gt;zsh-autosuggestions&lt;/a&gt; - Provides auto-complete suggestions using command history.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zsh-users/zsh-syntax-highlighting&quot;&gt;zsh-syntax-highlighting&lt;/a&gt; - Very helpful in catching syntax errors.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git&quot;&gt;git&lt;/a&gt; - Useful aliases and functions for git.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/git-prompt/README.md&quot;&gt;git-prompt&lt;/a&gt; - Displays metadata related to the current git repository branch and its status relative to the remote branch.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MichaelAquilina/zsh-you-should-use&quot;&gt;you-should-use&lt;/a&gt; - Suggests available aliases which you should use instead of the command you&#39;re currently using.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;I recommend installing all of these plugins via oh-my-zsh and adding them to your &lt;code&gt;~/.zshrc&lt;/code&gt; file. You can refer to the respective plugin documentation for more details.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vim&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;plugins=(git git-prompt zsh-autosuggestions zsh-syntax-highlighting you-should-use zsh-bat)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh My Zsh also provides a &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/wiki/Themes&quot;&gt;variety of themes&lt;/a&gt; to choose from but I prefer the &lt;a href=&quot;https://github.com/romkatv/powerlevel10k&quot;&gt;Powerlevel10k&lt;/a&gt; theme by &lt;a href=&quot;https://github.com/romkatv&quot;&gt;romkatv&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;2.-warp&quot; tabindex=&quot;-1&quot;&gt;2. Warp&lt;/h3&gt;
&lt;p&gt;If you don&#39;t like the look and feel of the default terminal in macOS even after configuring oh-my-zsh, then you can have a look at &lt;a href=&quot;https://www.warp.dev/all-features&quot;&gt;warp.dev&lt;/a&gt; which is a terminal with the most modern look you can ever get in a terminal. Integration with AI is one of the things which you can use it for.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1735553473/Syntackle/Posts/warp-dev.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1735553473/Syntackle/Posts/warp-dev.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1735553473/Syntackle/Posts/warp-dev.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1735553473/Syntackle/Posts/warp-dev.jpg&quot; alt=&quot;warp terminal&quot; height=&quot;774&quot; width=&quot;1972&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: warp.dev&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-zsh&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;brew&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --cask&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; warp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3.-ghostty&quot; tabindex=&quot;-1&quot;&gt;3. Ghostty&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ghostty.org/download&quot;&gt;Ghostty&lt;/a&gt; is a fast, native terminal emulator developed by Mitchell Hashimoto. It&#39;s written in Swift for macOS and in Zig for Linux. It&#39;s currently not available for Windows.&lt;/p&gt;
&lt;p&gt;It just works.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1769074965/Syntackle/Posts/Screenshot_2026-01-22_at_3.11.47_PM_ei6bp2.png&quot; alt=&quot;ghostty, a fast, native terminal emulator developed by Mitchell Hashimoto&quot; height=&quot;1199&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h3 id=&quot;4.-iterm2&quot; tabindex=&quot;-1&quot;&gt;4. iTerm2&lt;/h3&gt;
&lt;p&gt;There&#39;s also iTerm2 which is a terminal emulator for macOS. If you are a power user and love legacy terminals, then this one&#39;s for you.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1735553768/Syntackle/Posts/iterm2-banner.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1735553768/Syntackle/Posts/iterm2-banner.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1735553768/Syntackle/Posts/iterm2-banner.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1735553768/Syntackle/Posts/iterm2-banner.jpg&quot; alt=&quot;iTerm2 banner&quot; height=&quot;566&quot; width=&quot;1486&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Source: iterm2.com&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-zsh&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;brew&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --cask&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; iterm2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;editors-ides&quot; tabindex=&quot;-1&quot;&gt;Editors / IDEs &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#editors-ides&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1.-visual-studio-code&quot; tabindex=&quot;-1&quot;&gt;1. Visual Studio Code&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;VS Code&lt;/a&gt; is still my go to editor. I prefer it because of its simplicity and extensibility. Part of the reason why I prefer it is because I am in a way habituated to it and it does a good enough job of meeting my developer needs.&lt;/p&gt;
&lt;h3 id=&quot;2.-antigravity&quot; tabindex=&quot;-1&quot;&gt;2. Antigravity&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://antigravity.google/&quot;&gt;Antigravity&lt;/a&gt;, a VS Code fork by Google, uses the tech of Windsurf (a company with which it made a &lt;a href=&quot;https://syntackle.com/blog/gemini-3-pro-and-nano-banana-pro-and-antigravity/&quot;&gt;licensing deal&lt;/a&gt;) of $2.4 billion. It focuses heavily on agentic workflows by spinning up background agents to complete tasks. It can also spin up browser instances to test the implemented changes. Antigravity is in public preview currently and offers some of the SOTA models such as gemini and claude family of models free of cost (with rate limits).&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://syntackle.com/blog/claude-code-free-using-antigravity-proxy/&quot;&gt;use free Antigravity models with Claude Code&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;3.-cursor&quot; tabindex=&quot;-1&quot;&gt;3. Cursor&lt;/h3&gt;
&lt;p&gt;AI it is. &lt;a href=&quot;https://www.cursor.com/&quot;&gt;Cursor&lt;/a&gt;, a VS Code fork, does a great job in fulfilling the AI needs which lack in VS Code. With it&#39;s similarity with VS Code, users can easily switch between these editors and still get the work done efficiently. It&#39;s my go to editor for AI stuff.&lt;/p&gt;
&lt;h3 id=&quot;4.-zed&quot; tabindex=&quot;-1&quot;&gt;4. Zed&lt;/h3&gt;
&lt;p&gt;One of the things I love about &lt;a href=&quot;https://zed.dev/&quot;&gt;Zed&lt;/a&gt; is how performant it is. VS Code can sometimes feel sluggish especially when you have a lot of extensions. Zed does all of those things natively, in a fast and efficient way - mainly because it&#39;s written in Rust.&lt;/p&gt;
&lt;h2 id=&quot;productivity&quot; tabindex=&quot;-1&quot;&gt;Productivity &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#productivity&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1.-raycast&quot; tabindex=&quot;-1&quot;&gt;1. Raycast&lt;/h3&gt;
&lt;p&gt;Many people coin &lt;a href=&quot;https://www.raycast.com/&quot;&gt;Raycast&lt;/a&gt; as a spotlight replacement but it&#39;s more than that for me. It can do shortcuts, clipboard, search and installation of apps through homebrew. I have still kept the spotlight shortcut as &amp;quot;Command + Space&amp;quot; and use Raycast with the hotkey &amp;quot;Option + Space&amp;quot;.&lt;/p&gt;
&lt;h3 id=&quot;2.-obsidian&quot; tabindex=&quot;-1&quot;&gt;2. Obsidian&lt;/h3&gt;
&lt;p&gt;I kind of switch between &lt;a href=&quot;https://www.notion.so/&quot;&gt;Notion&lt;/a&gt; and &lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt; for note taking. I find Obsidian very snappy and easily accessible when I have to quickly jot something down, while Notion is for when I want to retain or log something for later use or reference. But, both are great in my opinion.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bear.app/&quot;&gt;Bear&lt;/a&gt; is also a good choice.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;3.-maccy---clipboard-manager&quot; tabindex=&quot;-1&quot;&gt;3. Maccy - Clipboard Manager&lt;/h3&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;macOS 26 Tahoe revamped spotlight search and finally introduced the clipboard feature. So, if you are on macOS 26 or later, you might not need this app.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you don&#39;t want to use Raycast&#39;s clipboard history (which I don&#39;t), try out &lt;a href=&quot;https://maccy.app/&quot;&gt;Maccy&lt;/a&gt; which is a simple clipboard manager. It is easily accessible via shortcuts (which you can configure) and is open-source. It requires macOS Sonoma 14 or higher.&lt;/p&gt;
&lt;h2 id=&quot;browsers&quot; tabindex=&quot;-1&quot;&gt;Browsers &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#browsers&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I use &lt;a href=&quot;https://www.google.com/chrome/what-you-make-of-it/&quot;&gt;Chrome&lt;/a&gt; for development and day-to-day work, &lt;a href=&quot;https://www.apple.com/in/safari/&quot;&gt;Safari&lt;/a&gt; for Netflix, &lt;a href=&quot;https://brave.com/&quot;&gt;Brave&lt;/a&gt; for private browsing, and &lt;a href=&quot;https://arc.net/&quot;&gt;Arc&lt;/a&gt; just to feel nice.&lt;/p&gt;
&lt;h2 id=&quot;cleanup&quot; tabindex=&quot;-1&quot;&gt;Cleanup &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#cleanup&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1.-mole&quot; tabindex=&quot;-1&quot;&gt;1. Mole&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tw93/Mole&quot;&gt;Mole&lt;/a&gt; is a CLI tool which acts as a deep cleaner for your mac. It combines multiple tools into a single package and lets you uninstall apps, deep clean system as well as monitor and analyze it for performance. It&#39;s the best CLI tool you can have on a mac. Saves you a lot of space and time.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1769074356/Syntackle/Posts/Screenshot_2026-01-22_at_2.59.33_PM_czeiyk.png&quot; alt=&quot;mole, a CLI tool which acts as a deep cleaner for your mac&quot; height=&quot;371&quot; width=&quot;1518&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h3 id=&quot;2.-appcleaner&quot; tabindex=&quot;-1&quot;&gt;2. AppCleaner&lt;/h3&gt;
&lt;p&gt;Uninstalling apps on MacOS is not as simple as you think. Even if you uninstall an app from your system, some residue files are always left behind. &lt;a href=&quot;https://freemacsoft.net/appcleaner/&quot;&gt;AppCleaner&lt;/a&gt; is for that. It lets you completely wipe out any data associated with the app you want to uninstall.&lt;/p&gt;
&lt;p&gt;If you want more features, try Mole instead of AppCleaner as it gives you more features and control out of the box.&lt;/p&gt;
&lt;h2 id=&quot;miscellaneous&quot; tabindex=&quot;-1&quot;&gt;Miscellaneous &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/#miscellaneous&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1.-bitwarden---password-manager&quot; tabindex=&quot;-1&quot;&gt;1. Bitwarden - Password Manager&lt;/h3&gt;
&lt;p&gt;I personally use &lt;a href=&quot;https://bitwarden.com/&quot;&gt;Bitwarden&lt;/a&gt; as a password manager and I have no complains so far. What&#39;s interesting is it&#39;s open-sourced and can be self-hosted. Being open-sourced also means it&#39;s transparent and audited by the community. Trust me, it&#39;s a pain in the neck to manage passwords for all of the random accounts we developers create to try different things, and bitwarden makes it easy for you.&lt;/p&gt;
&lt;h3 id=&quot;2.-syncthing&quot; tabindex=&quot;-1&quot;&gt;2. Syncthing&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://syncthing.net/&quot;&gt;Syncthing&lt;/a&gt; is by far the best file sharing tool I have ever used. You can literally sync folders between two machines (be it Android, macOS, or Windows) seamlessly. If you have another system at a remote location, it can be really handy to sync project folders or work files using a local network or an internet connection. Again, it&#39;s open-sourced and trusted by the community.&lt;/p&gt;
&lt;h3 id=&quot;3.-system-color-picker&quot; tabindex=&quot;-1&quot;&gt;3. System Color Picker&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://sindresorhus.com/system-color-picker&quot;&gt;System Color Picker&lt;/a&gt; by &lt;a href=&quot;https://github.com/sindresorhus&quot;&gt;Sindre Sorhus&lt;/a&gt; is the most useful tool for web designers and developers. It&#39;s open sourced and is a native color picker application for macOS which lets you pick colors from anywhere on the screen. It&#39;s a must have for convenience.&lt;/p&gt;
&lt;h3 id=&quot;4.-ice&quot; tabindex=&quot;-1&quot;&gt;4. Ice&lt;/h3&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://syntackle.com/blog/the-most-useful-macos-app/&quot;&gt;Ice&lt;/a&gt; won&#39;t work on macOS 26 Tahoe (macOS 26 made significant changes in APIs), a stable release is in the works, but there are several &lt;a href=&quot;https://github.com/jordanbaird/Ice/releases/tag/0.11.13-dev.2&quot;&gt;beta releases&lt;/a&gt; (0.11.13-dev.x) you can try.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once you have a lot of applications which use MacOS&#39; menubar for status display or accessibility, the menubar can overflow with those application icons and hide some icons behind the notch (if your Mac has one), especially when using applications such as Chrome (has a lot of menu options, eating up space of the menubar icons).&lt;/p&gt;
&lt;p&gt;One way is to keep less (default) icons in the menubar (besides the control center) by going to Settings &amp;gt; Control Center &amp;gt; Menu Bar Only/Other Modules — but that just works for native MacOS&#39; icons. For third-party application menubar icons? There&#39;s no option to reorder/hide or access hidden icons in MacOS.&lt;/p&gt;
&lt;p&gt;I really want a little ellipsis which lists all of the hidden MacOS menubar icons in a dropdown list below the visible ones, and &lt;a href=&quot;https://icemenubar.app/&quot;&gt;Ice&lt;/a&gt; does exactly that.&lt;/p&gt;
&lt;p&gt;Install Ice from &lt;a href=&quot;https://icemenubar.app/&quot;&gt;https://icemenubar.app/&lt;/a&gt; and you will see a dot/ellipsis collapsing all the menubar icons. You can show hide them by clicking on the ellipsis/dot in the menubar, but where it gets really interesting is that you can change the appearance of the menubar completely. Go to Ice Settings by right clicking on the menubar, and then to the Menu Bar Layout tab.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1746972554/Syntackle/Posts/Screenshot_2025-05-11_at_7.37.16_PM_rn01oq.png&quot; alt=&quot;Ice - a macOS application for menubar customization&quot; height=&quot;889&quot; width=&quot;1280&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;blockquote class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;This list is evolving. If you have any suggestions, please let me know. Here&#39;s an in-depth mac setup video by &lt;a href=&quot;https://www.youtube.com/@WesBos&quot;&gt;wesbos&lt;/a&gt; for power users:&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;GK7zLYAXdDs&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/mac-setup-for-developers/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Better - An AI powered Code Reviewer</title>
    <link href="https://syntackle.com/blog/ai-powered-code-review-tool-better/"/>
    <published>2024-09-28T09:17:44Z</published>
    <updated>2024-09-29T07:10:57Z</updated>
    <id>https://syntackle.com/blog/ai-powered-code-review-tool-better/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Code reviews have always been crucial in maintaining a standard and emphasizing on the best practices of code in a project. This is not a post about how developers should review the code, it&#39;s more about delegating a part of it to AI.&lt;/p&gt;
&lt;p&gt;As Michael Lynch mentions in his post - &lt;a href=&quot;https://mtlynch.io/human-code-reviews-1/#let-computers-do-the-boring-parts&quot;&gt;&amp;quot;How to Do Code Reviews Like a Human&amp;quot;&lt;/a&gt; - we should &lt;em&gt;&lt;strong&gt;let computers take care of the boring parts&lt;/strong&gt;&lt;/em&gt; of the code review. While Michael emphasizes on a formatting tool, I would like to take it a step further and let artificial intelligence figure it out. I mean, why not take the advantage of the AI boom in the industry?&lt;/p&gt;
&lt;p&gt;Now I am not saying that &lt;a href=&quot;https://syntackle.com/blog/window-ai-in-chrome/&quot;&gt;AI&lt;/a&gt; should be used in place of formatting tools and linters. Instead, it is to be used on top of that, to catch trivial stuff which might be missed by a human.&lt;/p&gt;
&lt;p&gt;That&#39;s why I decided to create a &lt;a href=&quot;https://github.com/murtuzaalisurti/better&quot;&gt;github action&lt;/a&gt; which code reviews a pull request diff and generates suggestions using AI. Let me walk you through it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;%F0%9F%9A%A8-note&quot; tabindex=&quot;-1&quot;&gt;🚨 Note&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;This GitHub action is now available at the &lt;a href=&quot;https://github.com/marketplace/actions/better-code-reviewer-powered-by-ai&quot;&gt;GitHub marketplace&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;It&#39;s a javascript action - learn more about &lt;a href=&quot;https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-javascript-action&quot;&gt;creating javascript github actions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;getting-the-diff&quot; tabindex=&quot;-1&quot;&gt;Getting the diff &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/#getting-the-diff&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To interact with the github API, I have used &lt;code&gt;octokit&lt;/code&gt;, which is kind of an SDK or a &lt;a href=&quot;https://docs.github.com/en/rest/using-the-rest-api/libraries-for-the-rest-api?apiVersion=2022-11-28#official-github-libraries&quot;&gt;client library for interacting with the github API&lt;/a&gt; in an idiomatic way.&lt;/p&gt;
&lt;p&gt;In order for you to get the diff of the pull request raised, you need to pass the &lt;code&gt;Accept&lt;/code&gt; header with the value &lt;code&gt;application/vnd.github.diff&lt;/code&gt; along with the required parameters.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getPullRequestDetails&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;octokit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; AcceptFormat&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;application/vnd.github.raw+json&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;diff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;AcceptFormat&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;application/vnd.github.diff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;json&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;AcceptFormat&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;application/vnd.github.raw+json&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; octokit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;rest&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;pulls&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        owner&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;owner&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        pull_number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;payload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;pull_request&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        headers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            accept&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;AcceptFormat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;If you are not familiar with github actions at all, here&#39;s a &lt;a href=&quot;https://lo-victoria.com/series/github-actions&quot;&gt;github actions 101 series by Victoria Lo&lt;/a&gt; and it&#39;s a good start.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once I get the diff, I parse it and remove unwanted changes, and then return it in a schema shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/** using zod */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;schema&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    path&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    position&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    change&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        add&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        ln&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        relativePosition&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    previously&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;optional&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    suggestions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;optional&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;ignoring-files&quot; tabindex=&quot;-1&quot;&gt;Ignoring Files &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/#ignoring-files&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ignoring files is quite straightforward. The user input list requires a semicolon separated string of glob patterns. It&#39;s then parsed, concatenated with the default list of ignored files and de-duped.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;**/*.md; **/*.env; **/*.lock;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; filesToIgnoreList&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ...&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Set&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        filesToIgnore&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;concat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;FILES_IGNORED_BY_DEFAULT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ignored files list is then used to remove the diff changes which refer to those ignored files. That gives you a raw payload containing only the changes you want.&lt;/p&gt;
&lt;h2 id=&quot;generating-suggestions&quot; tabindex=&quot;-1&quot;&gt;Generating suggestions &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/#generating-suggestions&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once I get the raw payload after parsing the diff, I pass it to the platform API. Here&#39;s an implementation of the OpenAI API.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useOpenAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;openAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;pullRequestContext&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; openAI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;beta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;chat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;completions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getModelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;openai&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;COMMON_SYSTEM_PROMPT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getUserPrompt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pullRequestContext&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        response_format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;zodResponseFormat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;diffPayloadSchema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;json_diff_response&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;choices&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;refusal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        throw&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`the model refused to generate suggestions - &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;refusal&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;parsed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might notice the use of response format in the API implementation. This is a feature provided by many LLM platforms, which allows you to tell the model to generate the response in a specific schema/format. It is especially helpful in this case as I don&#39;t want the model to hallucinate and generate suggestions for incorrect files or positions in the pull request, or add new properties to the response payload.&lt;/p&gt;
&lt;p&gt;The system prompt is there to give the model more context on how it should do the code review and what are some things to keep in mind. You can view the system prompt here &lt;a href=&quot;https://github.com/murtuzaalisurti/better/blob/main/utils/constants.js#L10&quot;&gt;github.com/murtuzaalisurti/better&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The user prompt contains the actual diff, the rules and the context of the pull request. It is what kicks off the code review.&lt;/p&gt;
&lt;p&gt;This github action supports both OpenAI and Anthropic models. Here&#39;s how it implements the Anthropic API:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useAnthropic&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;anthropic&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;pullRequestContext&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;definitions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; zodToJsonSchema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;diffPayloadSchema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;diffPayloadSchema&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; anthropic&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        max_tokens&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;8192&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getModelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;anthropic&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        system&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;COMMON_SYSTEM_PROMPT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        tools&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;structuredOutput&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                description&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Structured Output&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                input_schema&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;definitions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;diffPayloadSchema&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        tool_choice&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tool&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;structuredOutput&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getUserPrompt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pullRequestContext&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; parsed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; block&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;block&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;tool_use&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            parsed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; block&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            break&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; parsed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;adding-comments&quot; tabindex=&quot;-1&quot;&gt;Adding Comments &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/#adding-comments&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Finally, after retrieving the suggestions, I sanitize them and pass them to the github API to add comments as a part of the review.&lt;/p&gt;
&lt;p&gt;I chose the below way to add comments because by creating a new review, you can add all comments in one go instead of adding a single comment at a time. Adding comments one by one may also trigger rate limiting because adding comments triggers notifications and you don&#39;t want to spam users with notifications.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; filterPositionsNotPresentInRawPayload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;comments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; comments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;some&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rawComment&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; rawComment&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; comment&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; rawComment&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; comment&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; addReviewComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;suggestions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;octokit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;withTimestamp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// eslint-disable-line no-use-before-define&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; comments&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; filterPositionsNotPresentInRawPayload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rawComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;extractComments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;comments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;suggestions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; octokit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;rest&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;pulls&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createReview&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            owner&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;owner&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;repo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            pull_number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;payload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;pull_request&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`Code Review by &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;modelName&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;COMMENT&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            comments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`Failed to add review comments: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;comments&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        throw&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I wanted to keep the github action open-ended and open to integrations and that&#39;s why you can use any model of your choice &lt;em&gt;(see the list of &lt;a href=&quot;https://github.com/murtuzaalisurti/better?tab=readme-ov-file#4-ai-model-name-optional&quot;&gt;supported models&lt;/a&gt;)&lt;/em&gt;, or you can fine tune and build your own custom model on top of the supported base models and use it with this github action.&lt;/p&gt;
&lt;p&gt;If you encounter any &lt;a href=&quot;https://github.com/murtuzaalisurti/better?tab=readme-ov-file#things-to-note&quot;&gt;token issues or rate limiting&lt;/a&gt;, you might want to upgrade your model limits by referring to the respective platform&#39;s documentation.&lt;/p&gt;
&lt;p&gt;So, what are you waiting for? If you have repository on github, try the action now - it&#39;s on the &lt;a href=&quot;https://github.com/marketplace/actions/better-code-reviewer-powered-by-ai&quot;&gt;github action marketplace&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/ai-powered-code-review-tool-better/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Server Sent Events 101</title>
    <link href="https://syntackle.com/blog/server-sent-events/"/>
    <published>2024-08-19T10:45:50Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/server-sent-events/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Server Sent Events (SSE), as the name suggests, are a way to communicate with the client by keeping a persistent connection in which the server sends text messages to the client whenever they are available. They are similar to &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/&quot;&gt;websockets&lt;/a&gt; but, unlike websockets, the connection is unidirectional, i.e. only the server has the capability to send messages and the client just listens.&lt;/p&gt;
&lt;p&gt;Another key difference between SSE and websockets is that websockets use their own &lt;code&gt;ws://&lt;/code&gt; websocket protocol while SSEs use the HTTP protocol. Also, SSEs can only transmit data in &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format&quot;&gt;&lt;code&gt;text/event-stream&lt;/code&gt; format&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;sending-events-from-server&quot; tabindex=&quot;-1&quot;&gt;Sending Events From Server &lt;a href=&quot;https://syntackle.com/blog/server-sent-events/#sending-events-from-server&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In a basic &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/&quot;&gt;nodejs (express) server&lt;/a&gt;, you can define an endpoint to allow subscriptions from clients, and store them in a unique Set.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; clients&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Set&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; addSubscription&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    clients&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`Client &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; connected`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; removeSubscription&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    clients&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`Client &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; disconnected`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/subscribe&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URLSearchParams&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    addSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;close&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        removeSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once a subscription is added and stored in the Set, you must set these response headers with a status code of &lt;code&gt;200&lt;/code&gt; to let the client know that this is a text/event-stream, keep-alive connection.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/subscribe&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URLSearchParams&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    addSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;writeHead&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Content-Type&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/event-stream&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Connection&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keep-alive&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Cache-Control&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;no-cache&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;close&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        removeSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that the connection is set, you can send messages to the client in the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format&quot;&gt;EventStream&lt;/a&gt; format. That&#39;s it, you can now listen to these event streams using the EventSource API which I will talk about more later in this post.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/subscribe&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URLSearchParams&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    addSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;writeHead&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Content-Type&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/event-stream&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Connection&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keep-alive&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Cache-Control&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;no-cache&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`data: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;close&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        removeSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also ping the client at regular intervals by using &lt;code&gt;setInterval&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setInterval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`data: ping&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is all good but what if you want to send messages when something happens, either in the &lt;a href=&quot;https://syntackle.com/blog/node-http-server-using-hono/&quot;&gt;server&lt;/a&gt; or in the database. For that, you need to use event emitters in nodejs to fire a specific event and capture that event in our request handler to send a message to the client.&lt;/p&gt;
&lt;h2 id=&quot;event-emitters&quot; tabindex=&quot;-1&quot;&gt;Event Emitters&lt;/h2&gt;
&lt;p&gt;Event emitters are a type of the &lt;a href=&quot;https://ably.com/topic/pub-sub#pub-sub-architecture&quot;&gt;pub/sub architecture&lt;/a&gt; wherein you have subscribers subscribing to specific &amp;quot;named&amp;quot; events and emitters (publishers) which publish/emit the event based on some operation.&lt;/p&gt;
&lt;p&gt;Here&#39;s a simple example of an event emitter in nodejs:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;EventEmitter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;events&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; UpdateEvents&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; EventEmitter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;        super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    new&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;emit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;new&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; updates&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; UpdateEvents&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    updates&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    newUpdate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; updates&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;new&lt;/code&gt; method in the &lt;code&gt;UpdateEvents&lt;/code&gt; class is an event emitter method which emits the named event &lt;code&gt;new&lt;/code&gt;. This is what fires the event. Then, we create an instance of the &lt;code&gt;UpdateEvents&lt;/code&gt; class and export it for it to be used for listening to the &lt;code&gt;new&lt;/code&gt; event. You can listen to the event anywhere in your application code using:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;updates&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;new&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // do something with the data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is really useful for your SSE endpoint. For example, if you want to send events from an operation/event in some other part of the application and not necessarily inside the request handler, then you can fire an event from different places in your code and listen to it in the SSE endpoint.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// in some other part of the application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;newUpdate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// ----------------------------------&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// in the SSE endpoint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/subscribe&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URLSearchParams&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    addSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;writeHead&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Content-Type&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/event-stream&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Connection&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keep-alive&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        &quot;Cache-Control&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;no-cache&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    updates&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;new&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`data: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;close&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        removeSubscription&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;subscribing-to-sse-events-from-clients&quot; tabindex=&quot;-1&quot;&gt;Subscribing to SSE Events From Clients &lt;a href=&quot;https://syntackle.com/blog/server-sent-events/#subscribing-to-sse-events-from-clients&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSE Events are captured using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource&quot;&gt;&lt;code&gt;EventSource&lt;/code&gt;&lt;/a&gt; web API. You just have to pass the URL of the SSE endpoint to the &lt;code&gt;EventSource&lt;/code&gt; API. You can&#39;t pass your own custom headers in the EventSource, so you have to rely on query parameters to pass additional context about the client.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;SSE_ENDPOINT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;YOUR_API_BASE_URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; event&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; EventSource&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;?id=&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;The EventSource API &lt;a href=&quot;https://github.com/whatwg/html/issues/2177&quot;&gt;&lt;strong&gt;doesn&#39;t&lt;/strong&gt; allow you to pass custom headers&lt;/a&gt; natively. You have to rely on polyfills or query parameters to pass additional context about the client. Learn more about the limitations of the EventSource API &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventSource#:~:text=web%20storage.-,Warning,-%3A%20When%20not&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Then, listen to the messages which are sent by the server by using the &lt;code&gt;onmessage&lt;/code&gt; event.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;SSE_ENDPOINT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;YOUR_API_BASE_URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; event&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; EventSource&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;?id=&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onmessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onopen&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;connection opened&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What happens when the connection to the server is lost? In that case, the browser tries to reconnect automatically within a certain interval of time known as the &lt;a href=&quot;https://web.dev/articles/eventsource-basics#:~:text=The%20magical%20part%20is%20that%20whenever%20the%20connection%20is%20closed%2C%20the%20browser%20automatically%20reconnects%20to%20the%20source%20after%20~3%20seconds.%20Your%20server%20implementation%20can%20even%20have%20control%20over%20this%20reconnection%20timeout.&quot;&gt;&lt;code&gt;retry&lt;/code&gt; interval&lt;/a&gt;. The default retry interval is ~3 seconds in the browser. However, you can specify your own retry interval by sending the value (in milliseconds) in a &lt;code&gt;retry&lt;/code&gt; field with the server sent message.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`data: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`retry: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retryInterval&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// in milliseconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;Know how to properly send messages using the EventStream format in this &lt;a href=&quot;https://web.dev/articles/eventsource-basics#event_stream_format&quot;&gt;article by web.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you don&#39;t want to rely on the automatic reconnect provided by the browser or if it&#39;s not working for you, you can implement you custom retry mechanism yourself. Let me show you how.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; retryInterval&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 6000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; listenToEvents&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;retryAfter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; isListening&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; interval&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; setInterval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;isListening&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            isListening&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;SSE_ENDPOINT&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;YOUR_API_BASE_URL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; event&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; EventSource&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;?id=&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;crypto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;randomUUID&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onmessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; payload&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;                // do something with the payload&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                payload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retry&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retryInterval&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; payload&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retry&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;                clearInterval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                event&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;                listenToEvents&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retryInterval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;retryAfter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;listenToEvents&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// initially, establish the connection in 1 second&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First of all, you have to setup an interval which will keep checking if the connection is still alive or not. And the interval can be set to a custom value, or to the retry value you get from the server. This interval will be wrapped in a function named &lt;code&gt;listenToEvents&lt;/code&gt; which will accept a &lt;code&gt;retryInterval&lt;/code&gt; parameter and initialize a local variable named &lt;code&gt;isListening&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This interval will keep creating new eventsource objects if the &lt;code&gt;isListening&lt;/code&gt; variable is &lt;code&gt;false&lt;/code&gt;. It&#39;s set to &lt;code&gt;false&lt;/code&gt; by default but, it&#39;s set to &lt;code&gt;true&lt;/code&gt; when establishing the connection, so only one eventsource object will be created at the first round of the interval.&lt;/p&gt;
&lt;p&gt;If the connection is lost, the &lt;code&gt;onerror&lt;/code&gt; event will be fired closing the event, clearing the current interval and invoking the function &lt;code&gt;listenToEvents&lt;/code&gt; recursively.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a href=&quot;https://syntackle.com/blog/server-sent-events/#conclusion&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this guide, you got to know about server sent events, event emitters and the &lt;code&gt;EventSource&lt;/code&gt; API. Server Sent Events are almost similar to websockets with some key differences. If you want to learn more about websockets, check out the &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/&quot;&gt;WebSockets 101&lt;/a&gt; guide.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/server-sent-events/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>&quot;this&quot; Keyword in Arrow Functions</title>
    <link href="https://syntackle.com/blog/this-keyword-in-arrow-functions-javascript/"/>
    <published>2024-07-19T16:54:43Z</published>
    <updated>2024-07-19T16:54:43Z</updated>
    <id>https://syntackle.com/blog/this-keyword-in-arrow-functions-javascript/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;The &lt;code&gt;this&lt;/code&gt; keyword in javascript is probably one of the most misunderstood concepts of javascript. There are already some brilliant resources out there to explain the &lt;code&gt;this&lt;/code&gt; keyword, but in this article, you will see how the &lt;code&gt;this&lt;/code&gt; reference is different in &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;arrow functions&lt;/a&gt; introduced in ES6 as compared to regular function expressions. You will also get to know a way to visualize the &lt;code&gt;this&lt;/code&gt; keyword reference inside arrow functions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This article will only cover implicit binding of the &lt;code&gt;this&lt;/code&gt; keyword, i.e. what&#39;s interpreted by javascript by default.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&#39;s start by defining an object named &lt;code&gt;user&lt;/code&gt;. In this object, you have a regular function expression named &lt;code&gt;logName&lt;/code&gt;. How will you call the &lt;code&gt;logName&lt;/code&gt; function if you want to execute it? You will have to do &lt;code&gt;user.logName()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs &#39;John&#39; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the object on which the function is invoked. The object on which it is invoked is &lt;code&gt;user&lt;/code&gt; and that&#39;s the &lt;a href=&quot;https://www.youtube.com/watch?v=zdGfo6I1yrA&quot;&gt;&lt;em&gt;execution context&lt;/em&gt;&lt;/a&gt; of the function &lt;code&gt;logName&lt;/code&gt;. So, whenever you type &lt;code&gt;this&lt;/code&gt; inside the regular function expression, it automatically refers to the object that it&#39;s being called upon. In this case, it will log the value of the &lt;code&gt;name&lt;/code&gt; property inside the object &lt;code&gt;user&lt;/code&gt;. In other words, it &lt;em&gt;binds&lt;/em&gt; to the context of the object &lt;code&gt;user&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, let&#39;s create an arrow function &lt;code&gt;logNameArrow()&lt;/code&gt; inside the same object and having the same body as &lt;code&gt;logName()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs &#39;John&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What do you think will be logged when you invoke &lt;code&gt;logNameArrow&lt;/code&gt;? It will log &lt;code&gt;undefined&lt;/code&gt; but why? That&#39;s because arrow functions don&#39;t have their &lt;em&gt;own&lt;/em&gt; bindings.&lt;/p&gt;
&lt;p&gt;In other words, even if you invoke the arrow function from the object &lt;code&gt;user&lt;/code&gt; like this &lt;code&gt;user.logNameArrow()&lt;/code&gt;, the arrow function doesn&#39;t know on what it got invoked upon. Instead, what it knows, is the &lt;em&gt;lexical&lt;/em&gt; scope in which it exists. And, it will bind to the context of the &lt;em&gt;&lt;strong&gt;closest enclosing scope&lt;/strong&gt;&lt;/em&gt; (in this case it&#39;s the window object).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Lexical Scoping&lt;/strong&gt; defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.&lt;/em&gt; - &lt;a href=&quot;https://stackoverflow.com/a/2896899/17241798&quot;&gt;Pierre Spring, stackoverflow.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs &#39;John&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs undefined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s similar to how variables are resolved using lexical scoping. If a variable is not defined in the current scope, javascript will check the parent scope for that variable, and will keep doing so until it reaches the highest parent scope which encloses everything.&lt;/p&gt;
&lt;p&gt;To test this, you can create a new arrow function inside the regular function expression &lt;code&gt;logName&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs &#39;John&#39; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs undefined&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, here comes the interesting part. Since arrow functions don&#39;t have their own bindings, they look for the parent scope&#39;s context binding, in this case it&#39;s the context binding of the regular function expression &lt;code&gt;logName()&lt;/code&gt;. That is the reason the arrow function &lt;code&gt;logNameArrow&lt;/code&gt; (inside the &lt;code&gt;logName&lt;/code&gt; regular function expression) will log &#39;John&#39; instead of &lt;code&gt;undefined&lt;/code&gt;. Here&#39;s an example which demonstrates lexical scoping which is three levels deep.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// John&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// John&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; logNameArrow2&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// John&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; logNameArrow3&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// John&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;                logNameArrow3&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            logNameArrow2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// undefined&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s visualize the highest enclosing lexical scope by wrapping this object in an &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;IIFE (Immediately Invoked Function Expression)&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;Peter&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// John&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// Peter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    user&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;logNameArrow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you wrap the object in a wrapper function, it creates a new lexical scope in which the object and its properties exist. Define a variable named &lt;code&gt;name&lt;/code&gt;, identical to the &lt;code&gt;user&lt;/code&gt; object property &lt;code&gt;name&lt;/code&gt; and assign it a different value. Now, as you know, the arrow function tries to find the closest enclosing parent lexical scope (which in this case is the highest enclosing parent scope) i.e. the scope of the wrapper IIFE. And, it finds a variable named &lt;code&gt;name&lt;/code&gt; in that scope. And, thus it logs &#39;Peter&#39; as a result.&lt;/p&gt;
&lt;p&gt;That was everything you needed to know about how the &lt;code&gt;this&lt;/code&gt; keyword is referenced &lt;em&gt;implicitly&lt;/em&gt; in javascript arrow functions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;must-reads-%F0%9F%9A%A8&quot; tabindex=&quot;-1&quot;&gt;Must Reads 🚨&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ui.dev/this-keyword-call-apply-bind-javascript&quot;&gt;Understanding the &amp;quot;this&amp;quot; keyword, call, apply, and bind in JavaScript&lt;/a&gt; - ui.dev&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/learn/javascript/functions/this&quot;&gt;The this keyword&lt;/a&gt; - web.dev&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/zdGfo6I1yrA?t=614&quot;&gt;JavaScript Visualized - Execution Contexts&lt;/a&gt; - Lydia Hallie &lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;zdGfo6I1yrA&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/this-keyword-in-arrow-functions-javascript/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>5 Newsletters Every Developer Should Read</title>
    <link href="https://syntackle.com/blog/five-newsletters-every-developer-should-read/"/>
    <published>2024-07-13T11:24:43Z</published>
    <updated>2025-02-13T15:43:40Z</updated>
    <id>https://syntackle.com/blog/five-newsletters-every-developer-should-read/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Newsletters can be hard to follow along, especially when you subscribe to too many of them. That&#39;s why, today you will get to know about five newsletters every developer should follow and read. These are the newsletters I personally subscribe to.&lt;/p&gt;
&lt;h2 id=&quot;1.-pointer&quot; tabindex=&quot;-1&quot;&gt;1. Pointer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.pointer.io/&quot;&gt;Pointer.io&lt;/a&gt; is an engineering focused newsletter, an issue of which can be broken down into three sections: leadership articles, engineering articles, and some interesting links to &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;developer tools&lt;/a&gt; and resources. You can get a lot of value from the tools and resources listed in this newsletter.&lt;/p&gt;
&lt;h2 id=&quot;2.-tldr&quot; tabindex=&quot;-1&quot;&gt;2. TLDR&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://refer.tldr.tech/3ead5357/&quot;&gt;tldr.tech&lt;/a&gt;, as the name suggests, focuses on byte-sized latest updates in the programming, tech and startup world. This newsletter keeps you up-to-date in the ever changing tech industry and it does its job very well.&lt;/p&gt;
&lt;h2 id=&quot;3.-bytes&quot; tabindex=&quot;-1&quot;&gt;3. Bytes&lt;/h2&gt;
&lt;p&gt;If you deal with javascript as a developer, then &lt;a href=&quot;https://bytes.dev/&quot;&gt;bytes.dev&lt;/a&gt; is the perfect newsletter for you. It features tools and resources related to the javascript ecosystem and has a &amp;quot;spot the bug&amp;quot; section which lets you test your &lt;a href=&quot;https://syntackle.com/category/javascript/&quot;&gt;javascript&lt;/a&gt; skills.&lt;/p&gt;
&lt;h2 id=&quot;4.-the-pragmatic-engineer&quot; tabindex=&quot;-1&quot;&gt;4. The Pragmatic Engineer&lt;/h2&gt;
&lt;p&gt;One of the most popular engineering newsletters out there, &lt;a href=&quot;https://newsletter.pragmaticengineer.com/about&quot;&gt;the pragmatic engineer&lt;/a&gt; by &lt;a href=&quot;https://blog.pragmaticengineer.com/&quot;&gt;Gergely Orosz&lt;/a&gt; offers insightful stories from the big tech as well as some meaningful advice for leadership and management roles in software.&lt;/p&gt;
&lt;h2 id=&quot;5.-elevate-with-addy-osmani&quot; tabindex=&quot;-1&quot;&gt;5. Elevate with Addy Osmani&lt;/h2&gt;
&lt;p&gt;In his &lt;a href=&quot;https://addyo.substack.com/&quot;&gt;newsletter&lt;/a&gt;, &lt;a href=&quot;https://addyosmani.com/&quot;&gt;Addy Osmani&lt;/a&gt; shares his experience working in the software industry and how to deal with some of the challenges that come along with it. The newsletter offers advice and steps to be effective in the software world. Addy has also published many books related to programming, with &lt;a href=&quot;https://addyosmani.com/blog/software-engineering-soft-parts/&quot;&gt;&amp;quot;Software Engineering: The Soft Parts&amp;quot;&lt;/a&gt; being one of my favorites.&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If newsletters are not your choice, and you prefer reading blogs via RSS feeds, &lt;a href=&quot;https://rssed.netlify.app/&quot;&gt;rssed&lt;/a&gt; is a collection of interesting developer focused feeds which you can read anytime you want. For adding an interesting feed to the list, follow the steps &lt;a href=&quot;https://github.com/murtuzaalisurti/rssed?tab=readme-ov-file#contribute&quot;&gt;here&lt;/a&gt; or if you can&#39;t do that, shoot me an &lt;a href=&quot;https://syntackle.com/contact/&quot;&gt;email&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/five-newsletters-every-developer-should-read/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>I tried &quot;window.ai&quot; in Chrome</title>
    <link href="https://syntackle.com/blog/window-ai-in-chrome/"/>
    <published>2024-07-02T17:15:51Z</published>
    <updated>2025-11-24T07:00:06Z</updated>
    <id>https://syntackle.com/blog/window-ai-in-chrome/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;blockquote&gt;
&lt;p&gt;I never got chrome&#39;s built-in AI model working on &lt;a href=&quot;https://www.google.com/intl/en_in/chrome/canary/&quot;&gt;Chrome&#39;s Canary&lt;/a&gt; release (maybe because I am on v128), so I tried &lt;a href=&quot;https://www.google.com/intl/en_in/chrome/dev/&quot;&gt;Chrome&#39;s Dev&lt;/a&gt; Channel &lt;em&gt;&lt;strong&gt;- thanks &lt;a href=&quot;https://youtu.be/V4-4Ylipjoo?t=95&quot;&gt;@theo&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Google Chrome has started shipping experimental AI features such as &lt;a href=&quot;https://developer.chrome.com/docs/ai/built-in&quot;&gt;built-in AI&lt;/a&gt; in Chrome&#39;s Dev/Canary channels. In this tutorial, you will get to know how you can try the built-in AI model in chrome dev.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Practice frontend system design interview questions on &lt;a href=&quot;https://www.greatfrontend.com/prepare/system-design?fpr=murtuzaali48&quot;&gt;GreatFrontEnd&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;installing-chrome-dev&quot; tabindex=&quot;-1&quot;&gt;Installing Chrome Dev&lt;/h2&gt;
&lt;p&gt;Head over to &lt;a href=&quot;https://www.google.com/intl/en_in/chrome/dev/&quot;&gt;chrome&#39;s dev release download page&lt;/a&gt; and install the dev release of chrome.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-experimental-flags&quot; tabindex=&quot;-1&quot;&gt;Setting up experimental flags&lt;/h2&gt;
&lt;p&gt;Once you have installed chrome dev, visit &lt;code&gt;chrome://flags&lt;/code&gt; url and search for two flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#optimization-guide-on-device-model&lt;/code&gt; - set it to &lt;code&gt;Enabled BypassPerfRequirement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#prompt-api-for-gemini-nano&lt;/code&gt; - set it to &lt;code&gt;Enabled&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, visit &lt;code&gt;chrome://components&lt;/code&gt; and search for &lt;code&gt;Optimization Guide On Device Model&lt;/code&gt; component. If its not showing up in the list, disable/enable the above flags, relaunch/restart chrome and keep doing this until you get that component.&lt;/p&gt;
&lt;p&gt;Once you get that component, click check for updates (the initial version will be &lt;code&gt;0.0.0.0&lt;/code&gt;). It will start the download automatically and after it gets completed, you will see the updated version of that component (for me it was &lt;code&gt;2024.6.5.2205&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;With that being done, you are now ready to use &lt;code&gt;window.ai&lt;/code&gt; in chrome.&lt;/p&gt;
&lt;h2 id=&quot;creating-a-session&quot; tabindex=&quot;-1&quot;&gt;Creating a session&lt;/h2&gt;
&lt;p&gt;The initial API of &lt;code&gt;window.ai&lt;/code&gt; provides two methods &lt;code&gt;createTextSession&lt;/code&gt; and &lt;code&gt;createGenericSession&lt;/code&gt; to create a new chat session. I am not aware of the differences between the two as there&#39;s little to no documentation about it, but for now you can go experimenting with them.&lt;/p&gt;
&lt;p&gt;There are methods to verify if a session can be created or not as well. They are named as &lt;code&gt;canCreateTextSession&lt;/code&gt; and &lt;code&gt;canCreateGenericSession&lt;/code&gt;. They return a state which is used to determine when a session can be created. So, for example, if you haven&#39;t downloaded the model locally yet (remember that &lt;code&gt;Optimization Guide On Device Model&lt;/code&gt; component), it will return a state named &lt;code&gt;after-download&lt;/code&gt; which means a session can be created after you download the model.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; aiSession&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; window&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ai&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createTextSession&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; aiSession&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;prompt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;hey, how are you?&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, you can destroy the session by using the &lt;code&gt;destroy()&lt;/code&gt; method on the session created.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;aiSession&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;destroy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I found the output to be pretty slow, but considering the fact that it&#39;s still in its initial stages, things can change, and it can depend on your machine&#39;s resources and configuration as well. The great thing about it is that it works offline as well. And I think that&#39;s the power of built-in AI models, but that does mean you will have to trade-off resources with localization unless the computation power increases.&lt;/p&gt;
&lt;p&gt;Here&#39;s a brief and not so great conversation with the built-in AI in chrome.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1719944888/Syntackle/Posts/chromeAI_abgj17.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1719944888/Syntackle/Posts/chromeAI_abgj17.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1719944888/Syntackle/Posts/chromeAI_abgj17.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1719944888/Syntackle/Posts/chromeAI_abgj17.jpg&quot; alt=&quot;a chat with built-in chrome ai&quot; height=&quot;832&quot; width=&quot;1109&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/window-ai-in-chrome/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Create a Node Server using Hono under 10 Lines of Code</title>
    <link href="https://syntackle.com/blog/node-http-server-using-hono/"/>
    <published>2024-06-30T15:29:32Z</published>
    <updated>2024-06-30T15:29:32Z</updated>
    <id>https://syntackle.com/blog/node-http-server-using-hono/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Hono, as per the docs, was originally built for &lt;a href=&quot;https://hono.dev/docs/concepts/motivation&quot;&gt;Cloudflare Workers&lt;/a&gt;. It&#39;s an application framework designed to work the best for cloudflare pages and workers as well as javascript runtimes Deno and Bun. Although not built specifically for Node, an adapter can be used to run it in Node.&lt;/p&gt;
&lt;p&gt;In this tutorial, you will get to know how you can create a simple HTTP server in Node using Hono in less than 10 lines of code.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot; tabindex=&quot;-1&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Create a bare bones node environment using &lt;code&gt;npm init -y&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-hono&quot; tabindex=&quot;-1&quot;&gt;Setting Up Hono&lt;/h2&gt;
&lt;p&gt;Install hono from &lt;code&gt;npm&lt;/code&gt; along with its nodejs adapter.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; hono&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @hono/node-server&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;creating-a-server&quot; tabindex=&quot;-1&quot;&gt;Creating A Server&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a file named &lt;code&gt;index.mjs&lt;/code&gt; and then, import Hono and its nodejs adapter.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;Hono&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hono&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;serve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@hono/node-server&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Initialize a new Hono app.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Hono&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Handle a simple GET route.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Serve the app using the nodejs adapter.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;serve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`listening on port &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;...`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&#39;s a snippet of all the code combined:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;Hono&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hono&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;serve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@hono/node-server&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Hono&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;serve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`listening on port &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;...`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;One highlight of Hono is its &lt;a href=&quot;https://hono.dev/docs/api/routing#regexp&quot;&gt;Regexp router&lt;/a&gt;. It allows you to define routes which match a regex pattern. Apart from that, it also offers multiple built-in authentication modules for implementing various authentication methods such as &lt;a href=&quot;https://hono.dev/docs/middleware/builtin/basic-auth&quot;&gt;basic&lt;/a&gt;, &lt;a href=&quot;https://hono.dev/docs/middleware/builtin/bearer-auth&quot;&gt;bearer&lt;/a&gt;, and &lt;a href=&quot;https://hono.dev/docs/middleware/builtin/jwt&quot;&gt;jwt&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/node-http-server-using-hono/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Integrate Pagefind&#39;s Search with Astro: A Complete Setup Guide</title>
    <link href="https://syntackle.com/blog/pagefind-search-in-astro-site/"/>
    <published>2024-06-23T17:42:54Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/pagefind-search-in-astro-site/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Pagefind&#39;s take on search is quite simple - index your site at build time and host it alongside your static site. The search index sits right alongside the files of your site and it doesn&#39;t load all the data upfront.&lt;/p&gt;
&lt;p&gt;As mentioned in this &lt;a href=&quot;https://news.ycombinator.com/item?id=32175887&quot;&gt;HN answer&lt;/a&gt;, it only loads relevant search data when you start typing, and you can also load the js client (pagefind.js) conditionally when going for a custom implementation.&lt;/p&gt;
&lt;blockquote class=&quot;&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;With Pagefind, very little is loaded until you type in a search term. Once you start typing, a chunk of the search index is loaded containing your search word(s) and is then queried. This is what drives the performance you&#39;re seeing, which is predominantly the time for the data to load after you start typing — the query step itself is near-instant.&lt;/em&gt; - &lt;a href=&quot;https://news.ycombinator.com/item?id=32175887&quot;&gt;liambigelow on Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With that being said, let&#39;s look at how you can integrate pagefind with your Astro site to implement static, site-wide search.&lt;/p&gt;
&lt;h2 id=&quot;installing-pagefind&quot; tabindex=&quot;-1&quot;&gt;Installing Pagefind &lt;a href=&quot;https://syntackle.com/blog/pagefind-search-in-astro-site/#installing-pagefind&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Install it from a package manager such NPM.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -D&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;building-search-index&quot; tabindex=&quot;-1&quot;&gt;Building Search Index &lt;a href=&quot;https://syntackle.com/blog/pagefind-search-in-astro-site/#building-search-index&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The search index needs to be built at build time in order to query it later. You can do that in your build script itself or you can use a &lt;code&gt;postinstall&lt;/code&gt; script in the file package.json. I prefer to put it in the build script itself.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;build&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;astro build &amp;#x26;&amp;#x26; npx pagefind --site dist&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pagefind also supports a config file named &lt;code&gt;pagefind.yml&lt;/code&gt; which you can use to specify the &lt;a href=&quot;https://pagefind.app/docs/config-options/&quot;&gt;configuration options&lt;/a&gt; instead of specifying it in the cli command. The &lt;code&gt;site&lt;/code&gt; option here specifies the build directory of your project, and the glob option is for only including the files to be parsed to build the search index.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# pagefind.yml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;dist&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;glob&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;**/*.{html}&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The build script can be simplified as:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;build:astro&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;astro build&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;build:pagefind&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npx pagefind&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;build&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npm-run-all -s build:astro build:pagefind&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.npmjs.com/package/npm-run-all&quot;&gt;&lt;code&gt;npm-run-all&lt;/code&gt;&lt;/a&gt; package is a great tool to run cli commands either sequentially or parallelly in a cross-platform way.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This will build the pagefind search index whenever you build your site. But, what about dev mode? Astro won&#39;t access files from your dist folder in dev mode, so you need to copy the pagefind files from the &lt;code&gt;dist&lt;/code&gt; folder into your &lt;code&gt;public&lt;/code&gt; directory (&lt;a href=&quot;https://chrispennington.blog/blog/pagefind-static-search-for-astro-sites/#:~:text=So%20I%E2%80%99d%20recommend,during%20dev%20mode.&quot;&gt;got the idea from this post&lt;/a&gt;) which is used for static files.&lt;/p&gt;
&lt;p&gt;So, you can build the pagefind index, copy it from the &lt;code&gt;dist&lt;/code&gt; to &lt;code&gt;public&lt;/code&gt; directory and then run &lt;code&gt;astro dev&lt;/code&gt;. This way you can get the latest search index but, it still won&#39;t change on hot reload (this is a limitation).&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;If you are starting from scratch, i.e. you don&#39;t have a previous build, then you must build the site first and then run it in dev mode. It&#39;s because pagefind must have a build to build an index upon.&lt;/p&gt;
&lt;/div&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; : {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;copy:pagefind:dev&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npx shx cp -r dist/pagefind public/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;dev:astro&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;astro dev&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;dev&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npm-run-all -s build:pagefind copy:pagefind:dev dev:astro&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;initializing-pagefind&quot; tabindex=&quot;-1&quot;&gt;Initializing Pagefind &lt;a href=&quot;https://syntackle.com/blog/pagefind-search-in-astro-site/#initializing-pagefind&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are two ways in which you can use pagefind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;With pre-built UI&lt;/li&gt;
&lt;li&gt;Custom implementation using Pagefind API&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want to quickly implement search without worrying too much about the layout, you can go with the default UI provided by pagefind. For that, you need to link the js and css files as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;&amp;#x3C;!-- this will work in both dev and prod environments as we have copied the pagefind directory locally --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/pagefind/pagefind-ui.css&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; rel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; is:inline&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/pagefind/pagefind-ui.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then, initializing the PagefindUI:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt;inline&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    window.addEventListener(&#39;DOMContentLoaded&#39;, (event) =&gt; &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; PagefindUI&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;element&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#searchContainer&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    }&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although this seems quick and efficient, I always prefer having more control of the search layout and data. And that&#39;s why I prefer using the Search API provided by pagefind which lets you implement search however you want.&lt;/p&gt;
&lt;h3 id=&quot;using-the-api&quot; tabindex=&quot;-1&quot;&gt;Using the API&lt;/h3&gt;
&lt;p&gt;In order to use the API, you must import a file named &lt;code&gt;pagefind.js&lt;/code&gt; from the &lt;code&gt;pagefind&lt;/code&gt; directory. This file acts as a js client for the API. It&#39;s beneficial to import this file only once when the user focuses on the search input element and store it in a variable for future use.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;focus&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/pagefind/pagefind.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;Wrap the above code in a &lt;code&gt;&amp;lt;script defer&amp;gt;&lt;/code&gt; tag for it to be considered as a client-side script. Astro won&#39;t process and bundle it. It will be shipped to the client as it is. You can also consider the &lt;code&gt;is:inline&lt;/code&gt; attribute.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;init()&lt;/code&gt; method invoked above is for loading core dependencies and metadata about the site. It&#39;s an optional method but, you are pre-loading dependencies when you call it when the element gains focus, instead of it getting automatically invoked when a &lt;code&gt;search&lt;/code&gt; method is called after the user starts typing.&lt;/p&gt;
&lt;p&gt;You can also specify search options before you initialize the pagefind instance:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;focus&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/pagefind/pagefind.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;options&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            ranking&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;                // Decreasing the pageLength parameter is a good way to suppress very short pages that are undesirably ranking higher than longer pages. (max: 1, min: 0)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                pageLength&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, when the user starts typing, you can call the search method as shown below and get the search results:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keydown&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; results&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;search&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;results&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; results&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;excerpt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // do required DOM manipulation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&#39;s a catch. You are firing &lt;code&gt;pagefind.search&lt;/code&gt; on every keydown event, that&#39;s quite expensive because the user is still typing a word but, you are fetching search results for nearly every letter/substring. The solution to this problem is &lt;a href=&quot;https://css-tricks.com/debouncing-throttling-explained-examples/&quot;&gt;debouncing&lt;/a&gt;. You delay the execution of the function of the event up to a certain time by grouping the number of calls made during that time, up until no further event is fired during that time. In short, the search method won&#39;t be fired until the user stops typing after some time.&lt;/p&gt;
&lt;p&gt;I personally use the lodash library for debouncing functionality but pagefind provides a native method of implementing a debounced search, namely, &lt;a href=&quot;https://pagefind.app/docs/api/#debounced-search&quot;&gt;&lt;code&gt;pagefind.debouncedSearch&lt;/code&gt;&lt;/a&gt; and you should definitely check that out.&lt;/p&gt;
&lt;h3 id=&quot;pre-processing-the-script&quot; tabindex=&quot;-1&quot;&gt;Pre-processing the Script&lt;/h3&gt;
&lt;p&gt;If you want Astro to &lt;a href=&quot;https://docs.astro.build/en/guides/client-side-scripts/#script-processing&quot;&gt;bundle and process the script&lt;/a&gt;, or you want to import any npm packages in it, then you will have to make a couple of changes in the script as well as the build process.&lt;/p&gt;
&lt;p&gt;Firstly, all the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags are processed by Astro, unless you add an attribute like &lt;code&gt;is:inline&lt;/code&gt; or &lt;code&gt;defer&lt;/code&gt; to the script, or want to &lt;a href=&quot;https://docs.astro.build/en/guides/client-side-scripts/#opting-out-of-processing&quot;&gt;opt-out of script processing&lt;/a&gt;. So, you will want to remove any of those attributes for the script to be processed.&lt;/p&gt;
&lt;p&gt;Secondly, the dynamic import won&#39;t work. Typescript will complain about it because it can&#39;t resolve it yet as it doesn&#39;t exist yet. You are copying that &lt;code&gt;/pagefind/pagefind.js&lt;/code&gt; after the build to the public directory. So, you need to append a &lt;code&gt;?url&lt;/code&gt; param.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; searchField&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#search&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLInputElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;searchField&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;focus&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/pagefind/pagefind.js?url&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// appending `?url` because typescript will complain about the module not existing &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, if you don&#39;t have a previous build (i.e. if you are starting from scratch), the dynamic &lt;code&gt;/pagefind/pagefind.js?url&lt;/code&gt; import will throw an error when you run &lt;code&gt;npm run build&lt;/code&gt; because rollup won&#39;t be able to resolve that file as it doesn&#39;t exist yet (because we haven&#39;t built pagefind index and copied it to &lt;code&gt;/public&lt;/code&gt; -  that happens after you build). In order to overcome that, you need to declare the dynamic import as an external dependency in rollup config.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  vite&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    build&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      rollupOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        external&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;/pagefind/pagefind.js?url&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, if you are running the site in dev mode without having a previous build, make sure to build the site once for the first time. You can add a new script for that in package.json file: &lt;code&gt;&amp;quot;dev:build&amp;quot;: &amp;quot;npm-run-all -s build dev&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, you can import and use lodash or any npm package in your script.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; lodash&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;lodash&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; searchResults&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#searchResults&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;searchField&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keydown&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;lodash&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;debounce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; results&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; pagefind&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;debouncedSearch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;searchField&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;700&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))?.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;results&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;results&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; results&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;excerpt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;            // DOM manipulation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;700&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was all about using pagefind to implement search in a static site built using astro.&lt;/p&gt;
&lt;h2 id=&quot;bonus&quot; tabindex=&quot;-1&quot;&gt;Bonus&lt;/h2&gt;
&lt;p&gt;Pagefind has some &lt;a href=&quot;https://pagefind.app/docs/metadata/#automatic-metadata&quot;&gt;defaults of selecting the metadata about the page&lt;/a&gt;, for example, it will return the content of the first h1 element on your page as the title of the page. To override that, you can use the &lt;code&gt;data-pagefind-meta&lt;/code&gt; attribute and set it&#39;s value to &lt;code&gt;title&lt;/code&gt; on the element you wish to be returned as the title.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; data-pagefind-meta&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Page&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 21h14&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/posts/murtuzaali-surti_search-functionality-in-syntackle-powered-activity-7108786238035234817-cE7g?utm_source=combined_share_message&amp;amp;utm_medium=member_desktop&quot;&gt;Syntackle itself uses Pagefind for global search&lt;/a&gt;, press Ctrl+K or click the search button to see it in action.&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/pagefind-search-in-astro-site/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Running PostgreSQL using Docker</title>
    <link href="https://syntackle.com/blog/running-postgresql-using-docker/"/>
    <published>2024-06-16T08:42:41Z</published>
    <updated>2024-06-16T08:42:41Z</updated>
    <id>https://syntackle.com/blog/running-postgresql-using-docker/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Running PostgreSQL via Docker is one of the things you can do to quickly try postgresql without installing or configuring it locally. It&#39;s one of the &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#why-use-docker&quot;&gt;benefits of using Docker&lt;/a&gt;. In this quick tutorial, you will get to know how you can run postgresql inside a docker container terminal using &lt;code&gt;psql&lt;/code&gt; (a terminal interface to interact with postgresql databases).&lt;/p&gt;
&lt;h2 id=&quot;pulling-official-postgresql-image&quot; tabindex=&quot;-1&quot;&gt;Pulling Official PostgreSQL Image&lt;/h2&gt;
&lt;p&gt;Pull the official image of postgresql from Docker Hub using the &lt;code&gt;docker pull&lt;/code&gt; command.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pull&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can specify the version of postgresql to pull.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pull&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postgres:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pull&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postgres:16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will create a postgres image. You can verify that using the &lt;code&gt;docker images&lt;/code&gt; command.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; images&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;REPOSITORY&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   TAG&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;       IMAGE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ID&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;       CREATED&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;       SIZE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;postgres&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;     latest&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;    cff6b68a194a&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;   5&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; weeks&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ago&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   432MB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;running-the-image&quot; tabindex=&quot;-1&quot;&gt;Running the Image&lt;/h2&gt;
&lt;p&gt;Running the image means executing the image inside an isolated environment known as a container. It can be done using the &lt;code&gt;docker run&lt;/code&gt; command.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --name&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pgcontainer&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; POSTGRES_PASSWORD=specify_your_password&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -d&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s understand each flag/argument:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--name&lt;/code&gt; :- the name of the container to be created. (example: &lt;code&gt;pgcontainer&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; :- environment variables to be fed into the container (here: &lt;code&gt;POSTGRES_PASSWORD=specify_your_password&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt; :- runs the container in a detached mode (in background) without blocking the terminal.&lt;/li&gt;
&lt;li&gt;the last argument &lt;code&gt;postgres&lt;/code&gt; is the name of the image.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Run &lt;code&gt;docker run --help&lt;/code&gt; for more information.&lt;/p&gt;
&lt;p&gt;You can verify the container is running by using the &lt;code&gt;docker ps&lt;/code&gt; command which will list all the running containers. A status of &lt;code&gt;Up&lt;/code&gt; means the container is up and running.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ps&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# Output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;CONTAINER&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ID&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   IMAGE&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;      COMMAND&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                  CREATED&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;             STATUS&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;             PORTS&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;      NAMES&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;ebeab2ca77e9&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   postgres&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   &quot;docker-entrypoint.s…&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   About&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; an&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; hour&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ago&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   Up&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; About&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; an&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; hour&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   5432/tcp&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;   pgcontainer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;executing-commands-inside-container&quot; tabindex=&quot;-1&quot;&gt;Executing Commands Inside Container&lt;/h2&gt;
&lt;p&gt;You can execute commands inside the container by accessing it&#39;s terminal shell using the &lt;code&gt;docker exec&lt;/code&gt; command. The &lt;code&gt;-it&lt;/code&gt; flag specifies the mode (interactive) in which you want to access the shell. It is meant to keep the input stream alive even if the container is in detached mode. The below command will spin up a &lt;code&gt;psql&lt;/code&gt; instance which you can use to create and interact with databases.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; exec&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -it&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; pgcontainer&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; psql&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -U&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you execute the above command, you can interact with the &lt;code&gt;psql&lt;/code&gt; interface as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;psql&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (16.3 (Debian &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;16.3-1.pgdg120+1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;help&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; help.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;postgres&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;# |&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is just one of the ways you can use postgres&#39; image independently using docker. For more advanced and integrated usage of postgres along with multiple services, consider using &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#running-image-in-a-container:~:text=But%20there%27s%20a,something%20like%20this%3A&quot;&gt;docker compose&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/running-postgresql-using-docker/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Creating My First Web Component: The &lt;back-to-top&gt; Button</title>
    <link href="https://syntackle.com/blog/back-to-top-web-component/"/>
    <published>2024-06-01T16:43:51Z</published>
    <updated>2024-06-09T10:11:32Z</updated>
    <id>https://syntackle.com/blog/back-to-top-web-component/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;I came across the concept of web components, when I saw the word &amp;quot;WebC&amp;quot; in &lt;a href=&quot;https://www.zachleat.com/web/webc-in-eleventy/&quot;&gt;one of the Zach Leatherman&#39;s blog posts&lt;/a&gt;. Then, I came to know that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;WebC is a framework-independent standalone HTML compiler for generating markup for web components.&lt;/em&gt; - &lt;a href=&quot;https://www.zachleat.com/web/webc-in-eleventy/#the-age-of-webc-+-eleventy&quot;&gt;zachleat.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That ignited a spark of curiosity within me and I started reading and researching more about web components. Eventually, after realizing you can build and define custom HTML elements, I decided to build at least one of my own.&lt;/p&gt;
&lt;p&gt;It&#39;s alright if you didn&#39;t already know about &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/&quot;&gt;custom elements&lt;/a&gt; or web components until you came here (and I think for most entry-level developers, that is the case), but I assure you that you will find the world of web components fascinating.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you want to learn more about the basics of web components and custom elements, I &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/&quot;&gt;wrote a post&lt;/a&gt; explaining what they are.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You might have seen &amp;quot;back to top&amp;quot; buttons/links on some web pages(especially those which contain long form articles) which take you to the top of the page on a click. I took the functionality of those buttons and moved it in a re-usable web component. In this post, I will walk you through the process of how I built a &lt;code&gt;&amp;lt;back-to-top&amp;gt;&lt;/code&gt; web component.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;find-it-here-%F0%9F%93%A6&quot; tabindex=&quot;-1&quot;&gt;Find it here 📦&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt; - &lt;a href=&quot;https://github.com/murtuzaalisurti/back-to-top/blob/main/README.md&quot;&gt;github.com/murtuzaalisurti/back-to-top&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NPM&lt;/strong&gt;: &lt;a href=&quot;https://www.npmjs.com/package/@murtuzaalisurti/back-to-top&quot;&gt;@murtuzaalisurti/back-to-top&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;building-v1.0&quot; tabindex=&quot;-1&quot;&gt;Building v1.0&lt;/h2&gt;
&lt;p&gt;Custom elements can be defined in &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/#types-of-custom-elements&quot;&gt;two ways&lt;/a&gt; - by extending an existing HTML element class such as a button (&lt;code&gt;HTMLButtonElement&lt;/code&gt;) or by extending the generic &lt;code&gt;HTMLElement&lt;/code&gt; class. If you go the first route, you get all of the properties of a button element when you call the &lt;code&gt;super()&lt;/code&gt; method in the constructor but you lose the ability to attach a shadow DOM to that custom element since shadow DOM is only supported by certain elements.&lt;/p&gt;
&lt;p&gt;Despite the limitations, I decided to go with a customized built-in custom element a.k.a the element which extends a specific class of the element to be used - in my case, a button.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; BackToTop&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLButtonElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;        super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // properties&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // inspired by David Darnes&#39; component template - https://github.com/daviddarnes/component-template&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; register&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;tagName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;extendsElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;customElements&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; window&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;extendsElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;tagName&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;back-to-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;BackToTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;extends&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;extendsElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// you must specify extends option while defining a customized built-in element&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;tagName&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;back-to-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;BackToTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;BackToTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;register&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;back-to-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For event throttling, lodash seemed to be the best option because it allows you to create a custom build specific to your functionality. If you only want the &lt;code&gt;throttle&lt;/code&gt; or &lt;code&gt;debounce&lt;/code&gt; module, then you can get it by using:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;lodash&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; include=throttle,debounce&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The lodash custom build file gets imported in the web component file by a build step I perform using esbuild.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;./lodash.custom.min.js&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; BackToTop&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLButtonElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;        super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lodash is used to throttle the position calculation function in order to show/hide the &amp;quot;back to top&amp;quot; button.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;handleThrottle&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; _&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;throttle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; prevScrollPos&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;documentElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;scrollTop&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        window&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;scrollY&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;scrollTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentScrollPos&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;=&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; prevScrollPos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        ?&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;#hidden&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        :&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;#show&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentScrollPos&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; prevScrollPos&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentScrollPos&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;#hidden&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;connectedCallback&lt;/code&gt; method is executed once the web component class is instantiated, but there&#39;s also &lt;code&gt;disconnectedCallback&lt;/code&gt; which fires when the component is removed from the document. So, make sure to remove any listeners you have attached to the element inside this method.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;disconnectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    window&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;removeEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scroll&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;handleThrottle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;removeEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;handleClick&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can find the code for &lt;a href=&quot;https://www.npmjs.com/package/@murtuzaalisurti/back-to-top/v/1.0.2?activeTab=code&quot;&gt;v1.0&lt;/a&gt; on npm.&lt;/p&gt;
&lt;h2 id=&quot;building-v2.0&quot; tabindex=&quot;-1&quot;&gt;Building v2.0&lt;/h2&gt;
&lt;p&gt;After publishing the first version, I got wonderful &lt;a href=&quot;https://github.com/murtuzaalisurti/back-to-top/issues/1&quot;&gt;responses&lt;/a&gt; and &lt;a href=&quot;https://mastodon.social/@murtuzaalisurti/112506527451507068&quot;&gt;ideas&lt;/a&gt; from the community. One of them was to use an autonomous custom element (extending the generic &lt;code&gt;HTMLElement&lt;/code&gt; class) because &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is#browser_compatibility&quot;&gt;Safari doesn&#39;t yet support the &lt;code&gt;is&lt;/code&gt; attribute&lt;/a&gt; required for customized built-in elements to work. This forced me to rewrite the component as an autonomous custom element by using a wrapper around the button element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; BackToTop&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;        super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // properties&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; register&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;tagName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;customElements&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; window&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;tagName&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;back-to-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;BackToTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;BackToTop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;register&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Previously, the throttling rate was hardcoded inside the component, but with v2.0, the &lt;code&gt;throttle&lt;/code&gt; attribute was introduced to let users input a custom throttle rate measured in milliseconds. To handle attributes and their updates, you must define the attributes you want to watch in an &lt;code&gt;observedAttributes&lt;/code&gt; static property. You can listen to the updates on those defined attributes using the &lt;code&gt;attributeChangedCallback&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;You can store the value of the attribute in a class property. It&#39;s important to keep in sync the property and the attribute by setting the value of the property whenever the attribute value is modified.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; BackToTop&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;        super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;throttleRate&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 400&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// milliseconds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // defining which attributes to observe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    static&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; get&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; observedAttributes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;throttle&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // getter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    get&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getThrottleRate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;throttleRate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // setter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    set&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; setThrottleRate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;throttleRate&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // observing the &quot;throttle&quot; attribute&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    attributeChangedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;oldVal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;newVal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;throttle&quot;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;setThrottleRate&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; newVal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;handleThrottle&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;throttledFunction&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;getThrottleRate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those were the main points I wanted to cover in this post which were crucial to building this component. Obviously, this is not the entirety of code. Check out the entire code on &lt;a href=&quot;https://github.com/murtuzaalisurti/back-to-top&quot;&gt;GitHub&lt;/a&gt; and see the web component in action below:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;gOJLQKW&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/gOJLQKW&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;h2 id=&quot;one-last-thing&quot; tabindex=&quot;-1&quot;&gt;One Last Thing&lt;/h2&gt;
&lt;p&gt;With all of the refactoring, the component still relies on javascript to render the button because of this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is why, this can&#39;t be called an &lt;a href=&quot;https://blog.jim-nielsen.com/2023/html-web-components-an-example/&quot;&gt;HTML web component&lt;/a&gt; because it doesn&#39;t fallback to anything when javascript can&#39;t execute. Now that I know about the approach of HTML web components, they have started making more sense to me as they would fallback to basic HTML behavior in absence of javascript execution. That gives me the motivation to build &lt;code&gt;v3.0&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;UPDATE: &lt;a href=&quot;https://github.com/murtuzaalisurti/back-to-top/releases/tag/v3.0.3&quot;&gt;v3.0&lt;/a&gt; is here and it now supports a fallback anchor link and customizable button content. You can update your component definition as shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;back-to-top&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; throttle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;350&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;position: fixed; left: 1rem; bottom: 2rem;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;back-to-top&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;     button content here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;back-to-top&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/back-to-top-web-component/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>React 19 - A Brief Look At Form Handling</title>
    <link href="https://syntackle.com/blog/form-handling-in-react-19/"/>
    <published>2024-05-18T11:06:27Z</published>
    <updated>2025-10-11T16:14:09Z</updated>
    <id>https://syntackle.com/blog/form-handling-in-react-19/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;React 19 is finally here with it&#39;s &lt;a href=&quot;https://react.dev/blog/2024/12/05/react-19&quot;&gt;stable release&lt;/a&gt; and it brings with it the support for &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/&quot;&gt;custom elements&lt;/a&gt; (yayy! 🎉), better form handling with some new hooks and numerous improvements.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An open source &lt;a href=&quot;https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024#react-compiler&quot;&gt;react compiler&lt;/a&gt; is also in the works (&lt;a href=&quot;https://syntackle.com/blog/integrating-react-compiler-with-astro/&quot;&gt;v1 released, learn how to integrate&lt;/a&gt;) - a version of which is being used by Instagram!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Want to master React and get a deep understanding of it&#39;s fundamentals? This &lt;a href=&quot;https://www.amazon.in/Road-Learn-React-Pragmatic-React-Js/dp/172004399X?crid=21RSEEI4UHFQM&amp;amp;dib=eyJ2IjoiMSJ9.WtrXHJ8LPAlHDVF-askoJkDJSzCU0Fy6FzMT6Y9Zg5RBzB3hImavfzKhdF70oLSnpR8hPKiMC5MgBHHrfcAtrlNmRm3lcZjpcEbtv7V8pMcz6bNT3gte9K1tHB9Ry_70yaix6PFx7__bZCkyM9fQiX4rxQD-k-urNGtcIDZPXxtqDONFPZEumoRGbKX25knL._5_4gELCOvAN6YSYihVUEo0k78QekOI6OkgaGK_7ibE&amp;amp;dib_tag=se&amp;amp;keywords=road+to+react&amp;amp;qid=1736063926&amp;amp;sprefix=road+to+react%2Caps%2C234&amp;amp;sr=8-2&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=54a43f468930df582f553167693f7f9b&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;book by Robin Wieruch&lt;/a&gt; is a must read.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;installing-react-19&quot; tabindex=&quot;-1&quot;&gt;Installing React 19 &lt;a href=&quot;https://syntackle.com/blog/form-handling-in-react-19/#installing-react-19&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Vite can be used to test React 19 release locally.&lt;/p&gt;
&lt;p&gt;Now, React 19 is the default version of React if you scaffold a vite project. So, simply use the &lt;a href=&quot;https://github.com/vitejs/vite/tree/main/packages/create-vite&quot;&gt;&lt;code&gt;create-vite&lt;/code&gt;&lt;/a&gt; tool to create a new React project with React 19.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; vite@latest&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; react-app-name&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --template&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; react&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M9 18h6&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 22h4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Pro Tip&lt;/p&gt;
&lt;p&gt;If you want to integrate react compiler (of which v1 was released recently), follow this guide on &lt;a href=&quot;https://syntackle.com/blog/integrating-react-compiler-with-astro/&quot;&gt;how to integrate react compiler with React 17+&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/36994564/how-can-one-tell-the-version-of-react-running-at-runtime-in-the-browser#comment106830911_36994564&quot;&gt;Checking the version of React&lt;/a&gt; in the browser console can also be performed using &lt;code&gt;__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values().next()[&amp;quot;value&amp;quot;][&amp;quot;version&amp;quot;]&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// https://stackoverflow.com/questions/36994564/how-can-one-tell-the-version-of-react-running-at-runtime-in-the-browser#comment106830911_36994564&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    __REACT_DEVTOOLS_GLOBAL_HOOK__&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;renderers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;form-actions-in-react&quot; tabindex=&quot;-1&quot;&gt;Form Actions in React &lt;a href=&quot;https://syntackle.com/blog/form-handling-in-react-19/#form-actions-in-react&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Forms in &lt;a href=&quot;https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/&quot;&gt;React&lt;/a&gt; have always been not so easy to handle, which often leads to messy React code. Ultimately, folks have to resort to form handling libraries which only add more abstraction in the process.&lt;/p&gt;
&lt;p&gt;One of the things I like about React 19 is the ability to handle form states. Of all the new hooks introduced for forms in React 19, I personally like the &lt;code&gt;useActionState&lt;/code&gt; hook used to handle basic forms.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;useActionState&lt;/code&gt; hook exposes a function named &lt;code&gt;submitAction&lt;/code&gt; which can be passed to the &lt;code&gt;action&lt;/code&gt; attribute of the HTML &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element. It also accepts an initial state and a permalink value which I haven&#39;t tried yet, but &lt;a href=&quot;https://react.dev/reference/react/useActionState#parameters&quot;&gt;the documentation states&lt;/a&gt; that it is for passing the state to another URL.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// useActionState: (fn, initialState, permalink?) =&gt; [state, submitAction, isPending]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;submitAction&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;isPending&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useActionState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;previousState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;formData&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; updateSomething&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;formData&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;    null&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // initial state&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the above function in place, you have to now pass the &lt;code&gt;submitAction&lt;/code&gt; function returned from the &lt;a href=&quot;https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/&quot;&gt;hook&lt;/a&gt; to the &lt;code&gt;action&lt;/code&gt; attribute of the &lt;code&gt;form&lt;/code&gt; element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;{submitAction}&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; disabled&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;{isPending}&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Update&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The most helpful thing about this is that you get an &lt;code&gt;isPending&lt;/code&gt; state which is a boolean allowing you to determine the state of the submission without having to manage it through React&#39;s &lt;code&gt;useState&lt;/code&gt;. The same is true for form errors. If it&#39;s a validation error or a network error, you can send it with the response state that you are getting from the &lt;code&gt;useActionState&lt;/code&gt; hook and use it in your JSX. The UI will update itself automatically on the response of that hook.&lt;/p&gt;
&lt;h2 id=&quot;wrapping-it-in-a-custom-hook&quot; tabindex=&quot;-1&quot;&gt;Wrapping it in a Custom Hook &lt;a href=&quot;https://syntackle.com/blog/form-handling-in-react-19/#wrapping-it-in-a-custom-hook&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to make it re-usable, you might want to wrap it in a custom hook which you can share between multiple forms. The name of the custom hook can be something like &lt;code&gt;useFormHandler&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;useActionState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;react&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useFormHandler&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;callback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;initialState&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;permalink&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; formState&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useActionState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;previousState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;formData&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;formData&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    previousState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;OK&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    previousState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        initialState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        permalink&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; permalink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        formState&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; useFormHandler&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above custom hook accepts a callback function which is for you to handle the async network requests and validations. It accepts an initial state which you can pass if you want to, otherwise it defaults to &lt;code&gt;null&lt;/code&gt;. And lastly, a permalink which we discussed earlier. It returns the array returned by the &lt;code&gt;useActionState&lt;/code&gt; hook - &lt;code&gt;[state, submitAction, isPending]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Use it by passing an async callback which handles the requests.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; useFormHandler&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;./hooks/formHandler&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; saveChanges&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;            // ... do something with the data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            resolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            reject&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;formState&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; useFormHandler&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;saveChanges&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;submitAction&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;isPending&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; formState&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The use case for creating a custom hook is to add more validations and checks for the form data and to standardize the response state received from the &lt;code&gt;useActionState&lt;/code&gt; hook.&lt;/p&gt;
&lt;h2 id=&quot;some-more-hooks&quot; tabindex=&quot;-1&quot;&gt;Some more hooks&lt;/h2&gt;
&lt;p&gt;React 19 also introduced some more hooks such as &lt;code&gt;useFormStatus&lt;/code&gt; and &lt;code&gt;useOptimistic&lt;/code&gt; but I don&#39;t have a clear idea on what their best use case can be. Let&#39;s hope that with the introduction of newer hooks, the hooks land doesn&#39;t become cluttered and murkier than before.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It’s a funny conundrum. Why do we refactor? Because the code got too complicated. So we simplify it. And why do we simplify it? So we can add more to it over time and make it more complex again.&lt;/em&gt; - &lt;a href=&quot;https://blog.jim-nielsen.com/2024/notes-on-making-software-by-peter-van-hardenberg/&quot;&gt;Jim Nielsen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/form-handling-in-react-19/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Static Sites Are Good</title>
    <link href="https://syntackle.com/blog/static-sites-are-good/"/>
    <published>2024-03-24T05:33:54Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/static-sites-are-good/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Gone are the days when you had to wait for quite a long time to fetch a server rendered HTML page. Single page applications (SPA) try to solve this problem by handling the HTML rendering entirely with client-side javascript. But, too much of anything is harmful.&lt;/p&gt;
&lt;p&gt;It&#39;s true that javascript is meant to manipulate the &lt;a href=&quot;https://syntackle.com/blog/what-is-dom-diffing-bB8Ltf/&quot;&gt;DOM&lt;/a&gt; programmatically, however if you send too much of it to the client, it takes a hit on performance. And, &lt;em&gt;we are back to where it all started&lt;/em&gt;. SPAs were meant to improve performance (and they do up to a certain extent) but, their current implementation &lt;a href=&quot;https://www.matuzo.at/blog/2023/single-page-applications-criticism/&quot;&gt;does the opposite&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Not only that, SPAs are no good for accessibility and SEO as well. This doesn&#39;t mean you can&#39;t implement accessibility in SPAs, its just that &lt;a href=&quot;https://a11y-guidelines.orange.com/en/articles/single-page-app/&quot;&gt;it&#39;s hard&lt;/a&gt; — considering the fact that the HTML content is dynamically altered using javascript. For SEO, search engine crawlers can&#39;t find the rendered &lt;a href=&quot;https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/&quot;&gt;HTML&lt;/a&gt; content without executing javascript and that&#39;s not good.&lt;/p&gt;
&lt;p&gt;This leads to a couple of questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How do you find a balance between HTML and Javascript?&lt;/li&gt;
&lt;li&gt;Are SPAs bad for everything?&lt;/li&gt;
&lt;li&gt;What strategy can improve the performance while still using some javascript?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;static-first-approach&quot; tabindex=&quot;-1&quot;&gt;Static First Approach&lt;/h2&gt;
&lt;p&gt;The idea is simple — you build your &lt;em&gt;&amp;quot;staticky&amp;quot;&lt;/em&gt; content (which is &lt;em&gt;not&lt;/em&gt; meant to be interactive) at build time, host it somewhere on the cloud and then serve that as an HTML page to the client. Parts which do need some interactivity can be &lt;a href=&quot;https://archive.hankchizljaw.com/wrote/the-power-of-progressive-enhancement/&quot;&gt;progressively enhanced&lt;/a&gt; using javascript.&lt;/p&gt;
&lt;p&gt;Progressive enhancement is a concept where you send a minimum viable experience (wonderful analogy by &lt;a href=&quot;https://piccalil.li/about/&quot;&gt;Andy Bell&lt;/a&gt;) to the client which works even without javascript. And once javascript is available, you enhance the experience.&lt;/p&gt;
&lt;p&gt;For example, for a blog, you can build the static content and &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/&quot;&gt;components&lt;/a&gt; such as headers and footers at build time and then use some javascript (if you need to) for enhancing the button click of a newsletter CTA.&lt;/p&gt;
&lt;p&gt;I discussed the simplicity of static sites, Jamstack, it&#39;s future and it&#39;s meaning with &lt;a href=&quot;https://www.linkedin.com/in/mikeneumegen&quot;&gt;Mike Neumegen&lt;/a&gt; on &lt;code&gt;#thefutureofjamstack&lt;/code&gt;. We also talked about what should be the new name for Jamstack and it was fun. Catch the full talk &lt;a href=&quot;https://www.youtube.com/watch?v=2Oxu4y-RLrs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;2Oxu4y-RLrs&quot; title=&quot;The voice of simplicity with Murtuzaali Surti - What the Jam&quot; playlabel=&quot;The voice of simplicity with Murtuzaali Surti - What the Jam&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;spas-are-not-bad-for-everything&quot; tabindex=&quot;-1&quot;&gt;SPAs Are Not Bad For Everything&lt;/h2&gt;
&lt;p&gt;There are certain use cases where you need a lot of interactivity and state management, for example a video calling app or an enterprise web application involving a lot of complex components which talk to each other.&lt;/p&gt;
&lt;p&gt;However, in this case also, you should go for a hybrid approach where you server render as much as you can (using &lt;a href=&quot;https://www.joshwcomeau.com/react/server-components/&quot;&gt;server side rendering&lt;/a&gt;) and leave the rest for javascript.&lt;/p&gt;
&lt;h2 id=&quot;the-best-strategy&quot; tabindex=&quot;-1&quot;&gt;The Best Strategy&lt;/h2&gt;
&lt;p&gt;Honestly, there is no universal best strategy. It all depends on your use case and what you are trying to build. Finding the right approach is the first thing you should do when &lt;a href=&quot;https://youtu.be/7nG-x3Fs3oY?feature=shared&quot;&gt;building a project&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;7nG-x3Fs3oY&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;For the most part, static-first sites are the go to thing if your application doesn&#39;t involve much complexity. However, you are free to choose the right tool for your application — but choose wisely.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/static-sites-are-good/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Quokka in VS Code — JavaScript Debugging Made Simpler</title>
    <link href="https://syntackle.com/blog/quokka-js-one-of-the-best-vs-code-extensions-for-javascript/"/>
    <published>2024-03-03T11:21:00Z</published>
    <updated>2024-03-03T13:57:25Z</updated>
    <id>https://syntackle.com/blog/quokka-js-one-of-the-best-vs-code-extensions-for-javascript/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;!-- markdownlint-disable MD034 --&gt;
&lt;p&gt;Quokka.js is an awesome tool for prototyping your javascript code with the power of an instant inline output. It lets you code and see the output as you type and is really beneficial if you want to quickly test something out.&lt;/p&gt;
&lt;p&gt;What makes it more powerful is a &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=WallabyJs.quokka-vscode&quot;&gt;VS Code extension&lt;/a&gt; which you can use to instantly create a new javascript file with quokka running on it. Quokka only runs in node, so you won&#39;t get to use browser specific APIs when running it, however the official documentation says it&#39;s possible with the use of &lt;a href=&quot;https://quokkajs.com/docs/index.html#browser-like-runtime&quot;&gt;jsdom and a little bit of configuration&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-it-in-a-new-file&quot; tabindex=&quot;-1&quot;&gt;Using It In A New File&lt;/h2&gt;
&lt;p&gt;Once you do install the extension, doing a &lt;code&gt;CTRL + SHIFT + P&lt;/code&gt; and typing Quokka will give you an option to create a new javascript file.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_gif,q_auto:eco/v1709370614/Syntackle/Posts/quokkajs-demo.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;quokkajs demo&quot; height=&quot;342&quot; width=&quot;635&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Quokkajs in VS Code&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;This gives you the ability to run javascript without even needing to do &lt;code&gt;node .&lt;/code&gt; or use something like &lt;code&gt;nodemon&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-it-on-an-existing-file&quot; tabindex=&quot;-1&quot;&gt;Using It On An Existing File&lt;/h2&gt;
&lt;p&gt;Using it on an existing file works for the most part, however I didn&#39;t get inline output while doing this. The output just shows up in the &lt;code&gt;Output&lt;/code&gt; panel of VS Code.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_gif,q_auto:eco/v1709461674/Syntackle/Posts/quokka-on-existing-file.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;quokka on an existing file&quot; height=&quot;958&quot; width=&quot;1823&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;running quokkajs on an existing file&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The better alternative for experiencing this type of stuff on a project level is &lt;em&gt;Wallaby.js&lt;/em&gt;. &lt;a href=&quot;https://wallabyjs.com/&quot;&gt;Wallaby.js&lt;/a&gt; as per the official documentation is a test runner which operates on a project level.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Simply put, Wallaby.js is a test runner while Quokka.js is a scratchpad / playground.&amp;quot;&lt;/em&gt; - &lt;a href=&quot;https://quokkajs.com/docs/quokka-vs-wallaby.html&quot;&gt;quokkajs.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I haven&#39;t had a chance to use &lt;em&gt;Wallaby.js&lt;/em&gt; but I still use &lt;em&gt;Quokka.js&lt;/em&gt; whenever I need to test a piece of javascript code or just a concept which would later be a part of the project. Although both of them are run by the same entity, there are more differences between them than overlap.&lt;/p&gt;
&lt;p&gt;Anyways, I would go for &lt;em&gt;Quokka.js&lt;/em&gt; to quickly test a small piece of code and see what it does anytime.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/quokka-js-one-of-the-best-vs-code-extensions-for-javascript/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Issue With Watching File Changes in Docker</title>
    <link href="https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/"/>
    <published>2024-02-13T16:39:03Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Days ago, I was struggling to get live reloading/hot reloading (HMR) working for the code mounted in a docker volume on Windows. Volumes in docker serve the purpose of persistence — which means you can sync the container data with your local data. That works really well, but the catch comes when you want real time sync between both the locations of code — your local filesystem and docker&#39;s filesystem.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot; tabindex=&quot;-1&quot;&gt;The Problem &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/#the-problem&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Different operating systems have different implementations of handling file events, example MacOS has the &lt;code&gt;FSEvents&lt;/code&gt; API, linux has something known as &lt;code&gt;inotify&lt;/code&gt; and Windows has the &lt;code&gt;FileSystemWatcher&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/16048358/17241798&quot;&gt;Docker uses it&#39;s own filesystem&lt;/a&gt; and it&#39;s not necessary that your system&#39;s filesystem matches docker&#39;s. Thus, the file event handling APIs available on your system might not be available in a docker container. For example, the &lt;code&gt;FSEvents&lt;/code&gt; API of MacOS is not available in a linux environment. Now, maybe I am missing some details here but, this might cause some discrepancies in how those file events are handled — if they are even handled at all. This can cause hot/live reloading to not work at all if you update your local code mounted on a volume.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I noticed this issue on Windows, so not sure about how this should be affecting other platforms.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;the-fix&quot; tabindex=&quot;-1&quot;&gt;The Fix &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/#the-fix&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The fix to watching file changes in docker is to use &lt;em&gt;polling&lt;/em&gt;. &lt;a href=&quot;https://en.wikipedia.org/wiki/Polling_(computer_science)&quot;&gt;Polling&lt;/a&gt; is a way to periodically check for changes that may have taken place. In polling you don&#39;t get notified, you keep checking the state over a network. Over the network approach works for docker because now you don&#39;t have to deal with the file system notifications, you can listen on the changes over the network.&lt;/p&gt;
&lt;p&gt;If you are using a bundler such as &lt;code&gt;webpack&lt;/code&gt; or any other developer tool such as &lt;code&gt;gulp&lt;/code&gt;, &lt;code&gt;browser-sync&lt;/code&gt; or &lt;code&gt;livereload&lt;/code&gt;, they all use a cross platform file watcher named &lt;a href=&quot;https://www.npmjs.com/browse/depended/chokidar&quot;&gt;&lt;code&gt;chokidar&lt;/code&gt;&lt;/a&gt;. Chokidar relies on the &lt;code&gt;nodejs&lt;/code&gt;&#39;s file system API but it improves upon the nodejs&#39; API. Chokidar &lt;a href=&quot;https://github.com/paulmillr/chokidar/tree/master?tab=readme-ov-file#how&quot;&gt;supports polling&lt;/a&gt; and you can also set the polling interval.&lt;/p&gt;
&lt;p&gt;Here&#39;s an example of how you can use polling when using gulp:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;gulp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;watch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;path&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    interval&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    usePolling&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;task&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;drawback-of-polling&quot; tabindex=&quot;-1&quot;&gt;Drawback Of Polling &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/#drawback-of-polling&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The only reason polling is bad is that it&#39;s slow and consumes lot of CPU resources. If you have &lt;a href=&quot;https://github.com/dotansimha/graphql-code-generator/issues/1796&quot;&gt;too many source files to watch for&lt;/a&gt; and you don&#39;t want to allocate more space, then polling is not a way forward. Quoting a wonderful analogy about polling from Raymond Chen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;It’s like checking your watch every minute to see if it’s 3 o’clock yet instead of just setting an alarm.&amp;quot; - &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20060124-17/?p=32553&quot;&gt;Raymond Chen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Learn more about the &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20060124-17/?p=32553&quot;&gt;performance consequences of polling&lt;/a&gt; on &amp;quot;The Old New Thing&amp;quot; — written by Raymond Chen.&lt;/p&gt;
&lt;h2 id=&quot;an-alternative-docker-compose-watch&quot; tabindex=&quot;-1&quot;&gt;An Alternative — Docker Compose Watch &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/#an-alternative-docker-compose-watch&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you want to avoid polling, docker provides a way to watch file changes with the help of &lt;a href=&quot;https://docs.docker.com/compose/file-watch/&quot;&gt;&#39;docker compose watch&#39;&lt;/a&gt;. I removed volumes in lieu of this new &lt;code&gt;watch&lt;/code&gt; option which is available in docker compose version 2.22 and later.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# docker-compose.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    your_service_name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        build&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            context&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            dockerfile&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        env_file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            - &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;./.env&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # path to env file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        command&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npm run dev&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        develop&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            watch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                - &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;action&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;sync&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # &#39;build&#39; is another action type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                  path&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;./src&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # host directory path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                  target&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;/app/src&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; # container directory path to map&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                  ignore&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    - &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;node_modules/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        ports&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            - &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;127.0.0.1:3000:3000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, you also need to create a &lt;code&gt;USER&lt;/code&gt; which can edit files inside the container. The best practice is to create a non-privileged user and assigning that user as an owner of those copied files.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;# Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; node:20-alpine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; apk add --no-cache shadow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; useradd -ms /bin/sh -u 1001 app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;USER&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;COPY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; --chown=app:app . /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;WORKDIR&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; npm install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;For alpine linux, to be able to use &lt;code&gt;useradd&lt;/code&gt;, you need to install the shadow package in your image using &lt;code&gt;RUN apk add --no-cache shadow&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This approach works but personally I didn&#39;t find any significant performance improvement over polling. At the time of this writing, docker compose watch functionality has a bug which occurs when you terminate the &lt;code&gt;watch&lt;/code&gt; command. You can&#39;t run the watch command again due to this bug. Follow the steps mentioned in this &lt;a href=&quot;https://github.com/docker/compose/issues/11069#issuecomment-1769694535&quot;&gt;github issue comment&lt;/a&gt; to get the watch command running again.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I don&#39;t know how &lt;code&gt;docker compose watch&lt;/code&gt; works under the hood and does it use polling as well, but it&#39;s clear that now you have two approaches to get file watch working in a docker container. A slight advantage of using &lt;code&gt;docker compose watch&lt;/code&gt; is that you can also add an action named &lt;code&gt;build&lt;/code&gt; which will rebuild the image and container. For example, you can rebuild the image on the &lt;code&gt;package.json&lt;/code&gt; file change.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Chrome 121 Broke My CSS By Adopting New Scrollbar Properties</title>
    <link href="https://syntackle.com/blog/changes-to-scrollbar-styling-in-chrome-121/"/>
    <published>2024-01-26T06:32:34Z</published>
    <updated>2024-02-03T07:07:25Z</updated>
    <id>https://syntackle.com/blog/changes-to-scrollbar-styling-in-chrome-121/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Recently, in version 121, Chrome started supporting standardized CSS scrollbar properties &lt;code&gt;scrollbar-color&lt;/code&gt; and &lt;code&gt;scrollbar-width&lt;/code&gt; mentioned in the &lt;a href=&quot;https://drafts.csswg.org/css-scrollbars/&quot;&gt;CSS specification&lt;/a&gt; and it broke my CSS. Here&#39;s what happened and how I fixed it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR — Quick Fix&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/* Wrap new scrollbar properties in @supports rule for browsers without `::-webkit-scrollbar-*` support */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/* This way chrome won&#39;t override `::-webkit-scrollbar-*` selectors */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;@supports&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; selector(::-webkit-scrollbar) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      scrollbar-width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;thin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      scrollbar-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--thumb-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--track-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;I always feel scrollbars on a website seem off if the site is designed with consistency and a little bit creativity. They don&#39;t always match the theme of the site. Some people prefer it that way and that&#39;s okay but I want scrollbars to feel like an integral part of the website itself. And so, I styled the scrollbars for syntackle a while ago to match the current theme.&lt;/p&gt;
&lt;p&gt;Back then, Chrome didn&#39;t support &lt;code&gt;scrollbar-color&lt;/code&gt; and &lt;code&gt;scrollbar-width&lt;/code&gt; properties but it did have the &lt;code&gt;::-webkit-*&lt;/code&gt; pseudo selectors exposed, so I used them to create a custom scrollbar experience. But &lt;code&gt;webkit&lt;/code&gt; is only supported on Chrome and Safari, not firefox. To mitigate this, I resorted to the new scrollbar properties for firefox.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    scrollbar-width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;thin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    scrollbar-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#6d7c77&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #cfd7c7&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar-thumb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--tertiary-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar-track&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--primary-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason I attached the &lt;code&gt;::-webkit-*&lt;/code&gt; pseudo selectors on the body is that I control the theme of the site using CSS variables on the &lt;code&gt;body&lt;/code&gt; element and by altering the CSS classes through javascript.&lt;/p&gt;
&lt;p&gt;And this broke the scrollbar styling with Chrome 121. It seems that Chrome now prefers the new scrollbar properties on the &lt;code&gt;html&lt;/code&gt; element over the &lt;code&gt;::-webkit-*&lt;/code&gt; pseudo selectors.&lt;/p&gt;
&lt;p&gt;One thing that you could do is attach the new scrollbar properties to the &lt;code&gt;body&lt;/code&gt; element instead of &lt;code&gt;html&lt;/code&gt;, it works in Chrome but firefox doesn&#39;t seem to support that.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    scrollbar-width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;thin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    scrollbar-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#6d7c77&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #cfd7c7&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I researched a bit online and found out that recently Chrome published a &lt;a href=&quot;https://developer.chrome.com/docs/css-ui/scrollbar-styling&quot;&gt;blog post&lt;/a&gt; related to this change. There&#39;s a whole topic of overlay scrollbars and the impact of operating system on the scrollbar which you can deep dive into. But a quick fix which you can do is for the browsers that don&#39;t support &lt;code&gt;::-webkit-*&lt;/code&gt; pseudo selectors, add a &lt;code&gt;@supports&lt;/code&gt; rule check and add the new scrollbar properties there.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar-thumb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--tertiary-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;::-webkit-scrollbar-track&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--primary-color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;/* Browsers without `::-webkit-scrollbar-*` support */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;@supports&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; selector(::-webkit-scrollbar) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        scrollbar-width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;thin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        scrollbar-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#6d7c77&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #cfd7c7&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For me, I still like to have control over the scrollbar styling and that&#39;s why I prefer &lt;code&gt;webkit&lt;/code&gt; pseudo selectors over new properties but that&#39;s just a personal preference. The CSS specification considers exposing &lt;code&gt;::-webkit-*&lt;/code&gt; pseudo selectors as &lt;a href=&quot;https://drafts.csswg.org/css-scrollbars/#out-of-scope&quot;&gt;a mistake&lt;/a&gt; and have standardized the styling of scrollbar because of different platforms implementing it in different ways.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;Providing too much control would allow authors to get perfect results on some platforms, but at the expense of broken results on others.&amp;quot;&lt;/em&gt; - &lt;a href=&quot;https://drafts.csswg.org/css-scrollbars/#out-of-scope&quot;&gt;drafts.csswg.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With that being said, I am not encouraging you to use the webkit selectors and you should always look out for standardized properties first and see if that works for you.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/changes-to-scrollbar-styling-in-chrome-121/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>rssed — An RSS Feed Reader And Blogroll - Built Using Astro</title>
    <link href="https://syntackle.com/blog/blogroll-using-astro/"/>
    <published>2024-01-21T18:30:31Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/blogroll-using-astro/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;RSS a.k.a Really Simple Syndication is a great technology to subscribe to website content. You can get the latest updates published on a website by parsing the RSS feed. It uses XML to present the data and meta information about the content.&lt;/p&gt;
&lt;p&gt;A huge number of software developers have their own blog where they publish posts about programming and software development regularly. Initially, I was bookmarking blogs which I admire and used to visit them once in a while. But that wasn&#39;t practical enough. I was missing on beneficial updates and news of what was happening in the software world.&lt;/p&gt;
&lt;p&gt;So, I decided to keep track of all of those blogs using a blogroll — a collection of links to other sites or blogs — which updates itself on a daily basis. With the help of an &lt;a href=&quot;https://github.com/rbren/rss-parser/&quot;&gt;rss parser&lt;/a&gt;, &lt;a href=&quot;https://astro.build/&quot;&gt;astro&lt;/a&gt; and a little bit of logic, I present to you &lt;a href=&quot;https://rssed.netlify.app/&quot;&gt;rssed.netlify.app&lt;/a&gt; and the journey of how I built it.&lt;/p&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;initial-idea&quot; tabindex=&quot;-1&quot;&gt;Initial Idea &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#initial-idea&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At first, I thought to create a postgres database on &lt;a href=&quot;https://neon.tech/&quot;&gt;neon&lt;/a&gt; for storing the feeds urls and I did implement it, but unfortunately, after having some issues when deploying it to a serverless function on vercel, I dropped it.&lt;/p&gt;
&lt;p&gt;Went for SSR at first &lt;em&gt;(due to the urge to try &lt;a href=&quot;https://docs.astro.build/en/core-concepts/routing/#dynamic-routes&quot;&gt;dynamic paths in astro&lt;/a&gt;)&lt;/em&gt;, but finally resorted to do everything at build time. Because why not? If you have a list of feeds ready, instead of generating the page from the same template on each feed request again and again, generate all of it beforehand and then serve.&lt;/p&gt;
&lt;h2 id=&quot;astro&quot; tabindex=&quot;-1&quot;&gt;Astro &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#astro&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To give you some background — astro is a javascript based meta framework for building websites focused around content. You can use it to build static sites as well as interactive web applications using the &lt;a href=&quot;https://docs.astro.build/en/core-concepts/framework-components/&quot;&gt;framework of your choice&lt;/a&gt;, however I prefer the former use case much more than the latter. Astro&#39;s main focus is on adding interactivity through hydration &lt;em&gt;(sprinkling javascript)&lt;/em&gt; and isolating interactive components using the islands architecture.&lt;/p&gt;
&lt;p&gt;Astro primarily generates static sites but it also gives you &lt;a href=&quot;https://docs.astro.build/en/guides/on-demand-rendering/#enabling-on-demand-rendering&quot;&gt;2 options to build your site output&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;server&lt;/code&gt; - everything will be built and rendered on demand as per the user request. You can exclude some parts of your site which need to be rendered beforehand. So, here the default is &lt;em&gt;&lt;strong&gt;on-demand&lt;/strong&gt;&lt;/em&gt; server rendered content.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hybrid&lt;/code&gt; - the default here is everything is &lt;em&gt;&lt;strong&gt;pre-rendered at build time&lt;/strong&gt;&lt;/em&gt; unless you specify otherwise.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;hybrid&lt;/code&gt; mode is &lt;em&gt;&lt;strong&gt;removed&lt;/strong&gt;&lt;/em&gt; in Astro v5.0 so you must change its name to &lt;code&gt;static&lt;/code&gt; in astro config file. The static mode behaves the same as the hybrid mode and it&#39;s the default output mode. More info here - &lt;a href=&quot;https://docs.astro.build/en/guides/upgrade-to/v5/#removed-hybrid-rendering-mode&quot;&gt;Upgrade to Astro v5&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;astro/config&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;static&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For this blogroll, I went for the &lt;strong&gt;hybrid&lt;/strong&gt; approach as I didn&#39;t see an issue generating content at build time. But don&#39;t I want to update the feeds on a daily basis? Yes, I still do, and you might be thinking why go for a static approach — more on that later.&lt;/p&gt;
&lt;p&gt;There are three &lt;code&gt;.astro&lt;/code&gt; files in the picture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One for displaying the list of &lt;em&gt;sorted&lt;/em&gt; feeds (&lt;code&gt;src/pages/index.astro&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;One for displaying the posts for a single feed (&lt;code&gt;src/pages/feed/[id].astro&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The third serves as a layout (&lt;code&gt;src/layouts/Layout.astro&lt;/code&gt;) for the previous two.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;rss-feeds&quot; tabindex=&quot;-1&quot;&gt;RSS Feeds &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#rss-feeds&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RSS feeds always fascinate me considering how simple they are. A perfect way to consume content published independently. I was on the search for an RSS parser and eventually found the rss parser by &lt;a href=&quot;https://github.com/rbren/&quot;&gt;@rbren&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://rknight.me/blog/the-web-is-fantastic/&quot;&gt;The Web is Fantastic&lt;/a&gt; - &lt;em&gt;by Robb Knight&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Having stored the feed URLs along with their IDs in a &lt;code&gt;json&lt;/code&gt; file, it became easy for me to loop over them and parse them.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feedlist&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;../../data/feedlist.json&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feedItem&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;{ [&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }&gt; &amp;#x26; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    time&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    items&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feedItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    time&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    items&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ParseRSS&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Parser&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        timeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;120000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseAndStoreFeeds&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }[]) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feedPromises&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feedItem&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                ...&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ParseRSS&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            logger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    Promise&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;allSettled&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedPromises&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feedPromises&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        feed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;            !&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;some&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseAndStoreFeeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedlist&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What I am doing here is fetching the RSS feeds from their URLs by using the rss-parser &lt;em&gt;parallelly&lt;/em&gt;, handling potentially unhandled promise rejections using &lt;code&gt;Promise.allSettled()&lt;/code&gt; and pushing them &lt;em&gt;sequentially&lt;/em&gt; in an array. This approach of fetching feeds parallelly and storing them sequentially has improved the build time drastically.&lt;/p&gt;
&lt;p&gt;Earlier, I was fetching the feeds parallelly but waiting for the last one to get fetched and succeed. But this meant that if one of the URL fails to get parsed, I won&#39;t get any result. It&#39;s all or nothing. I certainly don&#39;t want to do that.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; allFeeds&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }[]) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;all&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                ...&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ParseRSS&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, I improved it a bit, but now the problem was that it was all sequential. If one URL takes 6 seconds to resolve and parse, the next one just keeps on waiting. That&#39;s too slow.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; allFeeds&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }[]) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feeds&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; site&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                ...&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ParseRSS&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feeds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I remembered I read a post by &lt;a href=&quot;https://jakearchibald.com/&quot;&gt;Jake Archibald&lt;/a&gt; discussing &lt;a href=&quot;https://jakearchibald.com/2023/unhandled-rejections/&quot;&gt;the gotcha of unhandled promise rejections&lt;/a&gt; and found the solution which I shared at the very first.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feedPromises&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feedItem&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ...&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; ParseRSS&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;site&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// gotcha&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;Promise&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;allSettled&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedPromises&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feed&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feedPromises&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    feed&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feed&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once I receive all of the parsed feeds in &lt;code&gt;index.astro&lt;/code&gt;, sorting them according to the publish date of the last post or the last build date keeps them in a descending order.&lt;/p&gt;
&lt;p&gt;For displaying posts from a single feed, I went for dynamic routes in astro(&lt;code&gt;[id].astro&lt;/code&gt;). It&#39;s awesome that you can generate multiple pages from the same template by using the &lt;code&gt;getStaticPaths()&lt;/code&gt; method and giving it a bunch of values as props with the feed &lt;code&gt;uuid&lt;/code&gt; as the param.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getStaticPaths&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; fetchFeeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feeds&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; allFeeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }[]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feedList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;Record&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;Record&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&gt;[] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;fl&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    params&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;fl&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    props&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; fl&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feedList&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            ?&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; feedList&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            :&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                      params&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                          id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;404&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                      props&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                          feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;              ];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                params&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;404&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                props&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And accessing the prop from the &lt;code&gt;Astro.props&lt;/code&gt; object.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;feeds&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Astro&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;daily-build&quot; tabindex=&quot;-1&quot;&gt;Daily Build &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#daily-build&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If all of this is static and doesn&#39;t even update itself, then what&#39;s the point of building a blogroll which subscribes to RSS feeds. That&#39;s where Netlify&#39;s &lt;code&gt;build hook&lt;/code&gt; comes into action. A simple POST request to the build hook URL can trigger a new build of the project. This request is made every day at &lt;code&gt;00:00&lt;/code&gt; with the help of a cron schedule &lt;code&gt;0 0 * * *&lt;/code&gt;. Learn more about cron timing and play with it on &lt;a href=&quot;https://crontab.guru/&quot;&gt;crontab.guru&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The below mentioned code lives under &lt;code&gt;netlify/functions&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;node-fetch&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@netlify/functions&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; BUILD_HOOK&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; process&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;BUILD_HOOK&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; unknown&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; URL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// every day at 00:00&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; handler&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; schedule&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;0 0 * * *&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;BUILD_HOOK&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            method&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            statusCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;200&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            statusCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;500&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;labelling-latest-posts&quot; tabindex=&quot;-1&quot;&gt;Labelling Latest Posts &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#labelling-latest-posts&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I stored the last updated date as a &lt;code&gt;data-&lt;/code&gt; attribute on the feed element, stored the time in localStorage and then accessed that attribute using client side javascript to calculate the difference in time between the localStorage timestamp and last updated time of the feed.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;DOMContentLoaded&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;.feed&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; ele&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; e&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; feedId&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;dataset&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lastPublishedTime&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;dataset&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;lastPublished&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getTime&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;localStorage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            localStorage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                read&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                timestamp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;lastPublishedTime&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;feed_banner&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; prevPostLogRead&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;localStorage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; loggedPublishTime&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;prevPostLogRead&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;timestamp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;lastPublishedTime&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; loggedPublishTime&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&amp;#x3C;=&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; newPostLogUnread&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    ...&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;prevPostLogRead&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    read&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                localStorage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;newPostLogUnread&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;dataset&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;true&#39;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;feed_banner&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; read&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;localStorage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getItem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;feedId&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                read&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; ele&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;feed_banner&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;beautify-logs&quot; tabindex=&quot;-1&quot;&gt;Beautify Logs &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#beautify-logs&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While enhancing some stuff, I thought why not make logs colorful and pretty. And, thus I ended up using &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/&quot;&gt;consola to beautify the logs&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;consola&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; loggerInstance&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    fancy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    formatOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        colors&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; logger&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; loggerInstance&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;deploying-to-netlify&quot; tabindex=&quot;-1&quot;&gt;Deploying to Netlify &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#deploying-to-netlify&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to deploy the astro site with a &lt;code&gt;hybrid&lt;/code&gt; or &lt;code&gt;server&lt;/code&gt; output mode (server side rendering), you need an adapter. Astro provides &lt;a href=&quot;https://docs.astro.build/en/guides/server-side-rendering/&quot;&gt;official adapters&lt;/a&gt; which you can use for deploying to various platforms. Run &lt;code&gt;npm run build&lt;/code&gt; locally to see the build output.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;astro/config&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; netlify&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@astrojs/netlify&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// https://astro.build/config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;hybrid&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  server&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    port&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  adapter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;netlify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;contribute&quot; tabindex=&quot;-1&quot;&gt;Contribute &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/#contribute&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://rssed.netlify.app/&quot;&gt;rssed&lt;/a&gt; is open source. You are free to contribute either new RSS feeds or code as a developer. I don&#39;t know if this has the potential to be the next big project but you can help it be one. Power to you.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;github-repository&quot; tabindex=&quot;-1&quot;&gt;GitHub Repository&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/murtuzaalisurti/rssed/&quot;&gt;murtuzaalisurti/rssed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/blogroll-using-astro/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Advent Of Code 2023 - Day Four Solution</title>
    <link href="https://syntackle.com/blog/advent-of-code-2023-day-four-solution-4SanE/"/>
    <published>2023-12-26T15:20:45Z</published>
    <updated>2023-12-26T15:20:45Z</updated>
    <id>https://syntackle.com/blog/advent-of-code-2023-day-four-solution-4SanE/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;It felt easier than the previous one to be honest, especially the first part. The puzzle is quite simple. For a given number of scratchcards, there are two lists of numbers printed on it separated by a pipe &lt;code&gt;|&lt;/code&gt; sign.&lt;/p&gt;
&lt;p&gt;The first list contains of all the winning numbers and the second list contains the numbers given to you. You have to figure out which of the given numbers match the winning numbers. You get one point for the first match then double it for every match after the first.&lt;/p&gt;
&lt;h2 id=&quot;part-one&quot; tabindex=&quot;-1&quot;&gt;Part One &lt;a href=&quot;https://syntackle.com/blog/advent-of-code-2023-day-four-solution-4SanE/#part-one&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, for example, if you have,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Card 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then, the matching numbers will be &lt;code&gt;1 and 21&lt;/code&gt; and the points will be &lt;code&gt;1&lt;/code&gt; after the first match and &lt;code&gt;1 * 2 = 2&lt;/code&gt; points after the next. You need to sum up all the points for a pile of cards.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;../lib/shared.mjs&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;day-4/input.txt&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardsWithTheirPoints&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardsWithTheirWinningCopies&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    card&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    copies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        count&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; str&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;|&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; PartOne&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;:&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; winningNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; numbersIhave&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; points&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; firstMatch&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; win&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; winningNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;numbersIhave&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;win&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;win&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;firstMatch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    points&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; points&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    points&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                firstMatch&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        cardsWithTheirPoints&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            points&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            card&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardsWithTheirPoints&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;points&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; totalPointsOfPileOfCards&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; PartOne&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;part-two&quot; tabindex=&quot;-1&quot;&gt;Part Two &lt;a href=&quot;https://syntackle.com/blog/advent-of-code-2023-day-four-solution-4SanE/#part-two&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The second part is quite interesting. The concept of points is now removed. For each matching win number you win the next card. So, for example, if you have a card,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Card 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then, it has two matching numbers, &lt;code&gt;1 and 21&lt;/code&gt; and therefore you also win cards &lt;code&gt;4&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt;. This way, multiple copies of cards are generated. If a card has no matching numbers, you win nothing. What you have to do is calculate all of the instances of each card &lt;em&gt;(original + copies)&lt;/em&gt; and then sum them up to get the total number of scratchcards.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; PartTwo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; calc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; card&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; index&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;:&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; winningNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; numbersIhave&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cardNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; win&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; winningNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;numbersIhave&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;win&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                    matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;win&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &gt;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; nextcards&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: ((&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;matchingNumbers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; card&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; card&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; card&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; winningCopyNumber&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; nextcards&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    cardsWithTheirWinningCopies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;winningCopyNumber&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;copies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; copy&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;copy&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; cardsWithTheirWinningCopies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;copies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;copy&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            calc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cardsWithTheirWinningCopies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;copies&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For each winning number, I am incrementing the copies of the successor cards and then looping over the copies. I initiated the copies for every card with &lt;code&gt;1&lt;/code&gt; depicting the original copy. If the card has no matching numbers, the copy count will be &lt;code&gt;1&lt;/code&gt; as it generated no more winning cards.&lt;/p&gt;
&lt;p&gt;The execution time for the second part in javascript is not up to the mark, and thus there&#39;s an opportunity to optimize, which I leave it to you.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;exec&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Part&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 1:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 3.171&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;exec&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Part&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 2:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 58.305&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can find the &lt;a href=&quot;https://github.com/murtuzaalisurti/advent-of-code-2023/blob/main/day-4/index.mjs&quot;&gt;entire code in my repository&lt;/a&gt; as well as the code for the previous puzzles.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/advent-of-code-2023-day-four-solution-4SanE/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Web Components &amp; Custom Elements</title>
    <link href="https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/"/>
    <published>2023-12-24T08:58:41Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Those familiar with React or any other javascript framework, are already aware of the component based architecture. You break the UI into re-usable pieces of code and stitch them together when required.&lt;/p&gt;
&lt;p&gt;Custom elements in HTML are a way to extend native HTML elements. Javascript frameworks simulate the behavior of components in a web page whereas custom elements provide a native HTML-ly way to do so. A web component uses custom elements along with other techniques such as the shadow DOM.&lt;/p&gt;
&lt;h2 id=&quot;types-of-custom-elements&quot; tabindex=&quot;-1&quot;&gt;Types Of Custom Elements &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/#types-of-custom-elements&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Autonomous custom elements&lt;/li&gt;
&lt;li&gt;Customized built-in elements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Autonomous custom elements extend the generic &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement&quot;&gt;HTMLElement&lt;/a&gt; class. On the other hand, a customized custom element extends a specific HTML elements&#39; class and builds on top of existing functionality. For example, if you want a custom anchor element, you can extend the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement&quot;&gt;HTMLAnchorElement&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;defining-custom-elements&quot; tabindex=&quot;-1&quot;&gt;Defining Custom Elements &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/#defining-custom-elements&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To define a custom element, we need to create a javascript class extending the native HTMLElement class. Try creating the below custom element in a codepen:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Demo&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;  constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;Demo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then invoking it in HTML:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;demo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;demo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It won&#39;t let you create it. Why? See the error.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-console&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;Uncaught SyntaxError: Failed to execute &#39;define&#39; on &#39;CustomElementRegistry&#39;: &quot;demo&quot; is not a valid custom element name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not a bug, this is intentionally done to separate custom elements from native HTML elements. Custom elements must contain a hyphen in their name to make custom elements recognizable and distinct from HTML elements.&lt;/p&gt;
&lt;p&gt;So now, if you change it to something like &lt;code&gt;demo-webc&lt;/code&gt; and change the class name to &lt;code&gt;DemoWebC&lt;/code&gt;, it works.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; DemoWebC&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;  constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;customProperty&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;custom&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// two arguments: tag name, class name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo-webc&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;DemoWebC&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It always recommended to call the &lt;code&gt;super()&lt;/code&gt; method first in the constructor as it initializes default properties of the &lt;code&gt;HTMLElement&lt;/code&gt; class by invoking its constructor.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;connectedCallback()&lt;/code&gt; method is for detecting when the element is loaded into the page. There&#39;s also a method named &lt;code&gt;disconnectedCallback()&lt;/code&gt; which detects if the element is removed from the page. A third method name &lt;code&gt;adoptedCallback()&lt;/code&gt; says that the element has moved to a new page.&lt;/p&gt;
&lt;p&gt;You can define custom properties inside the constructor and use them as custom attributes in your element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;customProperty&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;data-custom&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;custom value&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what if you need to modify the functionality on attribute&#39;s value change? That&#39;s where &lt;code&gt;attributeChangedCallback()&lt;/code&gt; method comes into action. In order to see it in action, you need to first define a static &lt;code&gt;observedAttributes&lt;/code&gt; class property and set it to an array of all the attributes you want to keep track of.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;attributeChangedCallback()&lt;/code&gt; fires if those attributes mentioned in the static &lt;code&gt;observedAttributes&lt;/code&gt; property change. Note that if the attribute is already present when the custom element loads, this method is fired at that time too.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; observedAttributes&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;data-custom&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;attributeChangedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;old&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;newValue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;old&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;newValue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you are done with building a custom element, you must register it by using the &lt;code&gt;define()&lt;/code&gt; method. It&#39;s callable on the &lt;code&gt;customElements&lt;/code&gt; global object (&lt;code&gt;window.customElements&lt;/code&gt;) which is a registry of custom elements.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;custom-element-name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;ClassName&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;options&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This was all for defining a customized autonomous custom element. What about extending only an anchor HTML element?&lt;/p&gt;
&lt;p&gt;For that, instead of extending the &lt;code&gt;HTMLElement&lt;/code&gt; class, extend the &lt;code&gt;HTMLAnchorElement&lt;/code&gt; class. And specify which type of HTML element it extends with the &lt;code&gt;extends&lt;/code&gt; option.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; DemoAnchor&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLAnchorElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;  constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;syntackle.com&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;https://syntackle.com&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo-anchor&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;DemoAnchor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;extends&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can&#39;t use this element like &lt;code&gt;&amp;lt;demo-anchor&amp;gt;&lt;/code&gt; because it&#39;s not an autonomous element, instead you can use it like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo-anchor&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;web-components&quot; tabindex=&quot;-1&quot;&gt;Web Components &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/#web-components&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Web components are more than just custom elements. They sometimes also involve a shadow DOM. A &lt;em&gt;&amp;quot;shadow&amp;quot;&lt;/em&gt; DOM, as the name suggests, is a sub-DOM tree for HTML elements. It is mainly used for encapsulation and restricting styles up to the web component only.&lt;/p&gt;
&lt;h3 id=&quot;shadow-dom&quot; tabindex=&quot;-1&quot;&gt;Shadow DOM&lt;/h3&gt;
&lt;p&gt;To create a shadow DOM, attach it to a host, in our case the custom element itself is a host to the shadow DOM. However, the shadow DOM can only be attached to a custom element or &lt;a href=&quot;https://dom.spec.whatwg.org/#dom-element-attachshadow&quot;&gt;these built-in elements mentioned in the HTML spec&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; access elements outside the shadow DOM from inside the shadow DOM.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; DemoWebC&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; HTMLElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;  constructor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B;font-style:italic&quot;&gt;    super&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;  connectedCallback&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; shadow&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;attachShadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;style&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `p { color: blue; }`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    shadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; text&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    shadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;customElements&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo-webc&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;DemoWebC&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Shadow DOM has two modes: &lt;code&gt;open&lt;/code&gt; and &lt;code&gt;closed&lt;/code&gt;. Open means external elements in the page can modify the contents of the shadow DOM by using &lt;code&gt;shadowRoot&lt;/code&gt; property. In the &lt;code&gt;closed&lt;/code&gt; mode, the shadow DOM is not accessible from outside using the &lt;code&gt;shadowRoot&lt;/code&gt; property as it is &lt;code&gt;null&lt;/code&gt; in this case.&lt;/p&gt;
&lt;p&gt;Try doing this on a closed shadow DOM custom element:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;demo-webc&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;shadowRoot&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It returns &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Templates&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;slots&lt;/strong&gt;&lt;/em&gt; are extremely useful when building complex custom elements or web components. Diving deep into them is out of the scope of this article, but here are some good resources for them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots&quot;&gt;Using templates and slots - Web APIs | MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javascript.info/slots-composition&quot;&gt;Shadow DOM slots, composition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raymondcamden.com/2022/10/13/working-with-slots-and-web-components&quot;&gt;Working with Slots and Web Components&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;styling-shadow-dom&quot; tabindex=&quot;-1&quot;&gt;Styling Shadow DOM&lt;/h3&gt;
&lt;p&gt;The shadow DOM can be styled either by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Constructing a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet&quot;&gt;&lt;code&gt;CSSStyleSheet&lt;/code&gt;&lt;/a&gt; object, inserting CSS in it using &lt;code&gt;replaceSync()&lt;/code&gt; and attaching it to the shadow DOM using the &lt;code&gt;adoptedStyleSheets&lt;/code&gt; property.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; shadowDOM&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;attachShadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; styleSheet&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; CSSStyleSheet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;styleSheet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;replaceSync&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`p { color: blue; }`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;shadowDOM&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;adoptedStyleSheets&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;styleSheet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Declaring styles using a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM#adding_style_elements_in_template_declarations&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;custom&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;blue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; }&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Web Component&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; shadowDOM&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;attachShadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; template&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#custom&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;shadowDOM&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;cloneNode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Simply creating a &lt;code&gt;style&lt;/code&gt; tag and inserting CSS as text in it.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;style&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textContent&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `p { color: blue; }`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;shadow&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;creating-your-own-web-component&quot; tabindex=&quot;-1&quot;&gt;Creating Your Own Web Component &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/#creating-your-own-web-component&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first web component shown below is a custom button element which opens a &lt;code&gt;dialog&lt;/code&gt; element. And the second web component involves a shadow DOM to pretty print JSON string in HTML.&lt;/p&gt;
&lt;p&gt;Similarly, you can create your own custom elements and use them anywhere you want.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;LYaYqmo&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/LYaYqmo&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/web-components-and-custom-elements-5LuzI/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Advent Of Code 2023 - Day Two Solution</title>
    <link href="https://syntackle.com/blog/advent-of-code-2023-day-two-E7Ndz/"/>
    <published>2023-12-08T07:40:05Z</published>
    <updated>2023-12-08T10:37:36Z</updated>
    <id>https://syntackle.com/blog/advent-of-code-2023-day-two-E7Ndz/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Just wrapped up solving advent of code&#39;s day two challenge. This was a tricky one in terms of the language used to describe the puzzle. I had to take some online help to understand what was the second part of the puzzle trying to say.&lt;/p&gt;
&lt;p&gt;You can visit the &lt;a href=&quot;https://adventofcode.com/2023/day/2&quot;&gt;advent of code day two&lt;/a&gt; challenge to check what was the puzzle. In short, in the first part of the puzzle, we had to figure out the sum of the number of valid games from a given input. And, in the second part, we had to find the sum of the powers of fewest number of cubes (of each color) present to make the game possible.&lt;/p&gt;
&lt;h2 id=&quot;part-one&quot; tabindex=&quot;-1&quot;&gt;Part One&lt;/h2&gt;
&lt;p&gt;To re-structure the data we are getting in the input in a singe line, I created this function to map the game number to the number of cubes revealed of each type in each play.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  cubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    green&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [ &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;6&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;5&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;5&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ],     &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    red&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [ &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;3&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;3&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;3&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ],       &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    blue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [ &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;7&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;8&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;5&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; ]       &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;readFileByLine&lt;/code&gt; function is the same as used in &lt;a href=&quot;https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/&quot;&gt;&lt;code&gt;day-1&lt;/code&gt;&lt;/a&gt;&#39;s solution.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getCubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; games&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;day-2/input.txt&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;games&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; games&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; splitGameNumberAndPlays&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;:&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubesFromAPlay&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            green&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            red&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            blue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; plays&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; splitGameNumberAndPlays&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; play&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; plays&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            play&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;,&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;cubeType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeColor&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeCount&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                cubesFromAPlay&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cubeColor&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cubeCount&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;splitGameNumberAndPlays&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            cubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cubesFromAPlay&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The maximum number of cubes that should be present (for each cube type) for a game play to make this a valid game are:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; totalCubesAtOnce&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    red&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    green&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;13&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    blue&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;14&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we get any count greater than the count above for each cube type, the game is marked as invalid. For example, game &lt;code&gt;Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue&lt;/code&gt; is a valid game because for each play (separated by semi-colon), the cube count for each type is under the maximum count.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; partOne&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; validGames&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getCubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; game&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; isValid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        loop2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Object&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; count&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; totalCubesAtOnce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]) { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    isValid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                    break&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; loop2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        isValid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; validGames&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; validGames&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;number&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then finally, I am summing up all of the valid game numbers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From this challenge, I came across an &lt;a href=&quot;https://stackoverflow.com/a/183197/17241798&quot;&gt;interesting revelation&lt;/a&gt; about breaking nested loops in javascript. I am &lt;a href=&quot;https://stackoverflow.com/questions/183161/whats-the-best-way-to-break-from-nested-loops-in-javascript#comment15345007_183197&quot;&gt;still processing this&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;part-two&quot; tabindex=&quot;-1&quot;&gt;Part Two&lt;/h2&gt;
&lt;p&gt;Here, we had to figure out the sum of the power (cube count of each color multiplied together) of the fewest set of cubes required to make the game possible. &amp;quot;Fewest&amp;quot; here means the biggest number of cubes of each color present in a game. Once we get the number of cubes required for each color, we can multiply them together and that will give us the power for each game. Adding them up gives us the result.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; partTwo&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; getCubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; powersOfCubes&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; cubeCountMappedToTheGameAndType&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; powersOfCubeInAGame&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; Object&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;game&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;cubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            powersOfCubeInAGame&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sort&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))[&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        powersOfCubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; powersOfCubeInAGame&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; powersOfCubes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The execution time turns out to be:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;exec&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 19.009&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;repository&quot; tabindex=&quot;-1&quot;&gt;Repository&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Here&#39;s my &lt;a href=&quot;https://github.com/murtuzaalisurti/advent-of-code-2023&quot;&gt;github repository&lt;/a&gt; for Advent Of Code 2023 solutions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/advent-of-code-2023-day-two-E7Ndz/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Completed Advent Of Code: Day One</title>
    <link href="https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/"/>
    <published>2023-12-03T11:21:58Z</published>
    <updated>2023-12-08T10:36:35Z</updated>
    <id>https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;&lt;a href=&quot;https://adventofcode.com/2023/about&quot;&gt;Advent of Code 2023&lt;/a&gt; is here and I just completed its &lt;a href=&quot;https://adventofcode.com/2023/day/1&quot;&gt;day-one&lt;/a&gt; challenge. Overall, it was fun to play with strings and numbers in javascript. Without any further ado, let&#39;s explore the solution.&lt;/p&gt;
&lt;p&gt;The challenge is divided into two parts. The first part is quite simple but the second one adds a cherry on top of the cake.&lt;/p&gt;
&lt;h2 id=&quot;part-1&quot; tabindex=&quot;-1&quot;&gt;Part 1 &lt;a href=&quot;https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/#part-1&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;From a given list of strings, I had to find the digits, combine the first and last digit in order of occurrence in the string and them sum it up all. To simplify, for a given string &lt;code&gt;gh34s1&lt;/code&gt;, the output will be &lt;code&gt;31&lt;/code&gt; with &lt;code&gt;3&lt;/code&gt; as the first digit, &lt;code&gt;1&lt;/code&gt; as the last digit and &lt;code&gt;31&lt;/code&gt; as their concatenation.&lt;/p&gt;
&lt;p&gt;So, for two strings &lt;code&gt;gh34s1&lt;/code&gt; and &lt;code&gt;d7hs23&lt;/code&gt; the sum of their digits will be &lt;code&gt;31 + 23 = 54&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I stored the input in a &lt;code&gt;.txt&lt;/code&gt; file and then looped over line by line to get the string from each line.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; readline&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;readline&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; fs&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;fs&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;path&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; readInterface&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; readline&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createInterface&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;fs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createReadStream&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;day-1/input.txt&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;stdout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        terminal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; readInterface&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; lines&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, to parse the digits in the string and to validate if they are numbers, I used &lt;a href=&quot;https://zod.dev/&quot;&gt;zod&lt;/a&gt;. There was a simple way to sort the first and last digits but I couldn&#39;t figure it out until I started with Part-2.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nan&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;safeParse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;success&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; char&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach gave me the correct answer for sure but there was a better approach. Yes, regex!&lt;/p&gt;
&lt;h2 id=&quot;part-2&quot; tabindex=&quot;-1&quot;&gt;Part-2 &lt;a href=&quot;https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/#part-2&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Part-2 had me thinking that my solution was correct, but in fact it wasn&#39;t. Lets see what was it. So, the second part introduced a twist in the story, not only the digits were represented as integers in the string, but also their alphabetical synonyms (&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;) were also a part of it.&lt;/p&gt;
&lt;p&gt;Regex was the answer. I tried &lt;code&gt;/(one|two|three|four|five|six|seven|eight|nine)/g&lt;/code&gt; as a regular expression along with &lt;code&gt;matchAll()&lt;/code&gt; to find all occurrences of the alphabetical number representations and it seemed to work.&lt;/p&gt;
&lt;p&gt;Then, I stored the digits along with their indexes in an array of objects by mapping the alphabetical numbers to their respective integers and sorted them in an ascending order based on the index to get the first and last digits.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; regex&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; RegExp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;(one|two|three|four|five|six|seven|eight|nine)&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;g&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; stringToIntMap&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;([[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;one&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;two&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;four&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;five&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;six&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;seven&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;eight&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;nine&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;matchAll&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;regex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;stringToIntMap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nan&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;safeParse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;success&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sort&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ...&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ...&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What it would do is, for a string like &lt;code&gt;d3two4eight&lt;/code&gt;, the first digit it will select is &lt;code&gt;3&lt;/code&gt; and the last as &lt;code&gt;8&lt;/code&gt;. So, the output for this string would be &lt;code&gt;38&lt;/code&gt;. So far so good. I submitted the answer and it was incorrect. There was a catch.&lt;/p&gt;
&lt;p&gt;The input also contained strings such as &lt;code&gt;3eightwo&lt;/code&gt;. The alphabetical parts of &lt;code&gt;eight&lt;/code&gt; and &lt;code&gt;two&lt;/code&gt; overlap. And so, my assumption was to ignore the latter digit and just keep &lt;code&gt;eight&lt;/code&gt; which would make the output as &lt;code&gt;38&lt;/code&gt;. But the correct output should be &lt;code&gt;32&lt;/code&gt; after taking into account the overlapping representations.&lt;/p&gt;
&lt;p&gt;After a bit of googling I found out about how to find overlapping matches using the &lt;a href=&quot;https://mtsknn.fi/blog/how-to-do-overlapping-matches-with-regular-expressions/&quot;&gt;lookahead assertion&lt;/a&gt; in regular expressions.&lt;/p&gt;
&lt;p&gt;Modified the regex to this and I got the perfect answer.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; RegExp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;(?=(one|two|three|four|five|six|seven|eight|nine))&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;gm&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&#39;s it. Through this challenge I learned about regex more than I could have normally. Here&#39;s the entire solution:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; readline&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;readline&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; fs&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;fs&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;path&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;zod&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; regex&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; RegExp&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;(?=(one|two|three|four|five|six|seven|eight|nine))&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;gm&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; stringToIntMap&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;([[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;one&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;two&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;four&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;five&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;six&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;seven&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;eight&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;], [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;nine&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; readInterface&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; readline&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createInterface&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;fs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createReadStream&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;day-1/input.txt&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;stdout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        terminal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; readInterface&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; lines&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // reading file line by line and storing it in an array - each line contains a string &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; readFileByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // looping over each string &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lines&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // finding alphabetical digits, mapping them to their integers, and storing them along with index &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;matchAll&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;regex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;stringToIntMap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // finding integers and storing them along with index &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; lineArr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;entries&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;nan&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;safeParse&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;success&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // sorting integers based on the index - ascending &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; allDigitsInLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sort&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            ...&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            ...&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;sortedDigitsAccordingToIndex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;        // concatenating digits and converting into integer &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;firstAndLastNumber&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;digit&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // summing up the result of every string &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; calibrationByLine&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;reduce&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;acc&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; acc&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; curr&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The execution time for &lt;code&gt;1000&lt;/code&gt; strings turns out to be:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;executed:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 94.047&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/completed-advent-of-code-day-1-CPjek/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>App Defaults 2023 — What I use</title>
    <link href="https://syntackle.com/blog/app-defaults-2023-what-i-use-by-murtuzaali-surti-qhifV/"/>
    <published>2023-11-26T00:00:00Z</published>
    <updated>2024-01-16T05:45:58Z</updated>
    <id>https://syntackle.com/blog/app-defaults-2023-what-i-use-by-murtuzaali-surti-qhifV/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;The other day, I stumbled upon a &lt;a href=&quot;https://rknight.me/popular-pages-with-eleventy-and-fathom-analytics/&quot;&gt;post&lt;/a&gt; by &lt;a href=&quot;https://social.lol/@robb&quot;&gt;@robb&lt;/a&gt; which in turn led me to &lt;a href=&quot;https://rknight.me/app-defaults/&quot;&gt;this post about app defaults&lt;/a&gt;. Following the spree, here&#39;s my list of all the apps I use for the following categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📨 &lt;strong&gt;Mail Client&lt;/strong&gt; - Gmail&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📝 &lt;strong&gt;Notes&lt;/strong&gt; - Notion, Obsidian&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📆 &lt;strong&gt;Calendar&lt;/strong&gt; - Google Calendar&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📁 &lt;strong&gt;Cloud&lt;/strong&gt; - Google Cloud, OneDrive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;strong&gt;RSS&lt;/strong&gt; - &lt;a href=&quot;https://rssed.netlify.app/&quot;&gt;rssed&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌐 &lt;strong&gt;Browser&lt;/strong&gt; - Chrome, Brave, Firefox&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;💬 &lt;strong&gt;Chat&lt;/strong&gt; - WhatsApp, Discord&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔖 &lt;strong&gt;Bookmarks&lt;/strong&gt; - &lt;a href=&quot;https://www.notion.so/web-clipper&quot;&gt;Notion Web Clipper&lt;/a&gt;, Chrome Bookmarks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📜 &lt;strong&gt;Word Processing&lt;/strong&gt; - Notion, Obsidian&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📈 &lt;strong&gt;Spreadsheets&lt;/strong&gt; - Google Sheets&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🎤 &lt;strong&gt;Podcasts&lt;/strong&gt; - Google Podcasts, PocketCasts&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔐 &lt;strong&gt;Password Management&lt;/strong&gt; - &lt;a href=&quot;https://bitwarden.com/&quot;&gt;Bitwarden&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🧑‍💻 &lt;strong&gt;Code Editor&lt;/strong&gt; - VS Code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✈️ &lt;strong&gt;VPN&lt;/strong&gt; - ProtonVPN&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;honorable-mentions&quot; tabindex=&quot;-1&quot;&gt;Honorable mentions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;📝⚡ &lt;strong&gt;Quick note-taking&lt;/strong&gt; - &lt;a href=&quot;https://numbr.dev/&quot;&gt;numbr&lt;/a&gt; - useful for quick note taking involving numbers, currency or any numeric values.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;further-reads-%F0%9F%93%9C&quot; tabindex=&quot;-1&quot;&gt;Further Reads 📜&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;More about &lt;a href=&quot;https://defaults.rknight.me/&quot;&gt;app defaults&lt;/a&gt; and how it started.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/app-defaults-2023-what-i-use-by-murtuzaali-surti-qhifV/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Elegant Console Logs With Consola</title>
    <link href="https://syntackle.com/blog/elegant-console-logs-p0JYCE/"/>
    <published>2023-11-16T00:00:00Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/elegant-console-logs-p0JYCE/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Console logs are not always well structured and eye-pleasing. Unpleasant and messy console takes away from the bliss of a developer. I recently came across a package named &lt;a href=&quot;https://www.npmjs.com/package/consola&quot;&gt;&lt;code&gt;consola&lt;/code&gt;&lt;/a&gt; which does exactly this — making consoles meaningful and elegant.&lt;/p&gt;
&lt;p&gt;It has browser support, pausing and resuming logs, prompt support and &lt;a href=&quot;https://github.com/unjs/consola#why-consola&quot;&gt;other useful features&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;install&quot; tabindex=&quot;-1&quot;&gt;Installation &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#install&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can install it by using &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;pnpm&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; consola&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;trying-it-out&quot; tabindex=&quot;-1&quot;&gt;Trying it out&lt;/h2&gt;
&lt;p&gt;Spin up a new &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/#creating-express-app&quot;&gt;node/express app&lt;/a&gt; and start exploring.&lt;/p&gt;
&lt;h3 id=&quot;basics&quot; tabindex=&quot;-1&quot;&gt;Basics &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#basics&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For a quick hands on experience, in your node application, throw an explicit error and then log it with the help of &lt;code&gt;consola&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;consola&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Unexpected error&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Error...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Info...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;warn&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Warning...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Logged...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;new-instance&quot; tabindex=&quot;-1&quot;&gt;New Instance &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#new-instance&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can create a new consola instance with the help of the &lt;code&gt;createConsola&lt;/code&gt; method and use that instead of the default global instance.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;consola&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; logger&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    level&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// error/fatal logs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    fancy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    formatOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        columns&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;logger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Info...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// this WON&#39;T work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;logger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Error...&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// this will work&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the log &lt;code&gt;level&lt;/code&gt; to selectively allow only certain types of logs. &lt;a href=&quot;https://www.npmjs.com/package/consola#log-level&quot;&gt;Log level&lt;/a&gt; of &lt;code&gt;0&lt;/code&gt; means only &lt;code&gt;FATAL&lt;/code&gt; and &lt;code&gt;ERROR&lt;/code&gt; logs are logged. The default log level is 3.&lt;/p&gt;
&lt;h3 id=&quot;reporters&quot; tabindex=&quot;-1&quot;&gt;Reporters &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#reporters&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Reporters are representations of logs in the terminal. Consola (v3.2.3) provides 3 &lt;a href=&quot;https://github.com/unjs/consola/tree/main/src/reporters&quot;&gt;reporters&lt;/a&gt; out of the box, namely, &lt;code&gt;basic&lt;/code&gt;, &lt;code&gt;fancy&lt;/code&gt; and &lt;code&gt;browser&lt;/code&gt;. They are configured based on log levels on the global &lt;code&gt;consola&lt;/code&gt; instance.&lt;/p&gt;
&lt;p&gt;To add a custom reporter to your newly created instance, you can use the &lt;code&gt;reporters&lt;/code&gt; property which is an array of reporters.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;LogLevels&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;consola&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; infoLogger&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    fancy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    formatOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        columns&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    reporters&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;level&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; LogLevels&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                    consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;dateStyle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;full&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        logs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;concat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `,`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ``&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                    consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                        new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;invalid log method&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, when you use any logging method on this instance, it will only log for the &lt;code&gt;info&lt;/code&gt; method and throw an error for other methods. You just created a custom info message logger which you can further modify however you want.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// for the above instance&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;infoLogger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Won&#39;t work&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) ❌&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;infoLogger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Will work&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) ✔️&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple reporters per instance are also supported allowing you to separate logs into desired representations.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;reporters&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;level&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; LogLevels&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;dateStyle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;full&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    logs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;concat&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `,`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ``&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                consola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                    new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;invalid log method&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            createConsola&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                fancy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                formatOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                    date&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Methods such as &lt;code&gt;addReporter&lt;/code&gt;, &lt;code&gt;setReporters&lt;/code&gt; and &lt;code&gt;removeReporter&lt;/code&gt; are available to handle reporters for an instance.&lt;/p&gt;
&lt;h3 id=&quot;wrapping-console-log&quot; tabindex=&quot;-1&quot;&gt;Wrapping native &lt;code&gt;console&lt;/code&gt; method with &lt;code&gt;consola&lt;/code&gt; instance &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#wrapping-console-log&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Doing so will redirect all the native &lt;code&gt;console.log&lt;/code&gt; calls to the specified &lt;code&gt;consola&lt;/code&gt; instance.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;infoLogger&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;wrapConsole&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// consola instance `infoLogger` will print the table&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;table&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Info&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Second Info&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;restoreConsole&lt;/code&gt; will restore the native functionality of &lt;code&gt;console.log&lt;/code&gt; and won&#39;t redirect to consola instance.&lt;/p&gt;
&lt;p&gt;There are several util methods present in &lt;code&gt;consola/utils&lt;/code&gt; which you can use to further customize the logs.&lt;/p&gt;
&lt;h3 id=&quot;prompts&quot; tabindex=&quot;-1&quot;&gt;Prompts &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/#prompts&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Prompts are supported in consola with the help of &lt;a href=&quot;https://github.com/natemoo-re/clack&quot;&gt;clack&lt;/a&gt;, a tool to build command-line apps. Check this out for some &lt;a href=&quot;https://github.com/unjs/consola/blob/main/examples/prompt.ts&quot;&gt;prompt examples in consola&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Correctly and elegantly representing console logs is an important task if you want to improve &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;developer productivity&lt;/a&gt; and &lt;code&gt;consola&lt;/code&gt; helps you with just that.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/elegant-console-logs-p0JYCE/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Sharing Localhost From VS Code - Port Forwarding</title>
    <link href="https://syntackle.com/blog/sharing-localhost-in-vscode-port-forwarding-Kew9D/"/>
    <published>2023-10-05T00:00:00Z</published>
    <updated>2023-12-17T10:41:42Z</updated>
    <id>https://syntackle.com/blog/sharing-localhost-in-vscode-port-forwarding-Kew9D/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Showing off what you built locally has never been easy. Sending &lt;code&gt;localhost:3000&lt;/code&gt; as a URL is like declaring a war.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Hey, I built a website! // [!code highlight]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Great, send me the link&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Sure, have a look // [!code highlight:2]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;http://localhost:3000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Awesome, looks identical to mine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thanks!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Jokes apart, you first need to &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/&quot;&gt;deploy&lt;/a&gt; it somewhere and then share the URL to a remote person. Or, use a third party service to generate a temporary URL.&lt;/p&gt;
&lt;p&gt;Using &lt;a href=&quot;https://ngrok.com/&quot;&gt;ngrok&lt;/a&gt; or a &lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;cloudflare tunnel&lt;/a&gt; might be a choice, but now, the feature of port forwarding is directly built into VS Code.&lt;/p&gt;
&lt;h2 id=&quot;port-forwarding-with-vs-code&quot; tabindex=&quot;-1&quot;&gt;Port forwarding with VS Code&lt;/h2&gt;
&lt;p&gt;You can now go to the &lt;code&gt;Ports&lt;/code&gt; view in VS Code, sign in to GitHub and forward any ports on which your local services are running. For example, you can spin up a &lt;code&gt;node&lt;/code&gt; server on port &lt;code&gt;5000&lt;/code&gt;, listen for requests on that server and forward port &lt;code&gt;5000&lt;/code&gt; to an accessible URL.&lt;/p&gt;
&lt;p&gt;The visibility of the URL is private by default, which means you need to sign in with the same github account you used to forward the port. You can set the visibility of the URL as &lt;code&gt;public&lt;/code&gt; to remove the sign in barrier.&lt;/p&gt;
&lt;p&gt;You can also change the &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/&quot;&gt;protocol&lt;/a&gt; from &lt;code&gt;HTTP&lt;/code&gt; to &lt;code&gt;HTTPS&lt;/code&gt; if you are forwarding any sensitive information. However, it&#39;s not recommended to forward any confidential or sensitive information over the tunnel.&lt;/p&gt;
&lt;p&gt;If you are concerned about the security aspect of it, the &lt;a href=&quot;https://code.visualstudio.com/docs/editor/port-forwarding#_how-are-forwarded-ports-secured&quot;&gt;official documentation&lt;/a&gt; says it all.&lt;/p&gt;
&lt;h2 id=&quot;personal-take&quot; tabindex=&quot;-1&quot;&gt;Personal Take&lt;/h2&gt;
&lt;p&gt;Does this mean all other services which provide port forwarding or remote tunneling will be obsolete? No. Port forwarding in &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;VS Code&lt;/a&gt; still doesn&#39;t support remote tunneling and many other features which other services may provide. For now, it&#39;s just a basic feature built into VS Code, but the possibilities are endless.&lt;/p&gt;
&lt;p&gt;Anyways, I am pretty excited to try this out and see what it brings to the table. At the very least, now we don&#39;t have to have another extension just to forward ports.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/sharing-localhost-in-vscode-port-forwarding-Kew9D/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Docker — Containerizing a Nextjs Application</title>
    <link href="https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/"/>
    <published>2023-07-28T00:00:00Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Containerization in it&#39;s entirety is an incredibly useful concept. From being able to execute applications in isolation, to being able to port them easily with all of their dependencies and configuration is all a developer could ask for.&lt;/p&gt;
&lt;p&gt;After getting somewhat familiar with this concept, I decided to get my hands on it. So, let me walk you through the whole process of containerizing a frontend Nextjs application using Docker.&lt;/p&gt;
&lt;p&gt;Note that this is an absolute beginner approach. I am not advising to use it in production. This is something new to me and I am still exploring Docker. I don&#39;t know, maybe you can help me make some improvements to this approach.&lt;/p&gt;
&lt;p&gt;Anyways, this tutorial is for someone who wants to explore and get a hands on experience with Docker.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By the way, a huge shoutout to &lt;a href=&quot;https://www.youtube.com/@TechWorldwithNana&quot;&gt;Nana Janashia&lt;/a&gt; who is an incredible DevOps instructor. I learned everything about docker from her youtube channel. 💙&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;why-use-docker&quot; tabindex=&quot;-1&quot;&gt;Why use Docker? &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#why-use-docker&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You might be thinking what&#39;s the point of containerizing an application? Well, installing dependencies, setting up database, and doing a lot of configuration every single time, isn&#39;t it better to just configure it once and ship it so that it can be run on another machine without any hassle?&lt;/p&gt;
&lt;p&gt;And not only that, some dependencies pollute your local environment but with docker everything runs in an isolated environment giving you more control.&lt;/p&gt;
&lt;p&gt;Okay but why can&#39;t we use a virtual machine if the end goal is to isolate everything? The problem is — VMs are heavy and they run on their own OS and kernel. Docker uses the resources of its host but has its own application layer and file system. You only need the docker engine to run a containerized application.&lt;/p&gt;
&lt;p&gt;Apart from that, it makes it so much easier to collaborate with project team members, testers, and devops team to run the application regardless of their operating system.&lt;/p&gt;
&lt;p&gt;Watch &lt;a href=&quot;https://youtu.be/pg19Z8LL06w?t=232&quot;&gt;this video&lt;/a&gt; to learn what problems docker solves in development as well as the deployment process. ✨&lt;/p&gt;
&lt;div class=&quot;youtube-embed-container&quot;&gt;&lt;div class=&quot;youtube-embed&quot;&gt;&lt;lite-youtube videoid=&quot;3c-iBn73dDE&quot; playlabel=&quot;YouTube&quot;&gt;&lt;/lite-youtube&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Install Docker from &lt;a href=&quot;https://docs.docker.com/get-docker/&quot;&gt;docker.com&lt;/a&gt;! 🏃&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;understanding-docker&quot; tabindex=&quot;-1&quot;&gt;Understanding Docker &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#understanding-docker&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Docker revolves mainly around three core components: &lt;code&gt;containers&lt;/code&gt;, &lt;code&gt;images&lt;/code&gt; and &lt;code&gt;volumes&lt;/code&gt;. Let&#39;s understand what are they and how they work together.&lt;/p&gt;
&lt;p&gt;If you want to containerize your application, first you have to build an &lt;code&gt;image&lt;/code&gt; of it. An image is nothing but a combination of your app code, dependencies, and configuration. It&#39;s like a complete package of your application, ready to be shipped.&lt;/p&gt;
&lt;p&gt;A container is just a running instance of an image. It lets you run the application in an isolated environment. You can run multiple containers based on different images.&lt;/p&gt;
&lt;p&gt;Volumes are often used to store persistent data. For example, if you to access the host&#39; files from the container, you can use volumes to map the host path to a container path. I am yet to have a good grasp on the concept of volumes in docker but here&#39;s a good video on &lt;a href=&quot;https://www.youtube.com/watch?v=p2PH_YPCsis&quot;&gt;docker volumes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;docker-files&quot; tabindex=&quot;-1&quot;&gt;Docker Files &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#docker-files&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a bunch of docker-specific files which are used to configure docker. It&#39;s good to understand what each of them does, so here we go:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Dockerfile&lt;/code&gt;: It&#39;s used to build an image of an application.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker-compose.yaml&lt;/code&gt;: A structured way to execute docker commands with a lot of options in order to handle containers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.dockerignore&lt;/code&gt;: Similar to &lt;code&gt;.gitignore&lt;/code&gt; in &lt;a href=&quot;https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/&quot;&gt;git&lt;/a&gt;, it is used to ignore files in docker.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;containerization-of-a-simple-nextjs-application&quot; tabindex=&quot;-1&quot;&gt;Containerization of a Simple Nextjs Application&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Create a nextjs app using the steps in their &lt;a href=&quot;https://nextjs.org/learn/basics/create-nextjs-app&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While creating a nextjs application, I went for directory based routing and thus the &lt;code&gt;app&lt;/code&gt; directory will act like the &lt;code&gt;src&lt;/code&gt; directory. Now, you need to build an &lt;code&gt;image&lt;/code&gt; of your application so that you can run it inside a container.&lt;/p&gt;
&lt;h3 id=&quot;building-a-docker-image&quot; tabindex=&quot;-1&quot;&gt;Building a docker image &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#building-a-docker-image&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To create your own docker image, you need to create the &lt;code&gt;Dockerfile&lt;/code&gt;. This file will have everything you need to package your application including dependencies and initial commands. Create the &lt;code&gt;Dockerfile&lt;/code&gt; at the root of your project.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; node:18-bullseye-slim&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; mkdir -p /home/yourapp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;COPY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; . /home/yourapp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;WORKDIR&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /home/yourapp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; npm install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;CMD&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;npm&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;run&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;dev&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Directives such as &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;COPY&lt;/code&gt;, &lt;code&gt;RUN&lt;/code&gt;, etc., are specific to the Dockerfile. To execute and run your application you need node in your image, that&#39;s why we are directing docker to pull a &lt;code&gt;nodejs&lt;/code&gt; image from docker hub which the app can use.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://snyk.io/blog/choosing-the-best-node-js-docker-image/&quot;&gt;Selecting node images from docker hub is much more nuanced&lt;/a&gt; than this! Do your own research before selecting any node image.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then, with the &lt;code&gt;RUN&lt;/code&gt; directive, you are telling docker to run a command inside the image&#39;s file system. It will create a &lt;code&gt;yourapp&lt;/code&gt; directory in the home directory.&lt;/p&gt;
&lt;p&gt;Next, the &lt;code&gt;COPY&lt;/code&gt; directive will copy the files from the current directory of your local system to the &lt;code&gt;yourapp&lt;/code&gt; directory of image&#39;s file system.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To ignore certain files or directories such as &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;node_modules&lt;/code&gt;, etc., you can create a &lt;code&gt;.dockerignore&lt;/code&gt; file and list them there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the &lt;code&gt;WORKDIR&lt;/code&gt; directive, the current directory will be set to the root directory of your project in image&#39;s file system. If you don&#39;t specify it, &lt;code&gt;npm&lt;/code&gt; will install dependencies in the root directory of the file system and not your project.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;npm install&lt;/code&gt; command will install dependencies and create &lt;code&gt;node_modules&lt;/code&gt; folder so you don&#39;t need to copy it from your local system. The &lt;code&gt;CMD&lt;/code&gt; directive is like an entrypoint command to run your built image. Docker will by default execute this &lt;code&gt;CMD&lt;/code&gt; command when you run your built image in a container.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/NodeJS_Docker_Cheat_Sheet.html&quot;&gt;use of the &lt;code&gt;CMD&lt;/code&gt; directive is a bit more nuanced&lt;/a&gt; too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that your image building instructions are ready, you can execute the following command to create an image.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; build&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -t&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; image_name:tag&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;-t&lt;/code&gt; flag is for specifying a tag to the image. You can specify something like &lt;code&gt;1.0&lt;/code&gt; or anything you want by replacing the &lt;code&gt;:tag&lt;/code&gt; placeholder. And, the &lt;code&gt;.&lt;/code&gt; is actually the context path which will be used by Docker to find your project files. If you are at the root of your project, you can specify &lt;code&gt;.&lt;/code&gt;, otherwise you have to give a path relative to where your terminal is currently pointing to.&lt;/p&gt;
&lt;p&gt;After the command gets executed successfully, you should get something like this in your terminal.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[+] Building 55.4s (&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;11/11&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) FINISHED                                                       docker:default&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [internal] load build definition from Dockerfile                                                0.1s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;transferring&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; dockerfile:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 208B&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                                                0.0s&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [internal] load .dockerignore                                                                   0.0s &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;transferring&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; context:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 72B&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                                                    0.0s&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [internal] load metadata &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; docker.io/library/node:18-bullseye-slim                            2.5s &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [auth] library/node:pull token &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; registry-1.docker.io                                         0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [1/5] FROM docker.io/library/node:18-bullseye-slim@sha256:d2617c7df857596e4f29715c7a4d8e861852  0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [internal] load build context                                                                   0.1s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;transferring&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; context:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 18.36kB&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                                                0.1s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;CACHED&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [2/5] RUN mkdir -p /app/path                                                   0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [3/5] COPY &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; /app/path                                                                0.1s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [4/5] WORKDIR /app/path                                                               0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; [5/5] RUN npm install                                                                          41.8s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;exporting&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                                                             10.3s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;exporting&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; layers&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                                                            10.3s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;writing&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; sha256:fb05dcdb130301a8a1f8afa39c01a4430c59127e266cb49bcb763b5dd73d7aef&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;        0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; =&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;naming&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; docker.io/image_name:tag&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;                                  0.0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if you have docker desktop installed, you can see a docker image entry in the &lt;code&gt;images&lt;/code&gt; tab.&lt;/p&gt;
&lt;p&gt;That&#39;s the basic process for building an image in docker from a Dockerfile. You can port this image to any other machine and it will execute exactly the same as it will on your machine.&lt;/p&gt;
&lt;p&gt;But still, your app isn&#39;t running! Why? Because you didn&#39;t run the image. And that&#39;s where containers come into action.&lt;/p&gt;
&lt;h3 id=&quot;running-image-in-a-container&quot; tabindex=&quot;-1&quot;&gt;Running Image in a Container &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#running-image-in-a-container&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As you know, a container is nothing but a running instance of an image. So how do you run an image? Using &lt;code&gt;docker run&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -d&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -p5000:3000&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --name&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; container_name&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; image_name:tag&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&#39;s going on with this command? you may ask! Well, nothing much — the first flag &lt;code&gt;-d&lt;/code&gt; is used for &lt;code&gt;detached&lt;/code&gt; mode which basically means the container will keep running in the background by freeing your terminal. If you don&#39;t specify it, the container will log everything in the terminal and once you kill the process, the container will exit and stop running.&lt;/p&gt;
&lt;p&gt;The second flag &lt;code&gt;-p&lt;/code&gt; is used for port binding. Port binding in docker is a way to map the container port to a port on your machine i.e. host port. Let&#39;s say you are running your application at port &lt;code&gt;3000&lt;/code&gt; inside the container and because the container is isolated, it has it&#39;s own ports, and thus you have to specify which port on your local machine will it forward the application content to.&lt;/p&gt;
&lt;p&gt;Here, with &lt;code&gt;-p5000:3000&lt;/code&gt; you are binding the &lt;code&gt;3000&lt;/code&gt; port of your container to the port &lt;code&gt;5000&lt;/code&gt; of your local machine. So, the syntax is:  &lt;code&gt;-pHOST:CONTAINER&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next two arguments are quite straightforward. You have to specify a container name and the name of the image which you want to run with it&#39;s tag.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have some &lt;code&gt;env&lt;/code&gt; variables, you can specify them in an env file and then use the flag &lt;a href=&quot;https://docs.docker.com/compose/environment-variables/set-environment-variables&quot;&gt;&lt;code&gt;--env-file&lt;/code&gt;&lt;/a&gt; to specify the path of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After running the command, you will see a container being created and the command which we specified in the &lt;code&gt;CMD&lt;/code&gt; directive will get executed, and the app will be live at port &lt;code&gt;5000&lt;/code&gt;!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To see all the running containers just run &lt;code&gt;docker ps&lt;/code&gt; and to view all containers, run &lt;code&gt;docker ps -a&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But there&#39;s a catch, every time you need to run an image, you have to run the docker run command with a long list of options. This isn&#39;t feasible and and it&#39;s time consuming when you have multiple services or containers talking to each other in a complex application. To overcome this, there&#39;s a file named &lt;code&gt;docker-compose.yaml&lt;/code&gt; which you can use to specify the containers with all of their required options and env variables. With only one container, your docker compose file can look something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  your_container_name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;your_container_name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;image_name:tag&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    env_file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&amp;#x3C;&amp;#x3C;path to env file&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;5000:3000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    command&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;npm run dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To run docker compose, execute &lt;code&gt;docker-compose up -d&lt;/code&gt; with a detached flag for the container to run in the background. To stop and remove the container, run &lt;code&gt;docker-compose down&lt;/code&gt;!&lt;/p&gt;
&lt;h3 id=&quot;persistent-data-volumes&quot; tabindex=&quot;-1&quot;&gt;Persistent Data - Volumes &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#persistent-data-volumes&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Try updating your nextjs code locally and see if you can see those changes being reflected in your containerized application. Does it update? No, it won&#39;t. The reason for that is your local code is not in sync with the code in the container, i.e. the code running in the container hasn&#39;t updated and is still the same.&lt;/p&gt;
&lt;p&gt;To overcome this issue, you need to keep some of your container files in sync with the local files. Volumes can be used to do that. You need to map your local directory to the container&#39;s directory with the help of a volume, which will help docker to listen for changes in the local directory and update the container directory!&lt;/p&gt;
&lt;p&gt;In your &lt;code&gt;docker-compose.yaml&lt;/code&gt; file, add the following:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  container_name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    # ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;./app:your_container_app_dir/app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    # ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the current nextjs application, you can persist the &lt;code&gt;app&lt;/code&gt; directory (if you opted for directory based navigation) or the &lt;code&gt;src&lt;/code&gt; directory. The path before the colon &lt;code&gt;:&lt;/code&gt; is your local directory&#39;s relative path to the app directory and the path after &lt;code&gt;:&lt;/code&gt; is the absolute path to where the project lives and it&#39;s app directory.&lt;/p&gt;
&lt;h3 id=&quot;live-reloading-hmr&quot; tabindex=&quot;-1&quot;&gt;Live Reloading (HMR) &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/#live-reloading-hmr&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All of that takes care of synching files, but hot reloading still won&#39;t work when you make any changes to the app directory. For that to work, you have to add a webpack config to the &lt;code&gt;next.config.js&lt;/code&gt; file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; nextConfig&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  webpack&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    config&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;watchOptions&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      poll&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      aggregateTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      ignored&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;**/node_modules&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;a href=&quot;https://syntackle.com/blog/the-issue-of-watching-file-changes-in-docker/&quot;&gt;reason behind the use of &lt;code&gt;polling&lt;/code&gt;&lt;/a&gt; is that &lt;code&gt;webpack&lt;/code&gt; and other similar bundlers use some packages such as &lt;code&gt;fsevent&lt;/code&gt; or &lt;code&gt;inotify&lt;/code&gt; to detect file changes. The problem with that is that docker uses it&#39;s own filesystem which is linux based irrespective of the OS&#39; filesystem. Maybe I am missing some details, but that causes discrepancies in the file change detection and live reload process. Polling works on a network level, thus resolving the filesystem issue, but some say it can be expensive and slow. — &lt;a href=&quot;https://stackoverflow.com/a/46804953/17241798&quot;&gt;stackoverflow.com/a/46804953&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After updating your next config, you need to rebuild the image because you didn&#39;t persist that file to reflect your local changes, rather added it as a one time static file using the &lt;code&gt;COPY&lt;/code&gt; directive. A better approach would be to add whole project directory to the volume so that you don&#39;t have to rebuild the image, but it&#39;s debatable.&lt;/p&gt;
&lt;h2 id=&quot;final-words&quot; tabindex=&quot;-1&quot;&gt;Final Words&lt;/h2&gt;
&lt;p&gt;That&#39;s it, you just built your own docker image and ran it in a container. If you want, you can also &lt;a href=&quot;https://docs.docker.com/get-started/publish-your-own-image/&quot;&gt;publish your docker image to docker hub&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/containerizing-a-nextjs-application-using-docker-st_G0u/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>WebSockets 101</title>
    <link href="https://syntackle.com/blog/websockets-101-JiIrdn/"/>
    <published>2023-06-22T00:00:00Z</published>
    <updated>2024-12-31T13:18:29Z</updated>
    <id>https://syntackle.com/blog/websockets-101-JiIrdn/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;WebSockets implement a full-duplex, bi-directional, TCP-based protocol, denoted by &lt;code&gt;ws(s)://&lt;/code&gt;, which enables a persistent connection between the client and the server.&lt;/p&gt;
&lt;h2 id=&quot;why-are-websockets-required&quot; tabindex=&quot;-1&quot;&gt;Why are websockets required? &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/#why-are-websockets-required&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Back when websockets weren&#39;t a thing, HTTP polling was used for a similar purpose. HTTP is basically a uni-directional protocol wherein a &lt;em&gt;client&lt;/em&gt; sends a &lt;code&gt;request&lt;/code&gt; to the &lt;em&gt;server&lt;/em&gt;, the &lt;em&gt;server&lt;/em&gt; accepts the request and sends a &lt;code&gt;response&lt;/code&gt;. The server &lt;em&gt;&lt;strong&gt;can&#39;t&lt;/strong&gt;&lt;/em&gt; send a response for which no request has been made by the client. In simple terms, it only responds to what it&#39;s asked for.&lt;/p&gt;
&lt;p&gt;This type of behavior poses a problem for real-time applications. What if the server needs to send some information to the client but the client doesn&#39;t know about it yet? It can&#39;t initiate a response without a request.&lt;/p&gt;
&lt;p&gt;To overcome these type of situations, a workaround is used, known as &lt;code&gt;polling&lt;/code&gt;. The client assumes that there might be something that will be required later in time from the server and sends periodic requests at specific intervals to the server known as &lt;em&gt;poll requests&lt;/em&gt; to check if there&#39;s something new. If there&#39;s nothing new for the server to send, it just responds with an empty response. This approach is known as &lt;em&gt;short polling&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1687454824/Syntackle/Posts/short_polling_yp1tbn.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1687454824/Syntackle/Posts/short_polling_yp1tbn.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1687454824/Syntackle/Posts/short_polling_yp1tbn.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1687454824/Syntackle/Posts/short_polling_yp1tbn.jpg&quot; alt=&quot;short polling illustration&quot; height=&quot;1346&quot; width=&quot;1766&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Short Polling&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Long polling&lt;/em&gt; is a similar approach as &lt;em&gt;short polling&lt;/em&gt; except the fact that the server doesn&#39;t respond with an empty response on a poll request by the client. Instead, it receives the request, keeps the connection open, and only responds to it when there is actually something new that needs to be sent to the client. After the server sends a response with some data, the client sends another poll request either immediately or after a delay. That&#39;s how the server is actually able to &lt;em&gt;initiate&lt;/em&gt; the communication which isn&#39;t possible in traditional HTTP protocol.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1687455585/Syntackle/Posts/long_polling_m64bi7.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1687455585/Syntackle/Posts/long_polling_m64bi7.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1687455585/Syntackle/Posts/long_polling_m64bi7.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1687455585/Syntackle/Posts/long_polling_m64bi7.jpg&quot; alt=&quot;long polling illustration&quot; height=&quot;964&quot; width=&quot;1766&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Long Polling&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Both of the above techniques have their own &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc6202#section-2.2&quot;&gt;drawbacks&lt;/a&gt; which lead to the use of websockets.&lt;/p&gt;
&lt;h2 id=&quot;working-of-websockets&quot; tabindex=&quot;-1&quot;&gt;Working of Websockets &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/#working-of-websockets&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Websockets allow the client &lt;em&gt;as well as&lt;/em&gt; the server to initiate the sending of messages. The websocket protocol involves a two-part process. The first part involves a &lt;em&gt;handshake&lt;/em&gt; and the latter part involves the exchange of &lt;em&gt;data&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1687457196/Syntackle/Posts/websocket_illustration_kxu8gq.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1687457196/Syntackle/Posts/websocket_illustration_kxu8gq.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1687457196/Syntackle/Posts/websocket_illustration_kxu8gq.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_jpg,q_auto:eco/v1687457196/Syntackle/Posts/websocket_illustration_kxu8gq.jpg&quot; alt=&quot;websocket illustration&quot; height=&quot;1346&quot; width=&quot;1766&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;WebSocket Illustration&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The initial handshake occurs when the client sends an HTTP 1.1 request to the server with an &lt;code&gt;upgrade&lt;/code&gt; header set to &lt;code&gt;websocket&lt;/code&gt;. This simply means that the client is informing the server that this connection isn&#39;t a normal HTTP connection, rather it needs to be upgraded to a websocket connection.&lt;/p&gt;
&lt;p&gt;The client&#39;s request looks something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ws://localhost:5000/&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; HTTP/1.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Host:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; localhost:5000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Connection:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Upgrade&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Upgrade:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; websocket&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Origin:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; http://localhost:3000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Sec-WebSocket-Version:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Sec-WebSocket-Key:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; VloOROMIOo0curA7dETByw==&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Sec-WebSocket-Extensions:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; permessage-deflate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;client_max_window_bits&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The connection type in the above request is set to &lt;em&gt;upgrade&lt;/em&gt; and the upgrade protocol is set to &lt;em&gt;websocket&lt;/em&gt;. The &lt;code&gt;upgrade&lt;/code&gt; header can &lt;em&gt;only&lt;/em&gt; be used in HTTP 1.1 requests to upgrade to a different protocol.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;sec-websocket-version&lt;/code&gt;, &lt;code&gt;sec-websocket-key&lt;/code&gt;, and &lt;code&gt;sec-websocket-extensions&lt;/code&gt; are special headers sent by the client to further describe the websocket connection.&lt;/p&gt;
&lt;p&gt;Now that the client request is sent, the server will verify the request (to make sure that it&#39;s a genuine websocket connection), accept the request if it supports a websocket connection, and return the verification response.&lt;/p&gt;
&lt;p&gt;Request verification is done as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The server needs two pieces of information — &lt;code&gt;sec-websocket-key&lt;/code&gt; and &lt;code&gt;GUID&lt;/code&gt; to verify the request.&lt;/li&gt;
&lt;li&gt;It will then perform necessary operations on this information and derive a &lt;code&gt;sec-websocket-accept&lt;/code&gt; value that is later sent to the client as a response header. This value tells the client that the server has accepted the connection and it can now verify the value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;sec-websocket-accept&lt;/code&gt; header isn&#39;t the only thing which is required to know if the server has accepted the connection or not. There&#39;s also a status code of &lt;code&gt;101&lt;/code&gt; which must be present to echo the acceptance of connection by the server. Any status code other than &lt;code&gt;101&lt;/code&gt; tells that the websocket connection isn&#39;t complete.&lt;/p&gt;
&lt;p&gt;The server response looks something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;HTTP/1.1&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 101&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Switching&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Protocols&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Upgrade:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; websocket&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Connection:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; Upgrade&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;Sec-WebSocket-Accept:&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; 30RLwsqJ/mc0ojx6XVmAQTDJSvY=&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, at this stage, both the client and the server are ready to receive messages from each other.&lt;/p&gt;
&lt;p&gt;The websocket instance has access to various events such as &lt;code&gt;onopen&lt;/code&gt;, &lt;code&gt;onclose&lt;/code&gt;, &lt;code&gt;onmessage&lt;/code&gt;, etc. to perform some operations when these events occur.&lt;/p&gt;
&lt;p&gt;To better understand the flow of messages and various events, let&#39;s build a small application which implements websockets.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;recommended-%E2%9C%A8&quot; tabindex=&quot;-1&quot;&gt;Recommended ✨&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://syntackle.com/blog/server-sent-events/&quot;&gt;Server Sent Events 101&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;building-a-websocket-application&quot; tabindex=&quot;-1&quot;&gt;Building a Websocket Application &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/#building-a-websocket-application&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to implement websockets, you can use a nodejs library named &lt;a href=&quot;https://github.com/websockets/ws&quot;&gt;&lt;code&gt;ws&lt;/code&gt;&lt;/a&gt;. It provides a fast and simple way to establish a websocket connection.&lt;/p&gt;
&lt;h3 id=&quot;websocket-server&quot; tabindex=&quot;-1&quot;&gt;WebSocket Server&lt;/h3&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; ws&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Firstly, you need a server to handle websocket requests. The &lt;code&gt;ws&lt;/code&gt; library provides an interface named &lt;code&gt;WebSocketServer&lt;/code&gt; to create a websocket server.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// server.mjs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;WebSocketServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;ws&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; wsServer&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; WebSocketServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, you can start attaching events to this server.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;wsServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;connection&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    //...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above event will trigger whenever the server receives a new connection request from a client. It provides a callback function with the &lt;code&gt;websocket&lt;/code&gt; instance (&lt;em&gt;for a particular client&lt;/em&gt;) and the request object.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;wsServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;connection&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; currentClient&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;headers&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;sec-websocket-key&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentClient&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; just got connected&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;clients connected: &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;wsServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;clients&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use the request object to the &lt;code&gt;sec-websocket-key&lt;/code&gt; header value, which I have used to identify a client. In production you must generate a unique id by yourself. This is just for demonstration purposes. Using the above &lt;a href=&quot;https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/&quot;&gt;code&lt;/a&gt;, you can log the client connection on the server.&lt;/p&gt;
&lt;p&gt;Next, let&#39;s see how you can broadcast a message to all clients connected to the server except the current client.&lt;/p&gt;
&lt;p&gt;So, here&#39;s a function that accepts a message &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/&quot;&gt;object&lt;/a&gt; and broadcasts it to all clients except the one who is sending it.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; broadcast&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; stringifiedMessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; JSON&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;stringify&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    wsServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;clients&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; ws&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;readyState&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; WebSocket&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;OPEN&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            client&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;stringifiedMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;                    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;                    return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The websocket server — &lt;code&gt;wsServer&lt;/code&gt;, has access to all the clients connected to it. The &lt;code&gt;ws&lt;/code&gt; websocket instance itself describes the client. So, you can verify the client against the current &lt;code&gt;ws&lt;/code&gt; instance and send the message accordingly.&lt;/p&gt;
&lt;p&gt;Also, the message should only be sent if the websocket connection is still open. If a client gets disconnected, the message will not be sent.&lt;/p&gt;
&lt;p&gt;But, what if we want to send a message only to the current client? For that, you simply need to do this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;error&lt;/code&gt; event of the websocket will allow you to log if anything goes wrong.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whenever a client sends a message to the server, the &lt;code&gt;message&lt;/code&gt; event will get triggered by which you can broadcast the message to all the clients if you want to.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;message&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; incomingMessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;utf8&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; outgoingMessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentClient&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;incomingMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            isConnectionMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    broadcast&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;outgoingMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; you are getting in the message event will be a buffer, so you need to parse it into a string.&lt;/p&gt;
&lt;p&gt;You can also broadcast a &lt;em&gt;client disconnected&lt;/em&gt; message to all of the connected clients on the event of disconnection of a specific client.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;close&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&#92;n&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentClient&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; closed the connection&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Remaining clients &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;wsServer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;clients&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    broadcast&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentClient&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        data&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;currentClient&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; just left the chat`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            isConnectionMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            isDisconnectionMessage&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;websocket-client&quot; tabindex=&quot;-1&quot;&gt;WebSocket Client&lt;/h3&gt;
&lt;p&gt;A websocket client is nothing but a webpage with some &lt;a href=&quot;https://www.greatfrontend.com/questions/js?fpr=murtuzaali48&quot;&gt;client-side javascript&lt;/a&gt;. You must use the native &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API&quot;&gt;&lt;code&gt;WebSocket&lt;/code&gt;&lt;/a&gt; API provided by the browser to establish a websocket connection.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; ws&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; WebSocket&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;ws://localhost: 5000&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The client&#39;s &lt;code&gt;ws&lt;/code&gt; instance has access to the same events like &lt;code&gt;open&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt;, &lt;code&gt;message&lt;/code&gt;, etc. because it is essentially a websocket connection instance.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onopen&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onclose&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;onmessage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;ws&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multiple browser instances (&lt;em&gt;or tabs&lt;/em&gt;) connected to the same websocket server can serve the purpose of multiple clients.&lt;/p&gt;
&lt;p&gt;That&#39;s it. You can now send messages to the server and observe how they get broadcasted to multiple connected clients.&lt;/p&gt;
&lt;h2 id=&quot;use-cases&quot; tabindex=&quot;-1&quot;&gt;Use Cases &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/#use-cases&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Real-Time Collaboration&lt;/li&gt;
&lt;li&gt;Chat Applications&lt;/li&gt;
&lt;li&gt;Multiplayer gaming&lt;/li&gt;
&lt;li&gt;Real-Time Feeds&lt;/li&gt;
&lt;li&gt;Live Browser Reloading&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&#39;s the &lt;a href=&quot;https://github.com/murtuzaalisurti/ws-websocket&quot;&gt;github repository&lt;/a&gt; containing the entire code.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/websockets-101-JiIrdn/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Builder.io&#39;s Partytown with 11ty</title>
    <link href="https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/"/>
    <published>2023-04-05T00:00:00Z</published>
    <updated>2025-01-05T06:43:19Z</updated>
    <id>https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Third party analytics scripts are generally included in the &lt;code&gt;head&lt;/code&gt; section of HTML. It poses a performance threat because of &lt;a href=&quot;https://developer.chrome.com/en/docs/lighthouse/performance/render-blocking-resources/&quot;&gt;render blocking&lt;/a&gt; nature of those resources.&lt;/p&gt;
&lt;p&gt;Although you can use the &lt;code&gt;async&lt;/code&gt; or &lt;code&gt;defer&lt;/code&gt; attribute to deal with those resources, they are still on the &lt;a href=&quot;https://dev.to/bbarbour/if-javascript-is-single-threaded-how-is-it-asynchronous-56gd&quot;&gt;main thread&lt;/a&gt; of javascript.&lt;/p&gt;
&lt;p&gt;What if you can shift them to a different thread and free the main thread? Yes, you can do it by using &lt;a href=&quot;https://partytown.qwik.dev/&quot;&gt;partytown&lt;/a&gt;, which is nothing but a library which uses web workers to separately execute third party scripts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Javascript is single-threaded, yet it is capable to execute asynchronous code! How? Well, here&#39;s an &lt;a href=&quot;http://latentflip.com/loupe&quot;&gt;interactive demo&lt;/a&gt; which will help you understand how the &lt;a href=&quot;https://youtu.be/8aGhZQkoFbQ&quot;&gt;event loop&lt;/a&gt; and web APIs work when the browser executes javascript!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Diving into &lt;a href=&quot;https://partytown.qwik.dev/how-does-partytown-work&quot;&gt;how partytown works&lt;/a&gt; is out of the scope of this article, but at the surface level, it manages to interact with the DOM synchronously from a &lt;a href=&quot;https://partytown.qwik.dev/#web-workers&quot;&gt;web worker&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_avif,q_auto:eco/v1680798425/Syntackle/Posts/builder-io-s-partytown-with-11ty-lN6X2w.avif&quot; type=&quot;image/avif&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_webp,q_auto:eco/v1680798425/Syntackle/Posts/builder-io-s-partytown-with-11ty-lN6X2w.webp&quot; type=&quot;image/webp&quot; /&gt;&lt;source srcset=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_png,q_auto:eco/v1680798425/Syntackle/Posts/builder-io-s-partytown-with-11ty-lN6X2w.png&quot; type=&quot;image/png&quot; /&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/f_auto,q_auto:eco/v1680798425/Syntackle/Posts/builder-io-s-partytown-with-11ty-lN6X2w.jpg&quot; alt=&quot;web worker in partytown&quot; height=&quot;611&quot; width=&quot;1169&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;&lt;a href=&quot;https://partytown.qwik.dev/#web-workers&quot;&gt;Web workers&lt;/a&gt; in partytown&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;integration&quot; tabindex=&quot;-1&quot;&gt;Integrating Partytown with 11ty &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/#integration&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Partytown is framework agnostic, i.e. you can even use it in a simple HTML-only site. For 11ty, you can install the &lt;code&gt;@qwik.dev/partytown&lt;/code&gt; npm package and extract a snippet from the &lt;code&gt;integration&lt;/code&gt; submodule which is required to execute partytown.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M12 16v-4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8h.01&quot;&gt;&lt;/path&gt;&lt;/svg&gt; INFO&lt;/p&gt;
&lt;p&gt;The partytown package is now moved under a new organization, &lt;code&gt;@qwik.dev/partytown&lt;/code&gt;. So move the npm package from &lt;code&gt;@builder.io/partytown&lt;/code&gt; to &lt;code&gt;@qwik.dev/partytown&lt;/code&gt; to get the latest releases.&lt;/p&gt;
&lt;/div&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @qwik.dev/partytown&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside &lt;code&gt;eleventy&lt;/code&gt; config:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;partytownSnippet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;@qwik.dev/partytown/integration&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You must include this snippet in your base layout or wherever you want to include partytown. I inserted it by using a &lt;a href=&quot;https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/&quot;&gt;shortcode&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addShortcode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;partytown&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; partytownSnippet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;());&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The shortcode (for nunjucks / liquid) will be:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{% &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;partytown&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use it inside a &lt;code&gt;script&lt;/code&gt; element like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; partytown&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; %&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The partytown snippet will now be inline with your HTML.&lt;/p&gt;
&lt;p&gt;Next, some &lt;a href=&quot;https://partytown.qwik.dev/copy-library-files&quot;&gt;static files need to be served&lt;/a&gt; from the same origin for partytown to work. These files, by default, &lt;em&gt;must&lt;/em&gt; be present in the &lt;code&gt;/~partytown/&lt;/code&gt; directory of your build.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tip: If you really want to serve &lt;code&gt;lib&lt;/code&gt; files from a different directory, you can specify it in the &lt;a href=&quot;https://partytown.qwik.dev/configuration&quot;&gt;&lt;code&gt;lib config&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Copy required files using &lt;a href=&quot;https://www.11ty.dev/docs/copy/&quot;&gt;&lt;code&gt;addPassthroughCopy&lt;/code&gt;&lt;/a&gt; in 11ty.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPassthroughCopy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;./node_modules/@qwik.dev/partytown/lib/*&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;~partytown&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPassthroughCopy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;./node_modules/@qwik.dev/partytown/lib/debug/*&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;~partytown/debug&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;adding-third-party-script&quot; tabindex=&quot;-1&quot;&gt;Adding Third Party Script &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/#adding-third-party-script&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For this tutorial, I am using google analytics script but &lt;a href=&quot;https://partytown.qwik.dev/common-services&quot;&gt;any third party script&lt;/a&gt; can be executed with partytown.&lt;/p&gt;
&lt;p&gt;First, you need to add an inline partytown config script which will be above any third party scripts declared. A partytown config script specific to &lt;a href=&quot;https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/&quot;&gt;google&lt;/a&gt; analytics will be:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    partytown = &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      forward&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;dataLayer.push&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    }&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add a &lt;code&gt;type=&amp;quot;text/partytown&amp;quot;&lt;/code&gt; attribute to all the third party scripts. By doing so, these scripts will be ignored by the main thread and executed on the web worker instead.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/partytown&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;analytics url&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// other third party inline scripts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/partytown&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    // script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The order of scripts will be as follows:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// partytown config script for google analytics &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    partytown = &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      forward&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;dataLayer.push&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    }&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// partytown inline script &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; partytown&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; %&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// third party scripts with &quot;type=&#39;text/partytown&#39;&quot; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/partytown&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&amp;#x3C;analytics url&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text/partytown&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    // script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;debugging&quot; tabindex=&quot;-1&quot;&gt;Debugging &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/#debugging&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For debugging partytown, you can specify &lt;code&gt;debug: true&lt;/code&gt; option in the partytown config script.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;partytown&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    debug&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable the &lt;code&gt;verbose&lt;/code&gt; level in chrome dev tools&#39; console and you will be able to see the partytown logs.&lt;/p&gt;
&lt;h2 id=&quot;takeaway&quot; tabindex=&quot;-1&quot;&gt;Takeaway &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/#takeaway&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Personally, I find the idea of using web workers to execute render blocking third party scripts interesting, partly because it improves performance and partly because it&#39;s simple. It does come with some &lt;a href=&quot;https://partytown.qwik.dev/trade-offs&quot;&gt;trade-offs&lt;/a&gt; though, but so does every other technology.&lt;/p&gt;
&lt;p&gt;And not just &lt;a href=&quot;https://11ty.dev/&quot;&gt;11ty&lt;/a&gt;, partytown can be &lt;a href=&quot;https://partytown.qwik.dev/integrations&quot;&gt;integrated&lt;/a&gt; with almost any modern frontend framework or library. At the time of writing, partytown is still in &lt;code&gt;beta&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;further-reading-%F0%9F%93%83&quot; tabindex=&quot;-1&quot;&gt;Further Reading 📃&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/adamdbradley/introducing-partytown-run-third-party-scripts-from-a-web-worker-2cnp&quot;&gt;Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/adamdbradley/how-partytown-s-sync-communication-works-4244&quot;&gt;How Partytown&#39;s Sync Communication Works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://partytown.qwik.dev/atomics&quot;&gt;Atomics - Partytown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://partytown.qwik.dev/browser-support&quot;&gt;Browser Support - Partytown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Why I love Markdown</title>
    <link href="https://syntackle.com/blog/why-i-love-markdown-Ib00ES/"/>
    <published>2023-03-08T00:00:00Z</published>
    <updated>2023-12-08T10:49:36Z</updated>
    <id>https://syntackle.com/blog/why-i-love-markdown-Ib00ES/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;Markdown is one of those languages to which I was introduced when I started using github for hosting my projects. The famous &lt;a href=&quot;https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes&quot;&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/a&gt; file got me into using markdown. That was my first encounter with markdown and since then, I never looked back. Here&#39;s why.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR&lt;/strong&gt; - It&#39;s simple! And I love simplicity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;about-markdown&quot; tabindex=&quot;-1&quot;&gt;A little bit about Markdown &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/#about-markdown&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Markdown is a markup language which is more easy and efficient to read and write formatted text rather than using &lt;a href=&quot;https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/&quot;&gt;HTML&lt;/a&gt;. It was created by &lt;a href=&quot;https://daringfireball.net/&quot;&gt;John Gruber&lt;/a&gt; who is a well-known blogger.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; serves as an abstraction which allows you to focus on writing rich text and forget about opening and closing those HTML tags every now and then.&lt;/p&gt;
&lt;p&gt;It then, gets compiled down to regular HTML by a &lt;a href=&quot;https://github.com/markdown-it/markdown-it&quot;&gt;markdown processor&lt;/a&gt; so that the browser can understand it and display it on the screen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Thus, &#39;Markdown&#39; is two things: (1) a plain text formatting syntax; and (2) a software tool, written in Perl, that converts the plain text formatting to HTML.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;— &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;John Gruber&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Reasons why I like to use Markdown:&lt;/p&gt;
&lt;h2 id=&quot;efficiency&quot; tabindex=&quot;-1&quot;&gt;1. It&#39;s efficient &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/#efficiency&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Previous to using markdown, I used WYSIWYG editors such as &lt;a href=&quot;https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/&quot;&gt;Google&lt;/a&gt; Docs and Microsoft Word which are sometimes an overkill when writing a simple blog post.&lt;/p&gt;
&lt;p&gt;I spent half of the time looking for tools to format the text, selecting and clicking over buttons with my mouse to get the job done.&lt;/p&gt;
&lt;p&gt;With markdown, things get incredibly easy. You just remember the syntax (and it&#39;s easy too) by practicing it a couple of times and write as well as format the text without breaking your flow.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6370&quot;&gt;&gt; This is a blockquote. The &lt;/span&gt;&lt;span style=&quot;color:#C678DD;font-style:italic&quot;&gt;*text*&lt;/span&gt;&lt;span style=&quot;color:#5C6370&quot;&gt; is in italics and this &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;**text**&lt;/span&gt;&lt;span style=&quot;color:#5C6370&quot;&gt; is bold.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;readable-syntax&quot; tabindex=&quot;-1&quot;&gt;2. Readable Syntax &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/#readable-syntax&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://daringfireball.net/projects/markdown/syntax&quot;&gt;markdown syntax&lt;/a&gt; is easy to remember as well as easy to read when accompanied with text.&lt;/p&gt;
&lt;p&gt;The syntax never takes the soul away from the text. You don&#39;t need to worry about those opening and closing tags in HTML.&lt;/p&gt;
&lt;p&gt;It enriches the text just the right way.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;&amp;#x3C;!-- list in HTML --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Item 1&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Item 2&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Item 3&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;&amp;#x3C;!-- list in markdown --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; Item 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; Item 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; Item 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;implementation&quot; tabindex=&quot;-1&quot;&gt;3. Implementation &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/#implementation&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You might have heard of different &lt;code&gt;flavors&lt;/code&gt; of markdown. Flavors of markdown simply extend or customize the markdown syntax.&lt;/p&gt;
&lt;p&gt;Different tools supporting markdown may have a slightly different syntax and markdown processing methods.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“To wrap your head around the concept of Markdown flavors, it might help to think of them as language dialects. People in New York City speak English just like the people in London, but there are substantial differences between the dialects used in both cities.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;— &lt;a href=&quot;https://www.markdownguide.org/getting-started/#flavors-of-markdown&quot;&gt;markdownguide.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I like the idea of having different implementations because it opens the door for new ideas to emerge. But, it comes at a cost. There is no &lt;strong&gt;standard specification&lt;/strong&gt; for markdown implementation and this is why some people prefer &lt;a href=&quot;https://ericholscher.com/blog/2016/mar/15/dont-use-markdown-for-technical-docs/&quot;&gt;not to use markdown for certain purposes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;markdown-is-not-perfect&quot; tabindex=&quot;-1&quot;&gt;Markdown is Not Perfect &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/#markdown-is-not-perfect&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After working with markdown for a good amount of time, I realised that it is extremely &lt;a href=&quot;https://www.markdownguide.org/getting-started/#whats-markdown-good-for&quot;&gt;good for certain things&lt;/a&gt; but &lt;a href=&quot;https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/&quot;&gt;not good for certain things&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&#39;s say you want to add a class to your paragraph element but using markdown. There is no way of doing so. What I did, and what most people do is that they add plain HTML into the markdown file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;## Heading 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;desc&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    Description&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;final-words&quot; tabindex=&quot;-1&quot;&gt;Final words&lt;/h2&gt;
&lt;p&gt;Markdown works really well if you use it to create some kind of written content in the form of blogs, notes, etc. Where it lacks is standardization. If you are using a specific tool to process your markdown, you can&#39;t switch to another tool instantaneously. You may need to modify your markdown syntax as per the requirement of the new tool. I think that&#39;s the biggest drawback for most of the people.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The blog post you just read, is also written using markdown.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/why-i-love-markdown-Ib00ES/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>What is DOM diffing?</title>
    <link href="https://syntackle.com/blog/what-is-dom-diffing-bB8Ltf/"/>
    <published>2023-03-01T00:00:00Z</published>
    <updated>2023-12-17T10:40:52Z</updated>
    <id>https://syntackle.com/blog/what-is-dom-diffing-bB8Ltf/</id>
    <content xml:lang="en" type="html">&lt;!-- markdownlint-disable MD033 --&gt;
&lt;p&gt;DOM, also known as the Document Object Model, is a programmatic representation of the contents of a web page. In other words, the content of a web page is represented in the form of &lt;code&gt;objects&lt;/code&gt; and &lt;code&gt;nodes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But why is there a need to represent it in such format? It&#39;s required because it allows programming languages such as &lt;a href=&quot;https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/&quot;&gt;JavaScript&lt;/a&gt; to manipulate or modify the content of a web page.&lt;/p&gt;
&lt;h2 id=&quot;the-dom&quot; tabindex=&quot;-1&quot;&gt;The DOM&lt;/h2&gt;
&lt;p&gt;DOM acts as an API (Application Programming Interface) to modify the structure as well as the content of a web page.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;!&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;DOM Tree&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Heading&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;contact&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;h2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Murtuzaali Surti&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;h2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;github&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;@murtuzaalisurti&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&#39;s the visualization of the above DOM tree:&lt;/p&gt;
&lt;div style=&quot;background-color: white; overflow: hidden; border: none; border-radius: 0.5rem; padding: 1rem 2rem;&quot;&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 778 471&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;&lt;g transform=&quot;translate(-36.4,30)&quot;&gt;&lt;path class=&quot;link&quot; d=&quot;M366.59999999999997,0C366.59999999999997,53.25 169.2,53.25 169.2,106.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M366.59999999999997,0C366.59999999999997,53.25 366.59999999999997,53.25 366.59999999999997,106.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M366.59999999999997,0C366.59999999999997,53.25 564,53.25 564,106.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M169.2,106.5C169.2,159.75 56.4,159.75 56.4,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M169.2,106.5C169.2,159.75 112.8,159.75 112.8,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M169.2,106.5C169.2,159.75 169.2,159.75 169.2,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M169.2,106.5C169.2,159.75 225.6,159.75 225.6,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M169.2,106.5C169.2,159.75 282,159.75 282,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M225.6,213C225.6,266.25 225.6,266.25 225.6,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M564,106.5C564,159.75 394.8,159.75 394.8,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M564,106.5C564,159.75 451.2,159.75 451.2,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M564,106.5C564,159.75 564,159.75 564,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M564,106.5C564,159.75 676.8,159.75 676.8,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M564,106.5C564,159.75 733.1999999999999,159.75 733.1999999999999,213&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M451.2,213C451.2,266.25 451.2,266.25 451.2,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M676.8,213C676.8,266.25 564,266.25 564,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M676.8,213C676.8,266.25 620.4,266.25 620.4,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M676.8,213C676.8,266.25 676.8,266.25 676.8,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M676.8,213C676.8,266.25 733.1999999999999,266.25 733.1999999999999,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M676.8,213C676.8,266.25 789.6,266.25 789.6,319.5&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M620.4,319.5C620.4,372.75 620.4,372.75 620.4,426&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;path class=&quot;link&quot; d=&quot;M733.1999999999999,319.5C733.1999999999999,372.75 733.1999999999999,372.75 733.1999999999999,426&quot; style=&quot;opacity: 1; fill: none; stroke: rgb(204, 204, 204);&quot;&gt;&lt;/path&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(366.59999999999997,0)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;html&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(169.2,106.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;head&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(56.4,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(112.8,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;meta&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(169.2,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(225.6,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;title&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text&quot; transform=&quot;translate(225.6,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(80, 180, 86); stroke: rgb(13, 149, 44);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(282,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(366.59999999999997,106.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(564,106.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;body&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(394.8,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(451.2,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;h1#title&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text&quot; transform=&quot;translate(451.2,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(80, 180, 86); stroke: rgb(13, 149, 44);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(564,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(676.8,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;div.contact&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(564,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(620.4,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;h2&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text&quot; transform=&quot;translate(620.4,426)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(80, 180, 86); stroke: rgb(13, 149, 44);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(676.8,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node element&quot; transform=&quot;translate(733.1999999999999,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: steelblue; stroke: rgb(53, 94, 149);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;p#github&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text&quot; transform=&quot;translate(733.1999999999999,426)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(80, 180, 86); stroke: rgb(13, 149, 44);&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(789.6,319.5)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;g class=&quot;node text indent&quot; transform=&quot;translate(733.1999999999999,213)&quot; style=&quot;opacity: 1; font-size: 11px; font-weight: bold;&quot;&gt;&lt;circle r=&quot;10&quot; style=&quot;stroke-width: 1.5px; fill: rgb(255, 204, 0); stroke: orange;&quot;&gt;&lt;/circle&gt;&lt;text text-anchor=&quot;middle&quot; dy=&quot;-15&quot;&gt;#text&lt;/text&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Snippet taken from &lt;a href=&quot;https://bioub.github.io/dom-visualizer/&quot;&gt;DOM Visualizer&lt;/a&gt; by @bioub&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These filled circles represent either a DOM element or a &lt;a href=&quot;https://javascript.info/dom-nodes&quot;&gt;DOM node&lt;/a&gt;. DOM can be accessed using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Using_the_Document_Object_Model#what_does_the_document_api_do&quot;&gt;&lt;code&gt;Document&lt;/code&gt;&lt;/a&gt; API which exposes a global &lt;code&gt;document&lt;/code&gt; object for you to manipulate the DOM using &lt;a href=&quot;https://syntackle.com/blog/how-to-make-a-qr-code-generator-using-javascript-5-rbxEeFYAidZ_zVp2Lh/&quot;&gt;JavaScript&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// test this in browser dev tools&#39; console&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// logs `object` &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;painting-of-dom&quot; tabindex=&quot;-1&quot;&gt;Painting of DOM&lt;/h2&gt;
&lt;p&gt;Whenever you update your HTML markup, the DOM gets updated and it needs to be repainted or re-rendered in order to reflect the changes on the screen.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// process of browser rendering&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;DOM&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; tree&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; CSSOM&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; tree&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; Render&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; tree&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; Prepare&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; Layout&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; Paint&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; Screen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These repaints can be &lt;a href=&quot;https://web.dev/critical-rendering-path-render-tree-construction/&quot;&gt;expensive&lt;/a&gt; and &lt;a href=&quot;https://css-tricks.com/browser-painting-and-considerations-for-web-performance/&quot;&gt;lead to performance issues&lt;/a&gt;. Repainting can happen more often if the user is interacting with the website because of the site being highly interactive.&lt;/p&gt;
&lt;h2 id=&quot;virtual-dom-%26-comparision-of-doms&quot; tabindex=&quot;-1&quot;&gt;Virtual DOM &amp;amp; Comparision of DOMs&lt;/h2&gt;
&lt;p&gt;In order to tackle the issue of expensive rendering, some frontend libraries such as &lt;a href=&quot;https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/&quot;&gt;React&lt;/a&gt;, create a virtual DOM which is similar to the actual DOM but it&#39;s efficient because it doesn&#39;t have to be painted.&lt;/p&gt;
&lt;p&gt;The virtual DOM is created on every state change or re-render in React and is then compared to the previously created virtual DOM. This process of comparing consecutive instances of virtual DOM is known as &lt;code&gt;DOM diffing&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the virtual DOM is different than the previous one, React will calculate which parts of the DOM have been modified and it will update only those parts in the actual DOM.&lt;/p&gt;
&lt;p&gt;If there&#39;s no change, the actual DOM will remain untouched. You can explore more about the &lt;a href=&quot;https://reactjs.org/docs/reconciliation.html#the-diffing-algorithm&quot;&gt;diffing algorithm&lt;/a&gt; in react by visiting their documentation.&lt;/p&gt;
&lt;p&gt;Want to implement DOM diffing in vanilla JS? &lt;a href=&quot;https://gomakethings.com/dom-diffing-with-vanilla-js/&quot;&gt;You can&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/what-is-dom-diffing-bB8Ltf/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Using Fontsource With 11ty</title>
    <link href="https://syntackle.com/blog/using-fontsource-with-11ty-FUzgft/"/>
    <published>2022-12-15T00:00:00Z</published>
    <updated>2023-12-08T10:48:36Z</updated>
    <id>https://syntackle.com/blog/using-fontsource-with-11ty-FUzgft/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Dealing with fonts can get quite overwhelming. For quite some time, I was searching for a way to self host &lt;a href=&quot;https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/&quot;&gt;google&lt;/a&gt; fonts because the google fonts API&#39;s network request increased the render blocking time more than I expected.&lt;/p&gt;
&lt;p&gt;I stumbled upon &lt;a href=&quot;https://fontsource.org/&quot;&gt;fontsource.org&lt;/a&gt; the other day and I found the idea of installing fonts from npm packages appealing.&lt;/p&gt;
&lt;p&gt;At first, I used it in my &lt;a href=&quot;https://murtuzaalisurti.com/&quot;&gt;personal site&lt;/a&gt; built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. The process was incredibly simple. You just have to &lt;a href=&quot;https://docs.astro.build/en/guides/fonts/#using-fontsource&quot;&gt;import fonts&lt;/a&gt; in your base layout file and that&#39;s it. You are ready to use it in your CSS!&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @fontsource/poppins&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @fontsource/nunito&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@fontsource/poppins&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@fontsource/nunito/400.css&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I thought what if I could use this in my &lt;a href=&quot;https://syntackle.com/&quot;&gt;11ty blog&lt;/a&gt; too. The next immediate thing which came to mind was to use vite because it can bundle those fonts for me just like Astro.&lt;/p&gt;
&lt;p&gt;So, I decided to use &lt;a href=&quot;https://slinkity.dev/&quot;&gt;slinkity&lt;/a&gt;. You can call slinkity as an extension for 11ty projects. It adds more features on the table by post processing your 11ty build output.&lt;/p&gt;
&lt;p&gt;Slinkity uses &lt;a href=&quot;https://vitejs.dev/&quot;&gt;vite&lt;/a&gt; for bundling which is great, but it became a problem for me. I have a relatively old and large project with some custom configurations which came in the way of how vite does things, so migrating to vite resulted in a mess. The migration needs more time. So, I decided to take another approach which might be not so good.&lt;/p&gt;
&lt;h2 id=&quot;using-rollup&quot; tabindex=&quot;-1&quot;&gt;Using Rollup &lt;a href=&quot;https://syntackle.com/blog/using-fontsource-with-11ty-FUzgft/#using-rollup&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://rollupjs.org/guide/en/&quot;&gt;Rollup&lt;/a&gt; is a javascript bundler you can use to bundle your modules.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; rollup&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I created a rollup config file, named &lt;code&gt;rollup.config.mjs&lt;/code&gt; at the root of the project.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/combine.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/minified/index.bundle.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            sourcemap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idea is to import the fonts just like I did in astro, in a javascript file and then extract &lt;a href=&quot;https://syntackle.com/blog/how-to-create-a-notification-badge-with-css-WrkjgwxkL5bw-mFwMFjl/&quot;&gt;css&lt;/a&gt; from it in order to copy it in the styles folder.&lt;/p&gt;
&lt;p&gt;So, inside the &lt;code&gt;combine.js&lt;/code&gt; file, I imported some fonts.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@fontsource/nunito&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@fontsource/poppins&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, to extract css, I used the &lt;a href=&quot;https://github.com/egoist/rollup-plugin-postcss&quot;&gt;postcss rollup plugin&lt;/a&gt; and the &lt;a href=&quot;https://github.com/vladshcherbin/rollup-plugin-copy&quot;&gt;rollup copy plugin&lt;/a&gt; to copy the generated css file to the desired directory. I had to use rollup-plugin-copy because of &lt;a href=&quot;https://github.com/egoist/rollup-plugin-postcss/issues/250&quot;&gt;this issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Installed the following dependencies:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; rollup-plugin-postcss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; rollup-plugin-copy&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; @rollup/plugin-node-resolve&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The postcss plugin will extract the styles from the javascript file into a new CSS file.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;nodeResolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@rollup/plugin-node-resolve&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; postcss&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;rollup-plugin-postcss&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/combine.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/minified/index.bundle.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            sourcemap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [ &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            nodeResolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            postcss&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                extract&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// no way to move output to another folder https://github.com/egoist/rollup-plugin-postcss/issues/250&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                minimize&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next step is to move the CSS file to the desired location because the extracted CSS file will be in the same directory as of the javascript file and you can&#39;t specify a location outside the parent folder due to a &lt;a href=&quot;https://github.com/egoist/rollup-plugin-postcss/issues/250&quot;&gt;bug in the postcss plugin&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;nodeResolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;@rollup/plugin-node-resolve&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; postcss&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;rollup-plugin-postcss&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; copy&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;rollup-plugin-copy&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/combine.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        output&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            file&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/minified/index.bundle.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            sourcemap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        plugins&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            nodeResolve&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            postcss&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                extract&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// no way to move output to another folder https://github.com/egoist/rollup-plugin-postcss/issues/250&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                minimize&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            copy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                targets&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        src&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/js/minified/index.bundle.css&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        dest&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src/styles/minified&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                        rename&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fonts.bundle.css&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;                ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                verbose&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                hook&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;writeBundle&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am running the copy plugin after all the bundles are written and that&#39;s why you see the &lt;code&gt;hook: &amp;quot;writeBundle&amp;quot;&lt;/code&gt; build hook specified for the copy plugin.&lt;/p&gt;
&lt;p&gt;Run rollup using this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npx&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; rollup&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --bundleConfigAsCjs&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the font CSS is ready to use, right? No. There is still one problem.&lt;/p&gt;
&lt;p&gt;This is how the generated CSS looks:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;@font-face&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{font-display:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;swap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;font-family:Nunito;font-style:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;normal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;font-weight:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;src:&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;files/nunito-cyrillic-ext-400-normal.woff2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;woff2&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;files/nunito-all-400-normal.woff&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;woff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);unicode-range:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+0460-052f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+1c80-1c88&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+20b4&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+2de0-2dff&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+a640-a69f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+fe2e-fe2f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;@font-face&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{font-display:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;swap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;font-family:Nunito;font-style:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;normal&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;font-weight:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;src:&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;files/nunito-cyrillic-400-normal.woff2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;woff2&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;files/nunito-all-400-normal.woff&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;woff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);unicode-range:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+0301&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+0400-045f&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+0490-0491&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+04b0-04b1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;u+2116&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you look closely at the src url, you will find that the files which the url is referring to are not present in our directory. Yes, the actual font files.&lt;/p&gt;
&lt;p&gt;I used &lt;code&gt;addPassthroughCopy()&lt;/code&gt; in 11ty to copy the required font files from node_modules to the output directory as per the url specified in the font stylesheet.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;  eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addPassthroughCopy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;./node_modules/@fontsource/poppins/files/*.woff2&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;styles/files&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy the required files to the output folder and the fonts are ready to be used.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;font-family&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;: &quot;Poppins&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; &quot;Nunito&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; sans-serif&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Is this a good solution? I don&#39;t know. For me it&#39;s more of a hack than a solution and I think there&#39;s a better way. Maybe, all we need is a 11ty plugin :)&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/using-fontsource-with-11ty-FUzgft/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Creating Git Hooks Using Husky</title>
    <link href="https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/"/>
    <published>2022-10-09T00:00:00Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/</id>
    <content xml:lang="en" type="html">&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;Hooks in git are nothing but some code which can be executed at specific points during git execution process.&lt;/p&gt;
&lt;p&gt;They are used to verify everything is as expected before or after executing a git command or action. Some common applications include formatting the code before committing, performing build step before pushing the code to production, etc.&lt;/p&gt;
&lt;p&gt;You can create &lt;a href=&quot;https://git-scm.com/docs/githooks&quot;&gt;hooks&lt;/a&gt; in the &lt;code&gt;.git/hooks&lt;/code&gt; directory but you can automate the process using &lt;a href=&quot;https://typicode.github.io/husky/#/&quot;&gt;husky&lt;/a&gt;!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This article has been updated in accordance with the latest version (v9) of husky.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;installing-husky&quot; tabindex=&quot;-1&quot;&gt;Installing Husky&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; husky&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;initializing-git-hooks&quot; tabindex=&quot;-1&quot;&gt;Initializing Git Hooks&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npx&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; husky&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will enable you to add git hooks to your project.&lt;/p&gt;
&lt;p&gt;One thing to note here is that when collaborating, contributors need to run this command after cloning the project to enable git hooks. But you can bypass this step by adding a &lt;code&gt;prepare&lt;/code&gt; script in your &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;It will run when you do &lt;code&gt;npm install&lt;/code&gt; in your project so you don&#39;t need to perform &lt;code&gt;npx husky init&lt;/code&gt; manually.&lt;/p&gt;
&lt;p&gt;To do so, add the following script to &lt;code&gt;package.json&lt;/code&gt;,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;prepare&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;husky&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But there&#39;s another catch. The &lt;code&gt;prepare&lt;/code&gt; script will also run in production but you need it in production as such, so there are many ways to disable it in production, one of them is by using the &lt;code&gt;is-ci&lt;/code&gt; npm package.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/watson/is-ci&quot;&gt;is-ci&lt;/a&gt; package will check if the code is executed in a continuous integration server or not.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; is-ci&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just change the prepare script to the following.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;prepare&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;is-ci || husky&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;adding-git-hooks&quot; tabindex=&quot;-1&quot;&gt;Adding Git Hooks&lt;/h2&gt;
&lt;p&gt;For example, if you want to format your code using a formatting tool before committing the code, you can add git hook to do that using the following command in unix based OS&#39; such as Mac or Linux:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;npm run format&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;.husky/pre-commit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, you can directly create a &lt;code&gt;pre-commit&lt;/code&gt; file in &lt;code&gt;.husky&lt;/code&gt; folder and add the command in it manually.&lt;/p&gt;
&lt;p&gt;Replace &lt;code&gt;npm run format&lt;/code&gt; with the command which will format your code.&lt;/p&gt;
&lt;p&gt;You can replace &lt;code&gt;pre-commit&lt;/code&gt; with some other hook such as &lt;code&gt;pre-push&lt;/code&gt;, &lt;code&gt;post-commit&lt;/code&gt;, &lt;code&gt;post-checkout&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;Another example could be, if you want to &lt;a href=&quot;https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/&quot;&gt;minify javascript&lt;/a&gt; before pushing to production, you can use &lt;code&gt;pre-push&lt;/code&gt; git hook.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;npm run minjs&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; &gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;.husky/pre-push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;minjs&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;terser js/app.js --compress --mangle --output js/app.min.js&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find the list of various &lt;a href=&quot;https://git-scm.com/docs/githooks&quot;&gt;git hooks&lt;/a&gt; on the official &lt;a href=&quot;https://git-scm.com/docs/githooks&quot;&gt;git site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will see a &lt;code&gt;.husky&lt;/code&gt; folder being created in your project and inside it there will be files for all the git hooks which you created.&lt;/p&gt;
&lt;p&gt;Make sure to run &lt;code&gt;git add&lt;/code&gt; after you make any changes. Finally, run the git command or action and your git hooks will be executed.&lt;/p&gt;
&lt;p&gt;That&#39;s it. For more applications of git hooks, &lt;a href=&quot;https://www.atlassian.com/git/tutorials/git-hooks&quot;&gt;read this article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Setting Background Color of Body Dynamically in React</title>
    <link href="https://syntackle.com/blog/setting-background-color-of-body-dynamically-in-react-5tVYr3/"/>
    <published>2022-09-03T00:00:00Z</published>
    <updated>2025-03-14T09:07:26Z</updated>
    <id>https://syntackle.com/blog/setting-background-color-of-body-dynamically-in-react-5tVYr3/</id>
    <content xml:lang="en" type="html">&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;In a single page application, you only have one &lt;code&gt;body&lt;/code&gt; element and although you can specify the background color of &lt;code&gt;body&lt;/code&gt; in a global stylesheet, it&#39;s not easy to update the background color dynamically for different pages in your website.&lt;/p&gt;
&lt;p&gt;I encountered this issue and immediately googled &lt;a href=&quot;https://styled-components.com/docs/api#deprecated-injectglobal&quot;&gt;some solutions&lt;/a&gt; but I wasn&#39;t satisfied with them.&lt;/p&gt;
&lt;p&gt;So, I went on to code a hacky but working patch using &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/&quot;&gt;CSS&lt;/a&gt; custom properties. I don&#39;t know if it&#39;s a recommended practice or not, but let&#39;s have a look at it.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Want to master React and get a deep understanding of it&#39;s fundamentals? This &lt;a href=&quot;https://www.amazon.in/Road-Learn-React-Pragmatic-React-Js/dp/172004399X?crid=21RSEEI4UHFQM&amp;amp;dib=eyJ2IjoiMSJ9.WtrXHJ8LPAlHDVF-askoJkDJSzCU0Fy6FzMT6Y9Zg5RBzB3hImavfzKhdF70oLSnpR8hPKiMC5MgBHHrfcAtrlNmRm3lcZjpcEbtv7V8pMcz6bNT3gte9K1tHB9Ry_70yaix6PFx7__bZCkyM9fQiX4rxQD-k-urNGtcIDZPXxtqDONFPZEumoRGbKX25knL._5_4gELCOvAN6YSYihVUEo0k78QekOI6OkgaGK_7ibE&amp;amp;dib_tag=se&amp;amp;keywords=road+to+react&amp;amp;qid=1736063926&amp;amp;sprefix=road+to+react%2Caps%2C234&amp;amp;sr=8-2&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=54a43f468930df582f553167693f7f9b&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;book by Robin Wieruch&lt;/a&gt; is a must read.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;css-custom-property&quot; tabindex=&quot;-1&quot;&gt;CSS Custom Property&lt;/h2&gt;
&lt;p&gt;Set a custom property in your &lt;code&gt;:root&lt;/code&gt; or &lt;code&gt;html&lt;/code&gt; element style which contains a default color value. Specify this styling in a global stylesheet, in your case it will probably be &lt;code&gt;index.css&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:root&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    --bodyColor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#000000&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;--bodyColor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;function-to-set-body-color&quot; tabindex=&quot;-1&quot;&gt;Function To Set Body Color&lt;/h2&gt;
&lt;p&gt;Create a file named &lt;code&gt;setBodyColor.js&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory which contains a function ready to be exported. The function is shown below:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; setBodyColor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;documentElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;--bodyColor&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this way, you can modify the value of the css custom property &lt;code&gt;--bodyColor&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-the-function&quot; tabindex=&quot;-1&quot;&gt;Using the function&lt;/h2&gt;
&lt;p&gt;Import the function in a component using,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; setBodyColor&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;./setBodyColor&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the relative url &lt;code&gt;./setBodyColor&lt;/code&gt; as per your folder structure.&lt;/p&gt;
&lt;p&gt;Use it in your functional component,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; HomePage&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    setBodyColor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#ffffff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; }) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; HomePage&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use this function in multiple components and pass a color to modify the background color of the body.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M12 16h.01&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M12 8v4&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; CAUTION&lt;/p&gt;
&lt;p&gt;Note that you must call the &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;function&lt;/a&gt; on every page or component to set the background color of the body. Otherwise, it will just take the value of the background color of the previous page.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This workaround isn&#39;t limited to &lt;code&gt;background-color&lt;/code&gt; property. You can set as many custom properties as you want. But, as I said earlier, I don&#39;t know if this is a foolproof technique, so the best thing you can do for your case is do your own research.&lt;/p&gt;
&lt;p&gt;Also, if you have any better solution, feel free to ping me on &lt;a href=&quot;https://x.com/murtuza_surti&quot;&gt;X (formerly Twitter)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/setting-background-color-of-body-dynamically-in-react-5tVYr3/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Minify JavaScript Using Terser</title>
    <link href="https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/"/>
    <published>2022-08-08T00:00:00Z</published>
    <updated>2023-12-17T10:50:32Z</updated>
    <id>https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Terser is a javascript compressor and mangler supporting ES6+ specification. In this tutorial, you will get to know how to use terser to minify or compress javascript.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;: &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;&lt;em&gt;nodejs&lt;/em&gt;&lt;/a&gt; should be installed on your system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1.-installing-terser&quot; tabindex=&quot;-1&quot;&gt;1. Installing terser&lt;/h2&gt;
&lt;p&gt;Install &lt;a href=&quot;https://terser.org/&quot;&gt;terser&lt;/a&gt; using &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; terser&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -g&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;2.-creating-a-script&quot; tabindex=&quot;-1&quot;&gt;2. Creating a script&lt;/h2&gt;
&lt;p&gt;Add the script to &lt;code&gt;package.json&lt;/code&gt; file of your project.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFFFFF&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;minify&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;terser src/js/app.js -c -m --output src/minified/app.min.js&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFFFFF&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;src/js/app.js&lt;/code&gt; and &lt;code&gt;src/minified/app.min.js&lt;/code&gt; with your input and output file path respectively.&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;-c&lt;/code&gt; flag stands for &lt;code&gt;--compress&lt;/code&gt; and &lt;code&gt;-m&lt;/code&gt; stands for &lt;code&gt;--mangle&lt;/code&gt;. For more options, visit the &lt;a href=&quot;https://terser.org/docs/cli-usage&quot;&gt;official documentation&lt;/a&gt; of terser.&lt;/p&gt;
&lt;h2 id=&quot;3.-executing-the-script&quot; tabindex=&quot;-1&quot;&gt;3. Executing the script&lt;/h2&gt;
&lt;p&gt;Run the script using this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; minify&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your javascript file should now be compressed!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Apart from &lt;code&gt;terser&lt;/code&gt;, you can also use &lt;a href=&quot;https://github.com/mishoo/UglifyJS&quot;&gt;&lt;code&gt;uglify-js&lt;/code&gt;&lt;/a&gt; to compress or minify javascript.&lt;/p&gt;
&lt;p&gt;You can also &lt;a href=&quot;https://try.terser.org/&quot;&gt;try terser&lt;/a&gt; on the web.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Deploying React App to Netlify</title>
    <link href="https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/"/>
    <published>2022-07-25T00:00:00Z</published>
    <updated>2025-01-05T08:09:15Z</updated>
    <id>https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/</id>
    <content xml:lang="en" type="html">&lt;p&gt;A &lt;a href=&quot;https://reactjs.org/docs/create-a-new-react-app.html&quot;&gt;react app&lt;/a&gt; is a single page application which means that there&#39;s only one document i.e. &lt;code&gt;index.html&lt;/code&gt; file which is updated using javascript as per the requirement of the user.&lt;/p&gt;
&lt;p&gt;Let&#39;s see you how you can deploy a &lt;a href=&quot;https://syntackle.com/blog/setting-background-color-of-body-dynamically-in-react-5tVYr3/&quot;&gt;react&lt;/a&gt; app on &lt;a href=&quot;https://www.netlify.com/&quot;&gt;netlify&lt;/a&gt; from an existing &lt;code&gt;git&lt;/code&gt; repository of yours.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Want to master React and get a deep understanding of it&#39;s fundamentals? This &lt;a href=&quot;https://www.amazon.in/Road-Learn-React-Pragmatic-React-Js/dp/172004399X?crid=21RSEEI4UHFQM&amp;amp;dib=eyJ2IjoiMSJ9.WtrXHJ8LPAlHDVF-askoJkDJSzCU0Fy6FzMT6Y9Zg5RBzB3hImavfzKhdF70oLSnpR8hPKiMC5MgBHHrfcAtrlNmRm3lcZjpcEbtv7V8pMcz6bNT3gte9K1tHB9Ry_70yaix6PFx7__bZCkyM9fQiX4rxQD-k-urNGtcIDZPXxtqDONFPZEumoRGbKX25knL._5_4gELCOvAN6YSYihVUEo0k78QekOI6OkgaGK_7ibE&amp;amp;dib_tag=se&amp;amp;keywords=road+to+react&amp;amp;qid=1736063926&amp;amp;sprefix=road+to+react%2Caps%2C234&amp;amp;sr=8-2&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=54a43f468930df582f553167693f7f9b&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;book by Robin Wieruch&lt;/a&gt; is a must read.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;tutorial&quot; tabindex=&quot;-1&quot;&gt;Tutorial &lt;a href=&quot;https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/#tutorial&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Create a &lt;a href=&quot;https://docs.netlify.com/configure-builds/file-based-configuration/#sample-netlify-toml-file&quot;&gt;&lt;code&gt;netlify.toml&lt;/code&gt;&lt;/a&gt; file at the root of your react application and add the following rule to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[[&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;redirects&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  from&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/*&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  to&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/index.html&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  status&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;200&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The above rule is applicable if you have multiple routes and have used libraries like &lt;code&gt;react-router&lt;/code&gt; in your project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What we are doing here is that we are telling netlify to redirect all the routes to our &lt;code&gt;index.html&lt;/code&gt; file with a status code of 200 because our application is built with react and it is a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/SPA&quot;&gt;single page application&lt;/a&gt;. We already discussed what an SPA is at the very beginning of this tutorial.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;recommended-%E2%9C%A8&quot; tabindex=&quot;-1&quot;&gt;Recommended ✨&lt;/h3&gt;
&lt;ul data-pagefind-ignore=&quot;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/&quot;&gt;Builder.io&#39;s Partytown with 11ty&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set up an &lt;a href=&quot;https://app.netlify.com/&quot;&gt;account on netlify&lt;/a&gt; if you haven&#39;t already.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to the &lt;code&gt;sites&lt;/code&gt; tab and add a new site.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &lt;code&gt;import an existing project&lt;/code&gt; from the dropdown menu.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You will see a number of providers from which you can import your project.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/5f7byCG.jpg&quot; alt=&quot;importing a project&quot; height=&quot;896&quot; width=&quot;1744&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Importing an existing project&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Authenticate and select a repository.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify the default deployment configuration as per your requirement.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/heodEQG.jpg&quot; alt=&quot;deployment configuration&quot; height=&quot;709&quot; width=&quot;1110&quot; /&gt;&lt;/picture&gt;&lt;figcaption&gt;&lt;p&gt;Deployment Config&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If required, you can also add &lt;code&gt;env&lt;/code&gt; variables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, click on &lt;code&gt;deploy site&lt;/code&gt; and your site should be deployed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Here&#39;s a blog post on how you can &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/&quot;&gt;deploy an express app to vercel&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/deploying-react-app-to-netlify-XZ_dWXAd/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Adding Custom Anchors to Headings in Markdown - Eleventy</title>
    <link href="https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/"/>
    <published>2022-07-10T00:00:00Z</published>
    <updated>2025-12-28T07:58:06Z</updated>
    <id>https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Anchors are nothing but &lt;code&gt;id&lt;/code&gt; attributes applied to an element to link to it using &lt;code&gt;href&lt;/code&gt; attribute internally on the same page.&lt;/p&gt;
&lt;p&gt;By default, &lt;a href=&quot;https://11ty.dev/&quot;&gt;11ty&lt;/a&gt; uses &lt;a href=&quot;https://www.npmjs.com/package/markdown-it&quot;&gt;markdown-it&lt;/a&gt; library to parse markdown. But, it seems that by default, &lt;code&gt;markdown-it&lt;/code&gt; doesn&#39;t support syntax for applying an &lt;code&gt;id&lt;/code&gt; to a header element.&lt;/p&gt;
&lt;p&gt;The syntax for applying a custom &lt;code&gt;id&lt;/code&gt; to a header element in &lt;code&gt;markdown&lt;/code&gt; is as follows:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;## text {#id}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make that syntax work, you need to create your own instance of &lt;code&gt;markdown-it&lt;/code&gt; library and add two plugins, &lt;code&gt;markdown-it-anchor&lt;/code&gt; and &lt;code&gt;markdown-it-attrs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.npmjs.com/package/markdown-it-anchor&quot;&gt;&lt;code&gt;markdown-it-anchor&lt;/code&gt;&lt;/a&gt; plugin will apply a default &lt;code&gt;id&lt;/code&gt; depending on the heading text automatically to every header element in our markup.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.npmjs.com/package/markdown-it-attrs&quot;&gt;&lt;code&gt;markdown-it-attrs&lt;/code&gt;&lt;/a&gt; plugin will replace the default &lt;code&gt;id&lt;/code&gt; with the custom &lt;code&gt;id&lt;/code&gt; you specify.&lt;/p&gt;
&lt;h2 id=&quot;custom-anchors&quot; tabindex=&quot;-1&quot;&gt;Applying Custom Anchors &lt;a href=&quot;https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/#custom-anchors&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Install the required dependencies:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; markdown-it&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; markdown-it-anchor&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; markdown-it-attrs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Require them inside &lt;code&gt;.eleventy.js&lt;/code&gt; file,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; markdownIt&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;markdown-it&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; markdownItAnchor&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;markdown-it-anchor&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; markdownItAttrs&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;markdown-it-attrs&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an instance of the &lt;code&gt;markdown-it&lt;/code&gt; library inside the &lt;code&gt;module.exports&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setLibrary&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;md&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;markdownIt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAnchor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAttrs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also add some options such as:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; markdownItOptions&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    html&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // you can include HTML tags&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; markdownItAnchorOptions&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    level&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // minimum level header -- anchors will only be applied to h2 level headers and below but not h1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setLibrary&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;md&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;markdownIt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAnchor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAnchorOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAttrs&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if you do something like:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;## Heading 1 {#head1}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, &lt;code&gt;head1&lt;/code&gt; will be the &lt;code&gt;id&lt;/code&gt; of this header element. You can link to this element by using &lt;code&gt;#head1&lt;/code&gt; as the &lt;code&gt;href&lt;/code&gt; value. That&#39;s how you can add custom anchors to heading elements.&lt;/p&gt;
&lt;h2 id=&quot;default-anchors&quot; tabindex=&quot;-1&quot;&gt;Applying Default Anchors &lt;a href=&quot;https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/#default-anchors&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you don&#39;t want a custom &lt;code&gt;id&lt;/code&gt; and just want to keep the default &lt;code&gt;id&lt;/code&gt; that&#39;s being applied to the element by the &lt;code&gt;markdown-it-anchor&lt;/code&gt; plugin, then remove the &lt;code&gt;markdown-it-attrs&lt;/code&gt; plugin and you will get a default anchor applied to the element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setLibrary&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;md&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;markdownIt&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAnchor&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;markdownItAnchorOptions&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all for now. Signing Off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/adding-custom-anchors-to-headings-in-markdown-eleventy-3NxBhIJO2OIr4XOj5LKc/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to vendor prefix and minify CSS?</title>
    <link href="https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/"/>
    <published>2022-06-30T00:00:00Z</published>
    <updated>2023-12-17T10:57:20Z</updated>
    <id>https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Writing CSS from scratch along with adding vendor prefixes can be a daunting task if done manually. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix&quot;&gt;Vendor prefixes&lt;/a&gt; can be easily added using the &lt;code&gt;autoprefixer&lt;/code&gt; plugin of PostCSS.&lt;/p&gt;
&lt;p&gt;Also, the size of CSS file matters because CSS files can be &lt;a href=&quot;https://web.dev/critical-rendering-path-render-blocking-css/&quot;&gt;render blocking&lt;/a&gt; so you need to keep a check on the size of the CSS file. This is where &lt;code&gt;cssnano&lt;/code&gt; comes handy.&lt;/p&gt;
&lt;p&gt;In this tutorial, you will be able to configure and set up PostCSS, autoprefixer and cssnano to vendor prefix and minify your CSS respectively.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot; tabindex=&quot;-1&quot;&gt;Prerequisites &lt;a href=&quot;https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/#prerequisites&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;a href=&quot;https://nodejs.org/&quot;&gt;nodejs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;installing-postcss&quot; tabindex=&quot;-1&quot;&gt;Installing PostCSS &lt;a href=&quot;https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/#installing-postcss&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It is a tool to modify and transform your CSS. There are so many plugins for &lt;a href=&quot;https://github.com/postcss/postcss&quot;&gt;PostCSS&lt;/a&gt; to perform all kinds of tasks ranging from compressing CSS to using new CSS features right off the bat.&lt;/p&gt;
&lt;p&gt;We will be using several postcss plugins to add vendor prefixes and minify CSS. But first, we need to install &lt;a href=&quot;https://github.com/postcss/postcss-cli&quot;&gt;postcss-cli&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -g&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postcss-cli&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The postcss package can be installed from &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postcss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; postcss-cli&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;auto-prefixing-css&quot; tabindex=&quot;-1&quot;&gt;Auto-prefixing CSS &lt;a href=&quot;https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/#auto-prefixing-css&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/postcss/autoprefixer&quot;&gt;autoprefixer&lt;/a&gt; plugin uses &lt;a href=&quot;https://caniuse.com/&quot;&gt;caniuse.com&lt;/a&gt; to search for browser support and accordingly add vendor prefixes to CSS properties. You can install autoprefixer from npm.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; autoprefixer&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you can autoprefix your CSS file using this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;postcss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles/&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;.css&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -u&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; autoprefixer&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --dir&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/prefixed&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --no-map&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above command will parse each and every &lt;code&gt;.css&lt;/code&gt; file inside the &lt;code&gt;styles&lt;/code&gt; directory and use &lt;code&gt;-u&lt;/code&gt; autoprefixer to auto-prefix files and output them in the &lt;code&gt;prefixed&lt;/code&gt; directory. The &lt;code&gt;--no-map&lt;/code&gt; argument is optional. If you want a source map to be generated, then remove the &lt;code&gt;--no-map&lt;/code&gt; argument.&lt;/p&gt;
&lt;p&gt;CSS file before prefixing:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    box-sizing: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;border-box&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-size-adjust: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After prefixing:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    box-sizing: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;border-box&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;    -webkit-text-size-adjust&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;       -moz-text-size-adjust&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            text-size-adjust: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;minifying-css&quot; tabindex=&quot;-1&quot;&gt;Minifying CSS &lt;a href=&quot;https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/#minifying-css&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://cssnano.co/&quot;&gt;cssnano&lt;/a&gt; plugin can minify/compress CSS and make it suitable for production use.
Install cssnano plugin using this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; cssnano&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --save-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Minify your already vendor-prefixed CSS file using this command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;postcss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/prefixed/&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;.css&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -u&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; cssnano&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --dir&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/minified&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --no-map&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will minify all the files present in the &lt;code&gt;prefixed&lt;/code&gt; directory and output them to the &lt;code&gt;minified&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;The final result you get is:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-webkit-text-size-adjust&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;-moz-text-size-adjust&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;text-size-adjust:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;box-sizing:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;border-box&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;margin:&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;recommended-%E2%9C%A8&quot; tabindex=&quot;-1&quot;&gt;Recommended ✨&lt;/h3&gt;
&lt;ul data-pagefind-ignore=&quot;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/&quot;&gt;Minify Javascript Using Terser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;bonus&quot; tabindex=&quot;-1&quot;&gt;Bonus&lt;/h2&gt;
&lt;p&gt;You can auto-prefix as well as minify CSS using one single command:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;postcss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles/&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;.css&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; -u&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; autoprefixer&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; cssnano&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --dir&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles/production&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --no-map&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Vendor-prefixing and minifying are some of the important boxes you need to check in order to make your CSS production ready. Using PostCSS, you can do so much with your CSS. There are a variety of awesome &lt;a href=&quot;https://github.com/postcss/postcss#plugins&quot;&gt;plugins&lt;/a&gt; available to use in postcss.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-vendor-prefix-and-minify-css-XfWdM2Vxl7G9LZAGkRwG/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Eleventy - Shortcode for Embedding Codepen</title>
    <link href="https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/"/>
    <published>2022-06-07T00:00:00Z</published>
    <updated>2023-12-08T10:45:36Z</updated>
    <id>https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/</id>
    <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;Don&#39;t know what eleventy is? Before you read further, check out this amazing &lt;a href=&quot;https://www.tatianamac.com/posts/beginner-eleventy-tutorial-parti/&quot;&gt;series of articles&lt;/a&gt;  by &lt;a href=&quot;https://www.twitter.com/TatianaTMac&quot;&gt;Tatiana Mac&lt;/a&gt; to know more about &lt;a href=&quot;https://11ty.dev/&quot;&gt;eleventy&lt;/a&gt; and static site generators in general.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Shortcodes are used to &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;invoke a particular function&lt;/a&gt; which returns some html or any other data based on the information that is passed. They are mainly used to reuse html templates which require some preprocessing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TLDR - &lt;a href=&quot;https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/#tutorial&quot;&gt;&lt;em&gt;Jump to tutorial&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While writing blogs, I came across the need to embed codepens in my articles for a quick code demo. Initially, I used to copy and paste the embed code provided by the codepen website. That&#39;s not at all feasible.&lt;/p&gt;
&lt;p&gt;It wasn&#39;t the case that I didn&#39;t knew about shortcodes at all because I used them on DEV, but I wasn&#39;t sure if something like that existed in &lt;a href=&quot;https://syntackle.com/blog/builder-io-s-partytown-with-11ty-lN6X2w/&quot;&gt;eleventy&lt;/a&gt; too. So, I buckled up and went on to explore shortcodes in eleventy!&lt;/p&gt;
&lt;h2 id=&quot;tutorial&quot; tabindex=&quot;-1&quot;&gt;Tutorial &lt;a href=&quot;https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/#tutorial&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As per 11ty&#39;s &lt;a href=&quot;https://www.11ty.dev/docs/&quot;&gt;official documentation&lt;/a&gt;, the default templating engine for markdown files is &lt;code&gt;liquid&lt;/code&gt;, so here I have used a &lt;code&gt;liquid&lt;/code&gt; shortcode as an example. You can &lt;a href=&quot;https://www.11ty.dev/docs/shortcodes/&quot;&gt;create a shortcode for other templating engines&lt;/a&gt; also.&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;.eleventy.js&lt;/code&gt; file, write the following code in &lt;code&gt;module.exports&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addLiquidShortcode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;codepen&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url_array&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; profile_url_array&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; username&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; profile_url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;profile_url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; user_profile&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; profile_url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; data_slug_hash&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url_array&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `&amp;#x3C;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;data_slug_hash&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; data-user=&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot; style=&quot;height: 571px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&amp;#x3C;span&gt;&amp;#x3C;a href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&gt;See the pen&amp;#x3C;/a&gt; (&amp;#x3C;a href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;user_profile&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&quot;https://codepen.io&quot;&gt;CodePen&amp;#x3C;/a&gt;.&amp;#x3C;/span&gt;&amp;#x3C;/p&gt;&amp;#x3C;script async src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&amp;#x3C;/script&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The shortcode 👇&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{% &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;codepen&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;url&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Place the above &lt;code&gt;shortcode&lt;/code&gt; where you want your codepen to be embedded. Pass a codepen &lt;code&gt;url&lt;/code&gt; to the shortcode function. Split the &lt;code&gt;url&lt;/code&gt; using &lt;code&gt;/&lt;/code&gt; as a separator.&lt;/p&gt;
&lt;p&gt;You will get an array from which you can filter out the slug after the &lt;code&gt;profile&lt;/code&gt; url. Convert the filtered array into a string using &lt;code&gt;join(&amp;quot;&amp;quot;)&lt;/code&gt;. What you get is the &lt;code&gt;profile url&lt;/code&gt; of a codepen user.&lt;/p&gt;
&lt;p&gt;Similarly, you can extract the &lt;code&gt;username&lt;/code&gt; as well as the &lt;code&gt;codepen id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Copy the &lt;code&gt;embed&lt;/code&gt; code from &lt;a href=&quot;https://blog.codepen.io/documentation/embedded-pens/&quot;&gt;codepen&lt;/a&gt; and edit it to make it dynamic. The function returns the &lt;code&gt;embed&lt;/code&gt; code and it is embedded inside your &lt;code&gt;html&lt;/code&gt; template.&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/eleventy-shortcode-for-embedding-codepen-ZyslIPzCHpJo3kkPwu2U/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>5 Most Useful Visual Studio Code Extensions</title>
    <link href="https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/"/>
    <published>2022-05-27T00:00:00Z</published>
    <updated>2025-12-28T07:58:06Z</updated>
    <id>https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Here are the five most useful Visual Studio Code extensions to improve your workflow as well as developer productivity!&lt;/p&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;h2 id=&quot;error-lens&quot; tabindex=&quot;-1&quot;&gt;1. Error Lens &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/#error-lens&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens&quot;&gt;Error Lens&lt;/a&gt; is an extension which allows you to see error, warning and diagnostic messages in line with your code without having to hover or click on anything! It also highlights the line with different colors to help you better visualize and differentiate between errors, warnings and other messages!&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcsqe8glunjdoku947eo.jpg&quot; alt=&quot;errorlens_demo&quot; height=&quot;212&quot; width=&quot;839&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;css-peek&quot; tabindex=&quot;-1&quot;&gt;2. CSS Peek &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/#css-peek&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With this &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek&quot;&gt;extension&lt;/a&gt;, you can search for relevant CSS files by using CSS classes in html file and edit &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/&quot;&gt;CSS&lt;/a&gt; files there itself! Here&#39;s how it works:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koc0rmfuygcnmk5g97p4.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;CSS Peek working&quot; height=&quot;1080&quot; width=&quot;1918&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Are you a beginner trying to get a gist of CSS and HTML? I personally started my web dev journey with this &lt;a href=&quot;https://www.amazon.in/HTML-CSS-Design-Build-Websites/dp/1118008189?pd_rd_w=xLzKo&amp;amp;content-id=amzn1.sym.d4089320-ab32-4dd6-a621-3f0516aefb4d&amp;amp;pf_rd_p=d4089320-ab32-4dd6-a621-3f0516aefb4d&amp;amp;pf_rd_r=29GWKXWFQ06KMMW5710H&amp;amp;pd_rd_wg=pE2OG&amp;amp;pd_rd_r=7e3eebe2-7091-4f8e-9124-504fba47ba54&amp;amp;pd_rd_i=1118008189&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=2d222709d7e366a74821ee8cf722ea79&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;book by John Duckett&lt;/a&gt; and it is one of the best books which will help you explore the world of CSS and HTML.&lt;/p&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;git-lens&quot; tabindex=&quot;-1&quot;&gt;3. GitLens &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/#git-lens&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens&quot;&gt;GitLens&lt;/a&gt; is a powerful extension which can display when a particular line was committed, who committed it and in which pull request it was included along with the &lt;a href=&quot;https://syntackle.com/blog/creating-git-hooks-using-husky-y6LKpN/&quot;&gt;git&lt;/a&gt; commit message! All of this information is inline with the line upon which your cursor is currently located.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.in/Pro-Git-Scott-Chacon-ebook/dp/B01ISNIKES?crid=1PHAAXUFTB5ON&amp;amp;dib=eyJ2IjoiMSJ9.URWGbI4GCTU8W1afvgWnh4HY2IMtAJ5Gqbje0aOJXqJSm42K5GoRUaeASMxlw8K7inXxT4og3qxIuT4rUP0w0QtyN6294YPjOZ7ACjlerz89YWAqTTJqplX_gHq182YO6asdDTR9_kVmhCrBeqKe20kwmBPtCrP3KwCCUOR2N10uaCjRJ91GJnldJwta6X0CISQgWdaJD2VbImPy79cb_5xmNWyGiXgTTH3l7idaXqs.4EloNNVh1b5R3AugzOK8rpIfgy-eNG1reyMxyHll08A&amp;amp;dib_tag=se&amp;amp;keywords=git+book&amp;amp;qid=1736065945&amp;amp;sprefix=git+book%2Caps%2C234&amp;amp;sr=8-4&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=e1121acd785d6e20b2924e6e562f8b8a&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;Pro Git&lt;/a&gt; is a great book for developing a solid understanding of Git and perhaps mastering it. And it&#39;s free.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You can also hover over the message to get even more information about a particular line of code!&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t3wnw8ktjwqc5kbmnugs.jpg&quot; alt=&quot;gitlens inline message&quot; height=&quot;274&quot; width=&quot;971&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fr0q3fk1fpzi9h5ez2s.jpg&quot; alt=&quot;gitlens hover&quot; height=&quot;510&quot; width=&quot;857&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;There are many more features in GitLens which you can explore and play around with!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;import-cost&quot; tabindex=&quot;-1&quot;&gt;4. Import Cost &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/#import-cost&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost&quot;&gt;Import Cost&lt;/a&gt; allows us to see the size of the imported package inline in the editor itself!&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn2wrul3oykol7nf7fcw.jpg&quot; alt=&quot;import cost&quot; height=&quot;114&quot; width=&quot;1101&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;version-lens&quot; tabindex=&quot;-1&quot;&gt;5. Version Lens &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/#version-lens&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=pflannery.vscode-versionlens&quot;&gt;Version Lens&lt;/a&gt; fetches information about dependency versions and displays it on top of the package!&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rr00wz0j8fm0j0wyfqco.jpg&quot; alt=&quot;Version Lens&quot; height=&quot;435&quot; width=&quot;426&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;p&gt;These were the 5 VSCode extensions which are powerful, useful and can improve your productivity and workflow!&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/murtuza_surti&quot;&gt;Twitter&lt;/a&gt; | &lt;a href=&quot;https://github.com/murtuzaalisurti&quot;&gt;GitHub&lt;/a&gt; | &lt;a href=&quot;https://linkedin.com/in/murtuzaali-surti&quot;&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/5-vscode-extensions-you-must-use-961&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Deploy an Express.js App to Vercel — A Step By Step Guide</title>
    <link href="https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/"/>
    <published>2022-05-22T15:25:37Z</published>
    <updated>2025-05-19T15:25:37Z</updated>
    <id>https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Vercel is a platform to host frontend applications and static sites but you can also host an Express application using serverless &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;functions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also use &lt;a href=&quot;https://vercel.com/docs/storage/vercel-postgres#how-vercel-postgres-works&quot;&gt;Vercel Postgres&lt;/a&gt; which allows you to integrate hosted serverless PostgreSQL database such as &lt;a href=&quot;https://neon.tech/&quot;&gt;neon.tech&lt;/a&gt; (Neon got acquired by Databricks) accessible by serverless functions.&lt;/p&gt;
&lt;p&gt;In this tutorial, I will show you how to create an &lt;a href=&quot;https://expressjs.com/&quot;&gt;Express&lt;/a&gt; app from scratch and deploy it to &lt;a href=&quot;https://vercel.com/&quot;&gt;vercel&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This article has been updated with latest vercel configurations.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;prerequisites&quot; tabindex=&quot;-1&quot;&gt;Prerequisites &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/#prerequisites&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt; should be installed on your system. To check if it is, run &lt;code&gt;node -v&lt;/code&gt; in your terminal and you should get a node version as an output.&lt;/p&gt;
&lt;h2 id=&quot;creating-express-app&quot; tabindex=&quot;-1&quot;&gt;Creating an Express App &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/#creating-express-app&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Run &lt;code&gt;npm init -y&lt;/code&gt; to create a &lt;code&gt;package.json&lt;/code&gt; file with default configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run &lt;code&gt;git init&lt;/code&gt; to initialize a &lt;code&gt;git&lt;/code&gt; repository.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;.gitignore&lt;/code&gt; file and write the folder name &lt;code&gt;node_modules&lt;/code&gt; in it. You can add as many files and folders you prefer to be ignored by &lt;code&gt;git&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the express package using npm or &lt;a href=&quot;https://yarnpkg.com/&quot;&gt;yarn&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; express&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create an &lt;code&gt;api&lt;/code&gt; folder (in the root folder) and add &lt;code&gt;index.js&lt;/code&gt; file in it. Adding an &amp;quot;api&amp;quot; folder is necessary because Vercel treats all index.js files in that folder as serverless functions. So, for example, if you create &lt;code&gt;api/test/index.js&lt;/code&gt;, when you hit &lt;code&gt;&amp;lt;BASE_URL&amp;gt;/test&lt;/code&gt; it will execute the code inside api/test/index.js as a serverless function. It is crucial for deploying the express app to Vercel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update &lt;code&gt;package.json&lt;/code&gt; file to explicitly set the entry file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;main&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;api/index.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;test&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;echo &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Error: no test specified&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &amp;#x26;&amp;#x26; exit 1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;keywords&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;author&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;license&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;ISC&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;dependencies&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;express&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;^4.21.2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Inside the &lt;code&gt;api/index.js&lt;/code&gt; file, add the following code in order to create an express app.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// cjs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;express&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 3000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Now, add a &lt;code&gt;GET&lt;/code&gt; request handler and send a response.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// api/index.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;/&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    res&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Express App Responded&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Export the &lt;code&gt;app&lt;/code&gt; for it to be run as a &lt;a href=&quot;https://vercel.com/docs/concepts/functions/serverless-functions&quot;&gt;serverless&lt;/a&gt; function.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// api/index.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Add a &lt;code&gt;start&lt;/code&gt; script to &lt;code&gt;package.json&lt;/code&gt; file in order to run the application locally.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;main&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;api/index.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;scripts&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;script&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;node api/index.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;test&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;echo &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;Error: no test specified&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;&#92;&quot;&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &amp;#x26;&amp;#x26; exit 1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;keywords&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;author&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;license&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;ISC&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;dependencies&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    &quot;express&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;^4.21.2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Run the application using the command &lt;code&gt;npm start&lt;/code&gt; The application should be live at &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;recommended-%E2%9C%A8&quot; tabindex=&quot;-1&quot;&gt;Recommended ✨&lt;/h3&gt;
&lt;ul data-pagefind-ignore=&quot;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://syntackle.com/blog/sharing-localhost-in-vscode-port-forwarding-Kew9D/&quot;&gt;Sharing Localhost From VS Code - Port Forwarding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;You should get an output similar to the following:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/zqT1Mgt.jpg&quot; alt=&quot;output&quot; height=&quot;957&quot; width=&quot;1918&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Yayy! You just created an Express.js Application. 🎉&lt;/p&gt;
&lt;h2 id=&quot;deploy-to-vercel&quot; tabindex=&quot;-1&quot;&gt;Deploying to Vercel &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/#deploy-to-vercel&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;vercel.json&lt;/code&gt; file in the root folder of your application. This is a &lt;a href=&quot;https://vercel.com/docs/project-configuration#&quot;&gt;configuration file&lt;/a&gt; for Vercel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following to your &lt;code&gt;vercel.json&lt;/code&gt; file, so that every request is routed to &lt;code&gt;/api&lt;/code&gt; endpoint because that where the express app as a serverless function lives.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;  &quot;rewrites&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;     &quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/(.*)&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;      &quot;destination&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;/api&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;git&lt;/code&gt; repository on GitHub and add your code to it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;a href=&quot;https://vercel.com/new&quot;&gt;new project&lt;/a&gt; on Vercel and import the &lt;code&gt;git&lt;/code&gt; repository that you just made.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/8MGt3fH.jpg&quot; alt=&quot;import repo in vercel&quot; height=&quot;307&quot; width=&quot;709&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Go to the project &lt;strong&gt;Settings &amp;gt; Build and Deployment &amp;gt; Framework Settings&lt;/strong&gt; and override the default output directory with the root directory &lt;code&gt;.&lt;/code&gt;. The reason of doing so is to tell Vercel to look for production ready files here. If you intend to use typescript, then the output directory will be the directory in which your compiled files are stored.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://res.cloudinary.com/dfue3cfts/image/upload/q_auto:eco/v1747666745/Syntackle/Posts/Screenshot_2025-05-19_at_8.27.53_PM_srtkth.png&quot; alt=&quot;modifying output directory of a project in vercel&quot; height=&quot;671&quot; width=&quot;1266&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;
&lt;p&gt;Deploy the application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your application should now be live! 🎉&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/8WwxhDO.jpg&quot; alt=&quot;deployment&quot; height=&quot;621&quot; width=&quot;1649&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;p&gt;Here&#39;s the &lt;a href=&quot;https://express-to-vercel-demo.vercel.app/&quot;&gt;live demo&lt;/a&gt; of the application. You can also find the source code on my &lt;a href=&quot;https://github.com/murtuzaalisurti/express-to-vercel&quot;&gt;express-to-vercel&lt;/a&gt; github repository!&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-create-and-deploy-an-express-js-app-to-vercel-ljgvGrsCH7ioHsAxuw3G/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Optional Chaining in JavaScript</title>
    <link href="https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/"/>
    <published>2022-04-04T00:00:00Z</published>
    <updated>2023-12-17T10:43:41Z</updated>
    <id>https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/</id>
    <content xml:lang="en" type="html">&lt;p id=&quot;definition&quot;&gt;Optional Chaining in JavaScript is used to return &lt;code&gt;undefined&lt;/code&gt; for accessing an object property that doesn&#39;t exist and whose parent property is &lt;em&gt;&lt;strong&gt;nullish (null or undefined).&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you are unaware that property exists or not and you want to avoid the error that&#39;s being thrown, you may want to use optional chaining to get around with it.&lt;/p&gt;
&lt;p&gt;In this article, you’ll learn how and &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#when-to-use-optional-chaining&quot;&gt;when to use Optional Chaining&lt;/a&gt;. You’ll also learn &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#what-you-cannot-do-in-optional-chaining&quot;&gt;when not to use&lt;/a&gt; Optional Chaining in JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; tabindex=&quot;-1&quot;&gt;How it Works &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#how-it-works&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, let&#39;s explore what can go wrong when accessing a property in a nested object.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; person&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;Murtuza&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    work&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;Software Developer&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    socials&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            username&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;murtuzaalisurti&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://github.com/murtuzaalisurti&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            proUser&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;                is&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;no&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        linkedin&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            username&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;murtuzaali-surti&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://linkedin.com/in/murtuzaali-surti&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        twitter&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            username&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;murtuza_surti&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;            link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://twitter.com/murtuza_surti&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above object, let&#39;s try to access the property &lt;code&gt;link&lt;/code&gt; nested within the property &lt;code&gt;website&lt;/code&gt;. Can we?&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;website&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;//an error will be thrown&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get an error,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;Cannot&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; read&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; property&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;link&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; undefined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The property website doesn&#39;t exist in the object!&lt;/p&gt;
&lt;p&gt;But, let&#39;s add the property &lt;code&gt;website&lt;/code&gt; to the root object and set the value of it as &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;website&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s check if this works,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;website&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;//an error will be thrown&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get a similar error,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;Cannot&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; read&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; property&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &#39;link&#39;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As mentioned in the above &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#definition&quot;&gt;definition&lt;/a&gt;, we can use optional chaining to handle these types of errors! Here&#39;s how we can do that.&lt;/p&gt;
&lt;h2 id=&quot;syntax&quot; tabindex=&quot;-1&quot;&gt;&lt;strong&gt;&lt;strong&gt;Syntax&lt;/strong&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// website: property to validate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// link: property to access&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;website&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;link&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The operator &lt;code&gt;?.&lt;/code&gt; will check if the property on its left-hand side is &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; and if that&#39;s the case, then it will simply return &lt;code&gt;undefined&lt;/code&gt; without throwing any errors. In other words, this is also known as &lt;strong&gt;short-circuiting&lt;/strong&gt;. Otherwise, it will return the value of the property on its right-hand side.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://i.imgur.com/rUOx6qB.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;demo&quot; height=&quot;139&quot; width=&quot;1141&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Not just that, you can also invoke a function if it exists using optional chaining.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;work&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, you can access properties using &lt;code&gt;[]&lt;/code&gt; brackets.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;socials&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-you-cannot-do-in-optional-chaining&quot; tabindex=&quot;-1&quot;&gt;What You Can’t Do &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#what-you-cannot-do-in-optional-chaining&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You cannot apply optional chaining to the objects that are not declared yet. For example:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;prop&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // object is not defined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We haven&#39;t declared &lt;code&gt;object&lt;/code&gt;, thus it will throw an error.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You cannot assign a value to this expression. In other words, the optional chaining expression can&#39;t be on the left-hand side.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The below code is not valid.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;socials&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt; // not valid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;when-to-use-optional-chaining&quot; tabindex=&quot;-1&quot;&gt;When to Use Optional Chaining? &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/#when-to-use-optional-chaining&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s important to note that optional chaining should not be used when it&#39;s not necessary to do so. Only use optional chaining when you know that the property that you want to access is optional and not mandatory.&lt;/p&gt;
&lt;p&gt;For example, in our object &lt;code&gt;person&lt;/code&gt;, we can keep the social media platforms optional, so we are not sure if a user has a &lt;a href=&quot;https://syntackle.com/blog/skeleton-loading-for-social-media-embeds-using-css-and-javascript-SrqqO--X_JMn2wVKyzAroLOs03/&quot;&gt;social media&lt;/a&gt; account or not on a particular platform. For that, we can use optional chaining to check if a user has a social media account on a particular platform and if it exists, get the username.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;person&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;socials&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;github&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;?.[&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, if we place the optional chaining operator at the root object, then it doesn&#39;t make any sense because the root object i.e. &lt;code&gt;person&lt;/code&gt; must exist and if it doesn&#39;t exist, we should get an error!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this article, you learned what Optional Chaining in &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;JavaScript&lt;/a&gt; is, how it works when to use it, and when not to use it.&lt;/p&gt;
&lt;p&gt;To learn more about how Optional Chaining works, make sure to check out the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#specifications&quot;&gt;MDN documentation&lt;/a&gt; on it for more details.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to compile SASS/SCSS into CSS and watch for changes?</title>
    <link href="https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/"/>
    <published>2022-03-24T00:00:00Z</published>
    <updated>2025-02-08T14:09:20Z</updated>
    <id>https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/</id>
    <content xml:lang="en" type="html">&lt;details&gt;&lt;summary data-pagefind-ignore=&quot;&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-grid-2x2-check&quot;&gt;&lt;path d=&quot;M12 3v17a1 1 0 0 1-1 1H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a1 1 0 0 1-1 1H3&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m16 19 2 2 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; Table of Contents &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-down down-arrow&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-chevron-up up-arrow&quot;&gt;&lt;path d=&quot;m18 15-6-6-6 6&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/summary&gt;&lt;span id=&quot;toc&quot;&gt;&lt;/span&gt;&lt;/details&gt;
&lt;p&gt;SASS or SCSS extends CSS which means that you can have all the features of CSS plus the features of SASS just like a cherry on top of a cake!&lt;/p&gt;
&lt;p&gt;Browsers don&#39;t understand &lt;a href=&quot;https://sass-lang.com/&quot;&gt;SASS&lt;/a&gt;, just like they don&#39;t understand &lt;a href=&quot;https://reactjs.org/docs/introducing-jsx.html&quot;&gt;JSX&lt;/a&gt; (which is compiled into valid javascript) in React. Which is why we need to compile SASS into normal CSS in order to run it in the browser.&lt;/p&gt;
&lt;p&gt;Let&#39;s see how we can transform a SASS file into a CSS file assuming that you have &lt;a href=&quot;https://sass-lang.com/install&quot;&gt;SASS already installed&lt;/a&gt; into your system.&lt;/p&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M21.801 10A10 10 0 1 1 17 3.335&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m9 11 3 3L22 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt; RECOMMENDED&lt;/p&gt;
&lt;p&gt;Are you a beginner trying to get a gist of CSS and HTML? I personally started my web dev journey with this &lt;a href=&quot;https://www.amazon.in/HTML-CSS-Design-Build-Websites/dp/1118008189?pd_rd_w=xLzKo&amp;amp;content-id=amzn1.sym.d4089320-ab32-4dd6-a621-3f0516aefb4d&amp;amp;pf_rd_p=d4089320-ab32-4dd6-a621-3f0516aefb4d&amp;amp;pf_rd_r=29GWKXWFQ06KMMW5710H&amp;amp;pd_rd_wg=pE2OG&amp;amp;pd_rd_r=7e3eebe2-7091-4f8e-9124-504fba47ba54&amp;amp;pd_rd_i=1118008189&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=syntackle-21&amp;amp;linkId=2d222709d7e366a74821ee8cf722ea79&amp;amp;language=en_IN&amp;amp;ref_=as_li_ss_tl&quot;&gt;book by John Duckett&lt;/a&gt; and it is one of the best books which will help you explore the world of CSS and HTML.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;compiling-a-sass-scss-file&quot; tabindex=&quot;-1&quot;&gt;Compiling a SASS/SCSS file &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/#compiling-a-sass-scss-file&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s say we have a folder structure something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;public/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;styles/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;src/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;styles/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    -&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt; &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;style.scss&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to compile the file with &lt;code&gt;.scss&lt;/code&gt; extension which is ultimately a SASS file, into a CSS file in &lt;code&gt;public/styles&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;We can do that by executing this command in the terminal at the root of the folder:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sass&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles:public/styles&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The directory before the colon &lt;code&gt;:&lt;/code&gt; is the input directory and the directory after the colon is the output directory.&lt;/p&gt;
&lt;p&gt;If you have your SASS file in the root directory and want to output the CSS file in the same root directory, you can use:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sass&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; style.scss&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; style.css&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Here, &lt;em&gt;&#39;root directory&#39;&lt;/em&gt; means the directory you are &lt;em&gt;&lt;strong&gt;currently pointing to&lt;/strong&gt;&lt;/em&gt; in your terminal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But what if we want to place the CSS file in the same directory as the SASS file? You can do that by executing the above command only:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sass&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles:src/styles&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s get to the juicy part. Let&#39;s see how we can &lt;code&gt;watch&lt;/code&gt; the changes made to our SCSS file and automatically compile them into CSS.&lt;/p&gt;
&lt;h2 id=&quot;watching-for-changes&quot; tabindex=&quot;-1&quot;&gt;Watching for changes &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/#watching-for-changes&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Just add a &lt;code&gt;--watch&lt;/code&gt; flag in the command to watch the changes made to the Sass file in &lt;code&gt;src/styles&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;sass&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; --watch&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; src/styles:public/styles&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s it. Now, the changes you make in the SASS file will automatically be compiled into CSS as soon as you save the SASS file!&lt;/p&gt;
&lt;p&gt;Also, if you are using &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;VSCode&lt;/a&gt;, then you can use &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass&quot;&gt;an extension&lt;/a&gt; to compile SASS files into CSS which makes it very convenient to deal with SASS, but that too has it&#39;s &lt;a href=&quot;https://www.youtube.com/watch?v=o4cECvhrBo8&quot;&gt;pros and cons&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>IIFE in JavaScript</title>
    <link href="https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/"/>
    <published>2022-02-26T00:00:00Z</published>
    <updated>2023-12-17T10:55:22Z</updated>
    <id>https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/</id>
    <content xml:lang="en" type="html">&lt;p&gt;You might be familiar with functions in JavaScript. An &lt;em&gt;&lt;strong&gt;IIFE (Immediately Invoked Function Expression)&lt;/strong&gt;&lt;/em&gt; is a special type of function which is invoked implicitly.&lt;/p&gt;
&lt;p&gt;Even if you don&#39;t invoke it in your &lt;a href=&quot;https://syntackle.com/blog/5-vscode-extensions-you-must-use-JTRFImxbBtrq6btizBCJ/&quot;&gt;code&lt;/a&gt;, it will run on it&#39;s own. You can relate it with a callback function which is automatically called when a particular event is fired.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;IIFE&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also define an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;arrow function&lt;/a&gt; as an IIFE.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;IIFE&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might be wondering, well what&#39;s the use of this type of function? This same thing can be done like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; func&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;IIFE&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Well, here&#39;s the catch. When we define a global variable in JavaScript, it can be accessed from anywhere in our code. For example,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; print&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    b&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 8 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 8 &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above code, the value of the variable &lt;code&gt;b&lt;/code&gt; is modified from &lt;code&gt;10&lt;/code&gt; to &lt;code&gt;8&lt;/code&gt;. But what if we don&#39;t want to modify the value of the global variable &lt;code&gt;b&lt;/code&gt;. What can we do?&lt;/p&gt;
&lt;p&gt;One thing we can do is to initialize a new variable &lt;code&gt;b&lt;/code&gt; inside the scope of the function &lt;code&gt;print()&lt;/code&gt; just like this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; print&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 8 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 10 &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We were able to create a new variable inside the scope of the function without actually modifying the actual global variable.&lt;/p&gt;
&lt;p&gt;But, there&#39;s another way! Let&#39;s say you don&#39;t want to reuse the function &lt;code&gt;print()&lt;/code&gt; and also you don&#39;t want to create a mess with global variables unintentionally. In that case, you can use an IIFE. Here&#39;s how you can do that :&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 8&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;    a&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 9&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// modifying the copy of &#39;a&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 9 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// passing a copy of variable as an argument&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;// output: 8 &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, we are passing the value of variable &lt;code&gt;a&lt;/code&gt; to the IIFE. Remember that we are only passing a copy of the variable, so we are not actually modifying the global variable. This is most useful when you are dealing with multiple files which are being imported and exported in your project and you don&#39;t know the name of every global variable defined.&lt;/p&gt;
&lt;p&gt;An IIFE is a function which does it&#39;s own thing without affecting things on a global level.&lt;/p&gt;
&lt;p&gt;You can also make an IIFE asynchronous.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro has-highlighted&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; get&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    // do something&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was a brief look at IIFE. I hope you got some idea of what&#39;s IIFE and how we can use it. If you want to dig deeper, &lt;a href=&quot;https://web.archive.org/web/20171201033208/http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife&quot;&gt;check this out&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/iife-in-javascript-XC6A0qHlZMh8Gts_MaDg/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to make a QR Code generator using JavaScript?</title>
    <link href="https://syntackle.com/blog/how-to-make-a-qr-code-generator-using-javascript-5-rbxEeFYAidZ_zVp2Lh/"/>
    <published>2021-12-23T00:00:00Z</published>
    <updated>2023-12-17T10:53:45Z</updated>
    <id>https://syntackle.com/blog/how-to-make-a-qr-code-generator-using-javascript-5-rbxEeFYAidZ_zVp2Lh/</id>
    <content xml:lang="en" type="html">&lt;p&gt;While you can generate QR codes for URLs in browsers such as Chrome, it&#39;s always interesting to learn how you can make your own version of a simple QR code generator. So, here we go.&lt;/p&gt;
&lt;h2 id=&quot;html&quot; tabindex=&quot;-1&quot;&gt;HTML&lt;/h2&gt;
&lt;p&gt;Here&#39;s a quick look at the HTML code and it&#39;s pretty straightforward.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;heading&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;QRcodes&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;sub-title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Generate QRCode for anything!&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;user-input&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;input_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Type something...&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;input_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;input_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; autocomplete&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;off&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Generate QR Code&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;display: none;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;./js/app.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last element is for the QR code to be displayed as soon as we fetch it from a library through javascript (more on that later).&lt;/p&gt;
&lt;p&gt;Let&#39;s move on to some javascript.&lt;/p&gt;
&lt;h2 id=&quot;javascript&quot; tabindex=&quot;-1&quot;&gt;JavaScript&lt;/h2&gt;
&lt;p&gt;First of all, we will create an event for when the user clicks on the &lt;code&gt;Generate QR code&lt;/code&gt; button.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; btn&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.button&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;btn&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;   //code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we are going to create a function known as &lt;code&gt;generate()&lt;/code&gt; which will be invoked as soon as the user clicks on the &lt;code&gt;Generate QR code&lt;/code&gt; button. This function will take the text input from the user as a parameter.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;    //code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside this function, we are going to use a javascript library &lt;a href=&quot;https://davidshimjs.github.io/qrcodejs/&quot;&gt;qrcode.js&lt;/a&gt; to generate QR code. You can use this library via a CDN by including the below &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag of &lt;code&gt;html&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside the &lt;code&gt;generate()&lt;/code&gt; function, we will create a new object using the given library. It will take two arguments, first is the element in which the QR code has to be displayed and secondly, the content for which the QR code has to be generated and some options to customize the QR code.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    var&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; qrcode&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; QRCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;), {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        width&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;180&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;//default 128&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        height&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;180&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        colorDark &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#000000&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        colorLight &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#ffffff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        correctLevel &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;QRCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;CorrectLevel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;H&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we will create a download button and append it below the QR code.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; download&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;download&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inside this download button we will add a link which allows users to download the QR code with a specified file name and append it into the download button. You  can &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download&quot;&gt;learn more about the download attribute here&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; download_link&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;download&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;qr_code_linq.png&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;innerText&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;Download&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;download&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s figure out the &lt;code&gt;href&lt;/code&gt; attribute of the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag next.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;qrcode&lt;/code&gt; object will return a &lt;code&gt;canvas&lt;/code&gt; element as well as an &lt;code&gt;image&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;For smartphones, the &lt;code&gt;canvas&lt;/code&gt; element will be visible but for desktop, the &lt;code&gt;image&lt;/code&gt; element will be visible having a &lt;code&gt;src&lt;/code&gt; attribute set to a &lt;code&gt;dataURL&lt;/code&gt;. We will use the &lt;code&gt;dataURL&lt;/code&gt; to download the QR code.&lt;/p&gt;
&lt;p&gt;In the case of desktop, it&#39;s pretty obvious. We just have to grab the value of &lt;code&gt;src&lt;/code&gt; attribute of the image element and assign it to the &lt;code&gt;href&lt;/code&gt; attribute of the download link (&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag) after a specified amount of time (0.3 seconds) using &lt;code&gt;setTimeout()&lt;/code&gt; function because the QR code takes some time to be generated.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; qr_code_img&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;qr_code_img&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But how do we get the &lt;code&gt;dataURL&lt;/code&gt; from the canvas element? By using the method &lt;code&gt;toDataURL()&lt;/code&gt; on the &lt;code&gt;canvas&lt;/code&gt; element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; qr_code_canvas&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;canvas&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;qr_code_canvas&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toDataURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After applying some logic, we get this:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;qr_code_img&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;qr_code_canvas&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toDataURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;qr_code_img&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, the &lt;code&gt;.qr-code&lt;/code&gt; element will be hidden until the user clicks on the &lt;code&gt;Generate QR code&lt;/code&gt; button. With this, our &lt;code&gt;generate()&lt;/code&gt; function is all set to be invoked.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    var&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; qrcode&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; QRCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;), {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        width&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;180&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;//128&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        height&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;180&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        colorDark &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#000000&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        colorLight &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#ffffff&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;        correctLevel &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;QRCode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;CorrectLevel&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;H&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;qrcode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; download&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;download&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; download_link&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;download&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;qr_code_linq.png&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;innerText&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;Download&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    download&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;canvas&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toDataURL&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;        setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            download_link&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now inside our click event function, we will check if there is already a QR code displayed or not. If it is, then we will first clear that QR code and &lt;a href=&quot;https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/&quot;&gt;generate&lt;/a&gt; a new one. If it&#39;s not present, we can simply generate a new one.&lt;/p&gt;
&lt;p&gt;Also, all of this happens only if the user enters some text or if the input value is not empty.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;btn&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; user_input&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#input_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;childElementCount&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;            document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;innerHTML&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;            generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;user_input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.qr-code&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;display: none&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;        console&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;not valid input&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can style the elements the way as you want. Here are the styles that I went for:&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:root&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;62.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    box-sizing: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;border-box&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-size-adjust: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;    -webkit-text-size-adjust&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:hover&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    cursor: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;pointer&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    flex-direction: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    align-items: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#EAE6E5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.heading&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .sub-title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-align: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Poppins&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#12130F&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.sub-title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.user-input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    flex-direction: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    align-items: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.user-input&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-align: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Poppins&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.user-input&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;80&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    max-width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;35&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Poppins&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    outline: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#9b8774ad&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-align: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    outline: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.7&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin-bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#5b92799d&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#12130F&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Poppins&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.qr-code&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-right: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-bottom-left-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-bottom-right-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-left: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; #8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.qr-code&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    justify-content: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#8F8073&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Poppins&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#EAE6E5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    outline: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin-top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.qr-code&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; button&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    text-decoration: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;#EAE6E5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a demo of the entire project:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;XWeeVrG&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/XWeeVrG&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here&#39;s the &lt;a href=&quot;https://github.com/murtuzaalisurti/qr&quot;&gt;github repository&lt;/a&gt; for this project.&lt;/p&gt;
&lt;p&gt;That&#39;s all for now. I am on &lt;a href=&quot;https://twitter.com/murtuza_surti&quot;&gt;Twitter&lt;/a&gt; as well as &lt;a href=&quot;https://github.com/murtuzaalisurti&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/how-to-make-a-qr-code-generator-using-vanilla-javascript-3cla&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-make-a-qr-code-generator-using-javascript-5-rbxEeFYAidZ_zVp2Lh/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Skeleton Loading for Social Media Embeds using CSS and JavaScript 🔥</title>
    <link href="https://syntackle.com/blog/skeleton-loading-for-social-media-embeds-using-css-and-javascript-SrqqO--X_JMn2wVKyzAroLOs03/"/>
    <published>2021-09-26T00:00:00Z</published>
    <updated>2023-12-17T10:40:49Z</updated>
    <id>https://syntackle.com/blog/skeleton-loading-for-social-media-embeds-using-css-and-javascript-SrqqO--X_JMn2wVKyzAroLOs03/</id>
    <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: This post is inspired by &lt;a href=&quot;https://youtu.be/ZVug65gW-fc&quot;&gt;Web Dev Simplified&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Social media embeds take some time to load and render, hence the user experience is not so good! Here&#39;s an example of twitter embeds:&lt;/p&gt;
&lt;p&gt;Without applying skeleton loading:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fi3mvfp595v20gx5oqm.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;Without skeleton loading&quot; height=&quot;353&quot; width=&quot;830&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;After applying skeleton loading:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqcsp8h77v63c9bsn9ny.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;after applying skeleton loading&quot; height=&quot;833&quot; width=&quot;1868&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;As you might have noticed, the user experience without skeleton loading is not so good! So, let&#39;s see how can we implement skeleton loading on twitter embeds!&lt;/p&gt;
&lt;h2 id=&quot;embedding-tweets&quot; tabindex=&quot;-1&quot;&gt;Embedding Tweets&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweets&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    //tweets&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we have created a container which will contain all our twitter embeds.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweets&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweet&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        //tweet 1 (paste the twitter embed code here without the script tag)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweet&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        //tweet 2 (paste the twitter embed code here without the script tag)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Paste the embed code of your tweet as shown above. Here&#39;s how you can get the embed code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to your tweet&lt;/li&gt;
&lt;li&gt;Click on the more menu&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/doopwfm8w7jwev3mwhe3.jpg&quot; alt=&quot;more_menu&quot; height=&quot;353&quot; width=&quot;830&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;Select the &#39;Embed Tweet&#39; option&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5yb2cka8ac8bl65ujr1.jpg&quot; alt=&quot;embed tweet option&quot; height=&quot;434&quot; width=&quot;447&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;You will be redirected to a new tab and you can copy the embed code from there itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1wz3f3cbcpsn5q2ka1k.jpg&quot; alt=&quot;twitter embed code&quot; height=&quot;592&quot; width=&quot;1283&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Note that you don&#39;t need to add multiple script tags for different tweets. You can add just one script tag at the bottom of the body element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;//add this just before the &amp;#x3C;/body&gt; tag.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;https://platform.twitter.com/widgets.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66;font-style:italic&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that you have done that, it&#39;s time to style the embeds using CSS!&lt;/p&gt;
&lt;h3 id=&quot;styling-the-embeds-using-css&quot; tabindex=&quot;-1&quot;&gt;Styling the embeds using CSS&lt;/h3&gt;
&lt;p&gt;You can do that by applying Flexbox properties to the container just like this!&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweets&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    flex-flow: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; wrap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    justify-content: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also customize the width of the embed! But note that the tweet embed can only shrink upto a certain limit. If you go beyond that threshold, the embed will overflow, so keep that in mind.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, it&#39;s time to create a skeleton for these tweets!&lt;/p&gt;
&lt;h2 id=&quot;creating-skeleton-for-embeds&quot; tabindex=&quot;-1&quot;&gt;Creating Skeleton for Embeds&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweets-skeleton&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweet-skeleton&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;img&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;content-1&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;line&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;line&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;line&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;content-2&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;line&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;            &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;line&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, let&#39;s style this skeleton using CSS.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweets&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .tweets-skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    flex-flow: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; wrap&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    justify-content: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.05&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;190&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;190&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;190&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin-bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .img&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .content-1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .content-2&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin-top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .line&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:last-child&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;75&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your tweet skeleton should look something like this:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qq03683q9ebguv8jxmxk.jpg&quot; alt=&quot;tweet skeleton&quot; height=&quot;549&quot; width=&quot;577&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Let&#39;s animate this skeleton to make it look like something is loading in the background! We will do that by using the concept of &#39;keyframes&#39; in CSS and animating the background color of the lines of text as well as the image!&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt; tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    0%{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    100%{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;243&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;243&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;243&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then, we will define the animation properties for the same.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .img&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    animation: tweet-skeleton &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; linear&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; infinite&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; alternate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.tweet-skeleton&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .line&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    margin: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;209&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    animation: tweet-skeleton &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; linear&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; infinite&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; alternate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&#39;s the output:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/giw4zssl4g30gul8yz6m.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;skeleton loading animation&quot; height=&quot;553&quot; width=&quot;586&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;As Kyle Cook wonderfully explains in his video, here&#39;s how you can create multiple skeleton templates based on your requirement using JavaScript!&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; tweets_skeleton&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.tweets-skeleton&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; tweet_skeleton&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.tweet-skeleton&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;  tweets_skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;tweet_skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;cloneNode&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here comes the fun part! How to show the skeleton while the tweet embed is rendering? We are going to do that by using the &lt;code&gt;setTimeout&lt;/code&gt; function in JavaScript.&lt;/p&gt;
&lt;p&gt;The idea is to hide the tweet embeds for a certain time until they are rendered as &lt;code&gt;iframes&lt;/code&gt; and showing the skeleton instead. After the specified time, the skeleton will hide itself and the tweet embeds will be shown. This is certainly not the best way to do this. Another approach is to &lt;a href=&quot;https://stackoverflow.com/a/5529841&quot;&gt;detect the network speed&lt;/a&gt; of the client and accordingly decide the timing.&lt;/p&gt;
&lt;p&gt;But to make things simple, we are going to use the &lt;code&gt;setTimeout&lt;/code&gt; function which will be executed after 4 seconds.&lt;/p&gt;
&lt;p&gt;Add these styles to the tweets container.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tweets&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;visibility: hidden; display: none;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setTimeout&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;  document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.tweets&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;visibility: hidden;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;  tweets_skeleton&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;display: none;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;4000&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;If there are large number of tweets, the loading time may increase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&#39;s the final output:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;ExXWXjZ&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/ExXWXjZ&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;That&#39;s all for now! I&#39;m on twitter as &lt;a href=&quot;https://twitter.com/murtuza_surti&quot;&gt;murtuza_surti&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/skeleton-loading-for-social-media-embeds-using-css-and-javascript-4njb&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/skeleton-loading-for-social-media-embeds-using-css-and-javascript-SrqqO--X_JMn2wVKyzAroLOs03/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to create Google&#39;s Material Design Text Input Field using CSS and JavaScript?</title>
    <link href="https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/"/>
    <published>2021-07-18T00:00:00Z</published>
    <updated>2023-10-01T00:00:00Z</updated>
    <id>https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/</id>
    <content xml:lang="en" type="html">&lt;p&gt;In this tutorial, we are trying to recreate Google&#39;s text input field animation and design from scratch with the help of CSS as well as JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;html&quot; tabindex=&quot;-1&quot;&gt;HTML&lt;/h2&gt;
&lt;p&gt;We are not going to use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements&quot;&gt;pseudo-elements&lt;/a&gt; to create this effect, but we will be taking help of &lt;code&gt;div&lt;/code&gt; element instead.&lt;/p&gt;
&lt;p&gt;We are wrapping the &lt;code&gt;input&lt;/code&gt; element and its related &lt;code&gt;div&lt;/code&gt;s inside a container. To create a placeholder, we have defined a separate &lt;code&gt;div&lt;/code&gt; which will act as a placeholder rather than using the &lt;code&gt;:placeholder&lt;/code&gt; pseudo-element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;input-contain&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; autocomplete&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;off&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; aria-labelledby&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;placeholder-fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;placeholder-text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;placeholder-fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;     &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;First Name&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;css&quot; tabindex=&quot;-1&quot;&gt;CSS&lt;/h2&gt;
&lt;p&gt;First of all, let&#39;s define the properties for the &lt;code&gt;input&lt;/code&gt; element and it&#39;s container.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.input-contain&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;relative&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; black&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will be placing the placeholder text on top of the &lt;code&gt;input&lt;/code&gt; element by setting the position of the placeholder text to &lt;code&gt;absolute&lt;/code&gt; so that it matches the width and height of the &lt;code&gt;input&lt;/code&gt; container.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    left: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    right: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; transparent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;transparent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    align-items: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But there&#39;s an issue. You can&#39;t click on the input element because the placeholder element is on the top of the input element. In order to overcome this situation, just set the value of &lt;code&gt;pointer-events&lt;/code&gt; to &lt;code&gt;none&lt;/code&gt; for the placeholder element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    pointer-events: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s style the placeholder text a little bit.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.4&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0.5&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;transparent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;black&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.4&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    padding: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1.2&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next up, let&#39;s define what should happen when the input element is focused.&lt;/p&gt;
&lt;p&gt;We are going to change the &lt;code&gt;border-color&lt;/code&gt; rather than keeping the outline on focus event.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:focus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    outline: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-color: blueviolet;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want the placeholder text to translate along Y-axis(to go up) and reduce it&#39;s &lt;code&gt;font-size&lt;/code&gt; a little bit when the input element is focused. Also, we can change the color of the placeholder text. Here&#39;s how we can do that. Change the &lt;code&gt;background-color&lt;/code&gt; to resemble the surrounding color to make it more elegant.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:focus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;white&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;black&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;-170&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-color: blueviolet;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: blueviolet;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a smooth transition, add &lt;code&gt;transition&lt;/code&gt; property to the placeholder text.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transition: transform &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.15&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, font-size &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.15&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, background-color &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0.2&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 0.15&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Up until now everything is fine, but now a problem arises. When you enter text in the input element and then remove the focus from the input element, the placeholder text comes to it&#39;s original position and we don&#39;t want that. We want the placeholder text to remain above the input text when something is already entered in the input field. Hence, we will be taking the help of &lt;a href=&quot;https://syntackle.com/blog/optional-chaining-in-javascript-D6SuXGtu0-K5hhtZUqqc/&quot;&gt;JavaScript&lt;/a&gt; and we will modify &lt;a href=&quot;https://syntackle.com/blog/how-to-create-a-notification-badge-with-css-WrkjgwxkL5bw-mFwMFjl/&quot;&gt;CSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you remember, we have already defined &lt;code&gt;value&lt;/code&gt; attribute for the &lt;code&gt;input&lt;/code&gt; element. This will come handy.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; autocomplete&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;off&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; aria-labelledby&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;placeholder-fname&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s modify some CSS. As already discussed, when the value is an empty string, the placeholder text should come back to its original position, but when the value is other than an empty string, the placeholder text should remain transformed(above the input text). We can achieve that by defining a &lt;code&gt;:not&lt;/code&gt; pseudo-class on the input element value. Here&#39;s how we can do that.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:focus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; :not&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;]) &lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;white&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;black&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;-170&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;:focus&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .placeholder-text&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .text&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-color: blueviolet;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: blueviolet;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But wait. The value attribute will remain the same in HTML. How can we change and set it to the string entered by the user? That&#39;s where JavaScript comes into action.&lt;/p&gt;
&lt;p&gt;We will set the value of the &lt;code&gt;value&lt;/code&gt; attribute to the string entered by the user just like this,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; input_element&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;input_element&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;keyup&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    input_element&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;input_element&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s it. You just made a modern material design text input field.&lt;/p&gt;
&lt;p&gt;Here&#39;s the final output:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;LYyLYGK&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/LYyLYGK&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/how-to-create-google-s-material-design-text-input-field-animation-38n&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-create-google-s-material-design-text-input-field-using-css-and-javascript-b0WGutb2uKPHdeSFNq2X/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to create an HTML generator with JavaScript?</title>
    <link href="https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/"/>
    <published>2021-07-13T00:00:00Z</published>
    <updated>2023-12-17T10:51:23Z</updated>
    <id>https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/</id>
    <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Before you proceed&lt;/strong&gt;:- This post is not about creating a safe or the best HTML generator rather it&#39;s just something for fun that you can try by using template literals in JavaScript. It was a fun experiment for me.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ever tired of writing multiple lines of similar HTML? If you are, then you can automate the process by using template literals in &lt;a href=&quot;https://syntackle.com/blog/minify-javascript-using-terser-TUYCYJ5y/&quot;&gt;JavaScript&lt;/a&gt;. Let&#39;s see how we can do that.&lt;/p&gt;
&lt;p&gt;Let&#39;s say you have multiple boxes which are actually hyperlinks and you want to create multiple of them.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u01jbnqch3x47e2dknjl.jpg&quot; alt=&quot;HTML Hyperlinks&quot; height=&quot;772&quot; width=&quot;1081&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;One way is to just copy and paste the HTML code and make changes to a particular section of the code. This approach can work for small projects but if your project is big enough, then it can become a mess.&lt;/p&gt;
&lt;p&gt;Alternatively, you can create your own HTML generator using &lt;code&gt;template literals&lt;/code&gt; in JavaScript which will generate HTML code for you!&lt;/p&gt;
&lt;h2 id=&quot;template-literals&quot; tabindex=&quot;-1&quot;&gt;Template Literals in JavaScript &lt;a href=&quot;https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/#template-literals&quot;&gt;&lt;sup&gt;#&lt;/sup&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Template literals in JavaScript are nothing but string literals which allow you to embed various expressions into the string. They are enclosed in backticks. For embedding an expression the syntax goes like this,&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `first part of the string &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;expression&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; second part of the string`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s create the HTML generator.&lt;/p&gt;
&lt;p&gt;Create respective input fields for link URL, Title &amp;amp; a Tag. You can add your own input fields also if you want to.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;contains&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Title&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;URL&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Tag&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;label&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;Generate&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a &lt;code&gt;textarea&lt;/code&gt; field in which the resultant code will be displayed as well as create a button to copy the code to the clipboard.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textarea&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;result_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; rows&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;textarea&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;copy_btn&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fas fa-clipboard&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewjgd4wau9sythc3syem.jpg&quot; alt=&quot;HTML Generator User Interface&quot; height=&quot;868&quot; width=&quot;886&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;h2 id=&quot;javascript&quot; tabindex=&quot;-1&quot;&gt;JavaScript&lt;/h2&gt;
&lt;p&gt;We will create a function named &lt;code&gt;generate()&lt;/code&gt;. This function has three parameters — &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;tag&lt;/code&gt;. It will take in the value of the &lt;code&gt;title&lt;/code&gt;, the &lt;code&gt;url&lt;/code&gt;, and the &lt;code&gt;tag&lt;/code&gt; that we have input in the field as arguments.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;tag&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#7F848E;font-style:italic&quot;&gt;   //code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Further, we will use template literals and we will embed the &lt;code&gt;title&lt;/code&gt;, the &lt;code&gt;url&lt;/code&gt; &amp;amp; the &lt;code&gt;tag&lt;/code&gt; into the string. Then, set the value of the &lt;code&gt;result&lt;/code&gt; field to the string that is generated.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; title&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#title&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#url&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; tag&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#tag&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.result_text&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E06C75;font-style:italic&quot;&gt;tag&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; final_string&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; `&amp;#x3C;a href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;&gt;&amp;#x3C;div class=&quot;link&quot;&gt;&amp;#x3C;div class=&quot;banner&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;tag&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&amp;#x3C;/div&gt;&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&amp;#x3C;/div&gt;&amp;#x3C;/a&gt;`&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; final_string&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All of this will take place after the user clicks the generate button and so let&#39;s add an eventListener to it.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; submit_btn&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;#submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;submit_btn&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    generate&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;tag&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    title&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    tag&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to copy the code from the &lt;code&gt;textarea&lt;/code&gt;, we can define a function called &lt;code&gt;copy()&lt;/code&gt; and then call the function when the user clicks on the &#39;copy to clipboard&#39; button.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt; copy_btn&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt; document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.copy_btn&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;copy_btn&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;    copy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt; copy&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    result&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;select&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;execCommand&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;copy&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&#39;s a quick demo:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;OJmWMpK&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/OJmWMpK&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now, you can copy the code into your main project.&lt;/p&gt;
&lt;p&gt;This is just one of the use cases of template literals. You can do a lot of things by using template literals in JavaScript. They make your life as a JavaScript developer pretty easy.&lt;/p&gt;
&lt;p&gt;Signing off.&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/how-to-create-an-html-generator-with-javascript-gdg&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-create-an-html-generator-with-javascript-TOku-OzmLp7AQXieYkwr/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>Dark mode toggle animation using CSS!</title>
    <link href="https://syntackle.com/blog/dark-mode-toggle-animation-using-css-wWkNc1nowuQVdhhYjVOC/"/>
    <published>2021-06-18T00:00:00Z</published>
    <updated>2023-12-17T10:54:42Z</updated>
    <id>https://syntackle.com/blog/dark-mode-toggle-animation-using-css-wWkNc1nowuQVdhhYjVOC/</id>
    <content xml:lang="en" type="html">&lt;p&gt;This tutorial will mainly focus on how to use transitions in CSS and make a toggle button for light as well as dark mode using little JavaScript. Let&#39;s dive into the world of transitions!&lt;/p&gt;
&lt;h2 id=&quot;html&quot; tabindex=&quot;-1&quot;&gt;HTML&lt;/h2&gt;
&lt;p&gt;HTML Markup is pretty simple to understand. All you have to do is to make a container for the icons that we are going to use from &lt;a href=&quot;https://fontawesome.com/v5.15/icons/sun?style=solid&quot;&gt;fontawesome&lt;/a&gt; and nest the respective &lt;code&gt;div&lt;/code&gt;s containing the icons inside the container.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;   &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;sun sun-logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fas fa-sun&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;   &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;   &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;moon moon-logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;      &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;fas fa-moon&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;   &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;css&quot; tabindex=&quot;-1&quot;&gt;CSS&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;relative&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.sun&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; .moon&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;fit-content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;fit-content&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.moon&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    inset: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the container position to be &lt;code&gt;relative&lt;/code&gt; and the moon container position to be &lt;code&gt;absolute&lt;/code&gt; because we will position the moon icon in the same position as that of the sun icon.&lt;/p&gt;
&lt;p&gt;Here&#39;s the interesting part. Instead of using &lt;code&gt;top: 0;&lt;/code&gt; &lt;code&gt;bottom: 0;&lt;/code&gt; &lt;code&gt;left: 0;&lt;/code&gt; and &lt;code&gt;right: 0;&lt;/code&gt; you can use &lt;code&gt;inset: 0;&lt;/code&gt; to get the same result. It works!&lt;/p&gt;
&lt;p&gt;Also, set the &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; of the sun and the moon container to &lt;code&gt;fit-content&lt;/code&gt;. What this will do is, it will set the height and width of the container to match the height and width of the content inside it.&lt;/p&gt;
&lt;p&gt;And, in order to change the size of the fontawesome icon, just change the &lt;code&gt;font-size&lt;/code&gt; of the icon.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.moon-logo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we will set up the initial position of the moon icon and its initial opacity when the webpage is rendered for the first time. Here, as the opacity of the moon icon is zero, only the sun icon will be visible to us.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;translateY(20%)&lt;/code&gt; declaration will offset the moon icon down along the Y-axis by 20% of the height of it&#39;s parent element.&lt;/p&gt;
&lt;p&gt;Similarly, the &lt;code&gt;rotateZ(50deg)&lt;/code&gt; declaration will rotate the moon icon along the Z-axis by 50 degrees.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.sun-logo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the same way, we will set the initial properties for the sun icon.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.animate-sun&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: aliceblue;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we will set the final properties of the sun icon to which it will transition into.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.animate-moon&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: aliceblue;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, we will set the final properties of the moon icon to which it will transition into. One thing to note here is the default color of the icons is &lt;code&gt;black&lt;/code&gt;, so if you want to change the color of the icon, then define its &lt;code&gt;color&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;But wait, we haven&#39;t used the &lt;code&gt;transition&lt;/code&gt; property yet, so how will it transition from one state to another? Yeah, that&#39;s the only thing left to do in CSS part.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.moon-logo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transition: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;all&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.sun-logo&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    opacity: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transform: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;rotateZ&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transition: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;all&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; ease-out&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    transition: background-color &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.dark&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;black&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will use the above class to change the &lt;code&gt;background-color&lt;/code&gt; of the &lt;code&gt;body&lt;/code&gt; when the transition of the icons will happen.&lt;/p&gt;
&lt;p&gt;That&#39;s it. Your CSS part is ready.&lt;/p&gt;
&lt;p&gt;Now, let&#39;s move on to the JavaScript part. We will use JavaScript to &lt;code&gt;toggle&lt;/code&gt; the classes on &lt;code&gt;click&lt;/code&gt; event.&lt;/p&gt;
&lt;h2 id=&quot;javascript&quot; tabindex=&quot;-1&quot;&gt;JavaScript&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.container&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#C678DD&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.sun-logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toggle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;animate-sun&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;.moon-logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toggle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;animate-moon&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;    document&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#E5C07B&quot;&gt;classList&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#61AFEF&quot;&gt;toggle&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;dark&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we have added an &lt;code&gt;eventListener&lt;/code&gt; to the container element so that when we click on the container, it will toggle the CSS classes for respective elements.&lt;/p&gt;
&lt;p&gt;Which means that, if the CSS class is not present in the &lt;code&gt;classList&lt;/code&gt; of an element, &lt;code&gt;toggle&lt;/code&gt; function will add the CSS class to the &lt;code&gt;classList&lt;/code&gt; of the respective element.&lt;/p&gt;
&lt;p&gt;And, if the CSS class is already present in the &lt;code&gt;classList&lt;/code&gt; of the element, it will remove it.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;classList&lt;/code&gt; is actually a &lt;code&gt;DOMTokenList&lt;/code&gt; but we will not go into the specifics of it.&lt;/p&gt;
&lt;p&gt;This is it. Here&#39;s the final output.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67x2v5x0txm0kznor5at.gif&quot; eleventy:ignore=&quot;&quot; alt=&quot;Final Output GIF&quot; height=&quot;957&quot; width=&quot;1918&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;LYWaoyQ&quot; data-user=&quot;seekertruth&quot; style=&quot;height: 571px; 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;
&lt;a href=&quot;https://codepen.io/seekertruth/pen/LYWaoyQ&quot;&gt;See the pen&lt;/a&gt; (&lt;a href=&quot;https://codepen.io/seekertruth&quot;&gt;@seekertruth&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 async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/dark-mode-toggle-animation-using-css-27il&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/dark-mode-toggle-animation-using-css-wWkNc1nowuQVdhhYjVOC/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>How to create a notification badge with CSS?</title>
    <link href="https://syntackle.com/blog/how-to-create-a-notification-badge-with-css-WrkjgwxkL5bw-mFwMFjl/"/>
    <published>2021-05-28T00:00:00Z</published>
    <updated>2023-12-17T10:58:42Z</updated>
    <id>https://syntackle.com/blog/how-to-create-a-notification-badge-with-css-WrkjgwxkL5bw-mFwMFjl/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Notification badges annoy me most of the times by popping up every now and then and I am pretty sure most of you experience similar thing, but anyways, let&#39;s see how we can create a notification badge using &lt;a href=&quot;https://syntackle.com/blog/how-to-compile-sass-into-css-and-watch-for-changes-5MHo7HhHUHUedZXaP62y/&quot;&gt;CSS&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;step-1%3A-html&quot; tabindex=&quot;-1&quot;&gt;Step 1: HTML&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;indicator&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;        &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;noti_count&quot;&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;1&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The element with a class &#39;&lt;em&gt;base&lt;/em&gt;&#39; will act as a profile image or an icon upon which we will position the notification indicator element having a class &#39;&lt;em&gt;indicator&lt;/em&gt;&#39;.&lt;/p&gt;
&lt;h2 id=&quot;step-2%3A-css&quot; tabindex=&quot;-1&quot;&gt;Step 2: CSS&lt;/h2&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.base&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; transparent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;relative&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First of all, we have to set up the height and width of the main &#39;&lt;em&gt;base&lt;/em&gt;&#39; element. Then we set the `border-radius`` property to 50%. Border radius rounds the edges of the border by a specified amount. In our case the height and width of the element are equal and so, when we apply border radius of 50%, a square looking element will transform to a circle.&lt;/p&gt;
&lt;p&gt;After applying a background color, the base element will look like a circle.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4gklfzuooiohhgkaexk.png&quot; alt=&quot;circle&quot; height=&quot;480&quot; width=&quot;679&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Now, set the position of the base element to &#39;&lt;em&gt;relative&lt;/em&gt;&#39; which means that it will be positioned relative to its current position. This will not change anything but we want this property to position the child elements, more on that in a second.&lt;/p&gt;
&lt;p&gt;You can also add an image instead of a background color to the base element, just like this.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.base&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    height: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    width: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; transparent&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-image: &lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&quot;../assets/unsplash.jpg&quot;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-size: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;cover&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;right&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;relative&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s design the indicator.&lt;/p&gt;
&lt;p&gt;First of all, set the position of the indicator as &#39;&lt;em&gt;absolute&lt;/em&gt;&#39; which means that it will be positioned inside the ancestor element which has its position as &#39;&lt;em&gt;relative&lt;/em&gt;&#39;.&lt;/p&gt;
&lt;p&gt;Then, we will define the final location of the indicator by setting the values of &lt;em&gt;top, bottom, right and left&lt;/em&gt; properties of the indicator.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.indicator&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    right: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    left: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: brown;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &#39;&lt;em&gt;bottom&lt;/em&gt;&#39; property will offset the &#39;&lt;em&gt;indicator&lt;/em&gt;&#39; element by 60% of the height of the &#39;&lt;em&gt;base&lt;/em&gt;&#39; element from the bottom of the &#39;&lt;em&gt;base&lt;/em&gt;&#39; element.&lt;/p&gt;
&lt;p&gt;Similarly, the &#39;&lt;em&gt;left&lt;/em&gt;&#39; property will offset the &#39;&lt;em&gt;indicator&lt;/em&gt;&#39; element by 60% of the width of the &#39;&lt;em&gt;base&lt;/em&gt;&#39; element from the left of the &#39;&lt;em&gt;base&lt;/em&gt;&#39; element.&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7r3um4t3cdzle5esi3sg.png&quot; alt=&quot;result&quot; height=&quot;390&quot; width=&quot;775&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;p&gt;Next, we will add a border having the color same as the &#39;&lt;em&gt;body&lt;/em&gt;&#39; element having a border-radius of 50%.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.indicator&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    right: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    left: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: brown;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we will style the notification counter.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.noti_count&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-family: &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Montserrat&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Lucida Sans Unicode&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Lucida Grande&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#98C379&quot;&gt;&#39;Lucida Sans&#39;&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;Arial&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    color: aliceblue;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    font-weight: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;700&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to center the notification count number, we can add &#39;&lt;em&gt;flex&lt;/em&gt;&#39; properties to its parent element.&lt;/p&gt;
&lt;pre class=&quot;shiki one-dark-pro&quot; style=&quot;background-color:#282c34;color:#abb2bf&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;.indicator&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    position: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    top: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    right: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    left: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    bottom: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    background-color: brown;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#56B6C2&quot;&gt; rgb&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;51&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    border-radius: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E06C75&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    display: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    justify-content: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;    align-items: &lt;/span&gt;&lt;span style=&quot;color:#D19A66&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ABB2BF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final output will be:&lt;/p&gt;
&lt;figure&gt;&lt;picture&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1c8qilqsqbzzhb45ish1.png&quot; alt=&quot;final output&quot; height=&quot;358&quot; width=&quot;802&quot; /&gt;&lt;/picture&gt;&lt;/figure&gt;
&lt;div class=&quot;note-block&quot;&gt;
    &lt;p class=&quot;indicator-container&quot;&gt;&lt;svg class=&quot;indicator&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;36&quot; height=&quot;36&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;path d=&quot;M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/3XM6pC9&quot;&gt;https://amzn.to/3XM6pC9&lt;/a&gt;
&lt;a href=&quot;https://amzn.to/49B9ufJ&quot;&gt;https://amzn.to/49B9ufJ&lt;/a&gt;
&lt;a href=&quot;https://amzn.to/4po0j6J&quot;&gt;https://amzn.to/4po0j6J&lt;/a&gt;
&lt;a href=&quot;https://amzn.to/4ogZAU9&quot;&gt;https://amzn.to/4ogZAU9&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;blockquote data-pagefind-ignore=&quot;&quot;&gt;
&lt;p&gt;&lt;em&gt;This post was originally published in &lt;a href=&quot;https://dev.to/murtuzaalisurti/how-to-create-a-notification-badge-with-css-only-2nf8&quot;&gt;dev.to&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;margin-top: 2rem;&quot;&gt;&lt;i&gt;This post was originally published in &lt;a href=&quot;https://syntackle.com/blog/how-to-create-a-notification-badge-with-css-WrkjgwxkL5bw-mFwMFjl/&quot;&gt;Syntackle&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;</content>
  </entry>
</feed>