<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Filip Kudla</title>
    <description>The latest articles on Forem by Filip Kudla (@filip_kudla).</description>
    <link>https://forem.com/filip_kudla</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102121%2F36b68ac4-dc42-4489-a4c2-a1a761a72f5a.png</url>
      <title>Forem: Filip Kudla</title>
      <link>https://forem.com/filip_kudla</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/filip_kudla"/>
    <language>en</language>
    <item>
      <title>3 layers of nextjs prefetch</title>
      <dc:creator>Filip Kudla</dc:creator>
      <pubDate>Mon, 17 Feb 2025 00:03:49 +0000</pubDate>
      <link>https://forem.com/filip_kudla/3-layers-of-nextjs-prefetch-38lm</link>
      <guid>https://forem.com/filip_kudla/3-layers-of-nextjs-prefetch-38lm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This post is sponsored by next.js... but in a bit different way. After spending a few hours connecting the right dots right after shipping the middleware feature on production and quick rollback 😬&lt;/p&gt;

&lt;p&gt;Don't know about most of the devs but for me, it was a "shocker". Our service throughput skyrocketed right after my initial merge. It was about a 2x or 3x increase. Simply caused by the middleware file.&lt;/p&gt;

&lt;p&gt;There is a gotcha that I want to mention at the very beginning of this article. Such "issues" are available on &lt;strong&gt;production app build only&lt;/strong&gt;. I mean link prefetch "feature" in the &lt;strong&gt;next v14 pages router&lt;/strong&gt;. It's a bit cumbersome and good to know ahead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftk1sao9ptm9z6ngqqqt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftk1sao9ptm9z6ngqqqt1.png" alt="dummy chart to present release" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;just to visualize this for you - you don't need to thank&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Layer 1 - Link prefetch
&lt;/h2&gt;

&lt;p&gt;I will call it a beginner-level prefetch.&lt;/p&gt;

&lt;p&gt;One of the &lt;a href="https://nextjs.org/docs/pages/api-reference/components/link#prefetch" rel="noopener noreferrer"&gt;Link properties is &lt;code&gt;prefetch&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can create a simple wrapper around the &lt;code&gt;Link&lt;/code&gt; component, such as a &lt;code&gt;CustomLink,&lt;/code&gt; and opt out of this behaviour. The whole logic is to set &lt;code&gt;prefetch: false&lt;/code&gt; as the default value in your component and then replace all usage of default &lt;code&gt;Link&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from 'next/link'

export const CustomLink = ({prefetch = false, ...props}) =&amp;gt; {
  return (
    &amp;lt;Link
      prefetch={prefetch}
      {...props}
    /&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not all! A different behaviour depends on whether you use the &lt;code&gt;app&lt;/code&gt; or &lt;code&gt;pages&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/pages/api-reference/components/link#prefetch" rel="noopener noreferrer"&gt;For &lt;code&gt;pages&lt;/code&gt; routing&lt;/a&gt; &lt;code&gt;prefetch&lt;/code&gt; has a &lt;code&gt;true&lt;/code&gt; value by default in next v15. Setting to false will work fine but there is one more disclaimer. Prefetch behaviour on hover can't be disabled with &lt;code&gt;next/link&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Of course, you can use the native &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag to disable prefetching completely but this will work only for external links.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/app/api-reference/components/link#prefetch" rel="noopener noreferrer"&gt;For &lt;code&gt;app&lt;/code&gt; directory&lt;/a&gt; routing we have a &lt;code&gt;null&lt;/code&gt; value by default.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Again, this might be outdated pretty fast so make sure to check the official docs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Layer 2 - Middleware
&lt;/h2&gt;

&lt;p&gt;I have found another place where you can minimize the middleware prefetch requests to the server. In middleware configuration itself!&lt;/p&gt;

&lt;p&gt;There is a great &lt;a href="https://nextjs.org/docs/pages/building-your-application/routing/middleware#matcher" rel="noopener noreferrer"&gt;matcher&lt;/a&gt; feature where we can exclude requests with prefetch headers. Let's consider the code snippet below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;source:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;missing:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"purpose"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prefetch"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation step-by-step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Note that Regexp is a negation&lt;/li&gt;
&lt;li&gt;It will work for not listed potential routes such as our pages&lt;/li&gt;
&lt;li&gt;Normally it would match both prefetch and non-prefetch requests but we have added a requirement to match only those without a "prefetch" header.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This would work just fine, except for one more case - prefetch on hover. If you are fine with it you can probably pause here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ultimate layer 3 - experimental &lt;code&gt;middlewarePrefetch&lt;/code&gt; flag
&lt;/h2&gt;

&lt;p&gt;You might wonder - why it's not just optional to prefetch, right? Well, you can but we need a closer look into the source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/pull/42936" rel="noopener noreferrer"&gt;https://github.com/vercel/next.js/pull/42936&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Middleware comes with 2 prefetch options - &lt;code&gt;strict&lt;/code&gt; and &lt;code&gt;flexible&lt;/code&gt;. The second one is set by default and it "always prefetches". While the first one prefetches only "when the href explicitly matches an SSG route" which should be fine to prefetch the static generated sites.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You have completely disabled prefetches if you are still using &lt;code&gt;getInitialProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: If you have just a few static sites, you probably don't need to configure 2nd option to exclude prefetches. It shouldn't generate a big load on your servers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why does it generate all the load on our server
&lt;/h2&gt;

&lt;p&gt;The answer is simple, with the &lt;code&gt;middleware&lt;/code&gt; file we were running additional operations for ALL our requests like images, prefetches and pages which are treated as additional load. This takes time and resources so our application will scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Big unknown
&lt;/h2&gt;

&lt;p&gt;I couldn't understand why prefetch is not happening when you are not using nextjs middleware file. Without it, it's completely normal behaviour. Looks like &lt;code&gt;middleware&lt;/code&gt; is directly connected with this feature and mentioned load from the previous point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;There it is. 3 layers to avoid prefetch while using middleware. I can say that you might live with the 2nd option without any issues but it's also good to know how to completely shut down "prefetch".&lt;/p&gt;

&lt;p&gt;Also, I can see the 3rd layer as part of the docs. I need to think about some PR for that 👀 &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Thoughts on CSS-in-JS and Utility-First CSS (Tailwind)</title>
      <dc:creator>Filip Kudla</dc:creator>
      <pubDate>Sun, 26 Jan 2025 00:23:29 +0000</pubDate>
      <link>https://forem.com/filip_kudla/thoughts-on-css-in-js-and-utility-first-css-tailwind-159p</link>
      <guid>https://forem.com/filip_kudla/thoughts-on-css-in-js-and-utility-first-css-tailwind-159p</guid>
      <description>&lt;p&gt;Recently I have had a chance to create UI a little in my work due to assessments that we run in our company. I haven't done this for a long time and apparently missed a lot.&lt;/p&gt;

&lt;p&gt;I admit that I don't touch UI often in my daily work (now you might wonder what do I do in my job then 🤫). Plus I don't get that excited about writing some CSS styles, it is not my cup of tea.&lt;/p&gt;

&lt;p&gt;In such a case, that was a ride, and I thought my opinion would stay as close to neutral as it could be (seriously). After using both again, one after another, in the same application, I can definitely share my few thoughts on this topic. I will skip the part about what we have achieved in our working group and focus on styling experience and tooling for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind
&lt;/h2&gt;

&lt;p&gt;Deciding on tailwind came a bit out of nowhere. We all were more or less familiar with it, more or less sceptical but we wanted to save our time on writing stuff.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small things matter
&lt;/h3&gt;

&lt;p&gt;The integration part, along with creating custom variables and themes, was fast enough. Extending or building a new theme is very intuitive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="py"&gt;--font-script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Comic-sans&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;extending&lt;/span&gt; &lt;span class="err"&gt;theme&lt;/span&gt;
  &lt;span class="err"&gt;--color-*:&lt;/span&gt; &lt;span class="err"&gt;initial;&lt;/span&gt;  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;overwriting&lt;/span&gt; &lt;span class="err"&gt;defaults&lt;/span&gt;
  &lt;span class="py"&gt;--color-white&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, I love it when tools have some base styles defined. Even simply disabling native margins and padding is huge. It just saves precious time and we have one problem less!&lt;/p&gt;

&lt;p&gt;Feeling intuitive in our own stylesheets assures our flow and pushes us to keep progressing. Tailwind wants to be intuitive. It works sometimes... and sometimes not really. Take class namings. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;p&lt;/code&gt; for padding and &lt;code&gt;mb&lt;/code&gt; for margin-bottom - great! &lt;/p&gt;

&lt;p&gt;For &lt;code&gt;display&lt;/code&gt; values I would prefer &lt;code&gt;display-flex&lt;/code&gt;, &lt;code&gt;display-block&lt;/code&gt; etc. instead just &lt;code&gt;flex&lt;/code&gt; and &lt;code&gt;block&lt;/code&gt;. It's probably connected to other flexbox and grid properties. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;rounded&lt;/code&gt; for &lt;code&gt;border-radius&lt;/code&gt; 🤨... If you can't remember it as me. We can create a small theme twig in our theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="py"&gt;--border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--rounded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--border-radius-none&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--rounded-none&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--border-radius-full&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--rounded-full&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;...and&lt;/span&gt; &lt;span class="err"&gt;so&lt;/span&gt; &lt;span class="err"&gt;on&lt;/span&gt;
  &lt;span class="err"&gt;--rounded*:&lt;/span&gt; &lt;span class="err"&gt;initial;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Personal feelings
&lt;/h3&gt;

&lt;p&gt;Readability is not as problematic as many people think. The same applies to maintainability and scalability. However, it required some time to get used to the syntax, and VsCode IntelliSense was a little too slow for me to hint proper class 😅. The code itself grows pretty well. Stays readable even with a few lines of classes for small piece of code. It's pretty easy to find what I want and edit it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important note: Don't think about using &lt;code&gt;@apply&lt;/code&gt; too fast. You can end up with Tailwind-in-CSS 😐&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Server side
&lt;/h3&gt;

&lt;p&gt;By the way, no issues during my entire experience for our testing phase for SSR. Important factor! You can just start using it and it just works. I don't even have anything more to say there 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS-in-JS (emotion)
&lt;/h2&gt;

&lt;p&gt;Let's agree it's rather a twilight of such solutions in 2024 and 2025. Of course, this is connected with the react trend for using server components and all that.&lt;/p&gt;

&lt;p&gt;See this link: &lt;a href="https://nextjs.org/docs/app/building-your-application/styling/css-in-js" rel="noopener noreferrer"&gt;https://nextjs.org/docs/app/building-your-application/styling/css-in-js&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Underlying issue
&lt;/h3&gt;

&lt;p&gt;It's probably the biggest issue nowadays, even though those were very popular tools. Most developers are looking for other solutions to avoid creating tech debt and move forward.&lt;/p&gt;

&lt;p&gt;As CSS-in-JS relies heavily on React Context API and now your react app might have a mix of server components inside "client components" it simply loses its data and possibility to modify styles on rerender correctly. It is impossible to achieve with the same library 😞&lt;/p&gt;

&lt;p&gt;Don't worry, there are compatible CSS-in-JS alternative libraries! &lt;/p&gt;

&lt;p&gt;To understand the full context behind this problem, I recommend checking &lt;a href="https://www.joshwcomeau.com/react/css-in-rsc/" rel="noopener noreferrer"&gt;this article from Joshua Comeau&lt;/a&gt;. It is always worth checking his blog posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looking back
&lt;/h3&gt;

&lt;p&gt;Not sure if it deserved that amount of attention after I look back. After all, I regret shifting everything to JS in my apps. &lt;/p&gt;

&lt;p&gt;We can agree on at least one thing there - they gave a decent developer experience (aka a lazy developer's experience) as we don't need to switch context that much. Everything can stay even within one file (I'm looking at you tailwind 👀). We loved that concept and that concept lost us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Experience and long-term vision
&lt;/h3&gt;

&lt;p&gt;It turns out that you have to do a lot of typing with that solution! And it comes together with configuration effort (btw. not only during project bootstrap). It felt way less grateful compared to Tailwind.&lt;/p&gt;

&lt;p&gt;I still very much like the possibility of passing conditional props and all the power related to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ddd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Primary&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Side note it probably complicates more than helps for example in understanding the final syntax and potential refactor tho.&lt;/p&gt;

&lt;p&gt;Speaking about refactoring it must be a real curse when you have used style overwriting too much. Plus it might be a sign for you and your designer. Example syntax below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-design-system-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyFunnyButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  margin-bottom: 3px; // 3px, really?! don't do that :')
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something to revisit and fix at the source. Design systems should be consistent and overwrites shouldn't be needed for atom components.&lt;/p&gt;

&lt;p&gt;If I had to bootstrap a new project now, honestly I would pass this solution.&lt;/p&gt;

&lt;h1&gt;
  
  
  Variables and theming
&lt;/h1&gt;

&lt;p&gt;CSS variables are probably one of the greatest things available to me. Defining a palette once and reusing it across all components is almost like selecting a predefined component variant by prop. Import one file with a project theme variables and I'm ready to go (with a small cheatsheet at the beginning ofc.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--main-bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--secondary-bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--alternative-bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Hussle with postprocessors and additional configs
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Postprocessors are plugins that run after generating your CSS file with a bundler and help optimise it. A good example could be the PostCSS tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you run your project without adding any CSS postprocessors or configs? Just a barebone CSS file? You did? You must be crazy or lazy 😒&lt;/p&gt;

&lt;p&gt;Well, I wasn't able to run &lt;em&gt;anything&lt;/em&gt; without them. It unlocks a lot of benefits. We can name a few now from PostCSS tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cssnano which deletes unused code, &lt;/li&gt;
&lt;li&gt;nested plugin to allow using nesting similar to sass project,&lt;/li&gt;
&lt;li&gt;stylelint... self-explanatory one&lt;/li&gt;
&lt;li&gt;autoprefixer so you don't need to worry about it (not that relevant nowadays but still worth using)&lt;/li&gt;
&lt;li&gt;import which allows to use &lt;code&gt;@import&lt;/code&gt; rule like the one known from JS files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I got your interest, the full list is available here: &lt;a href="https://postcss.org/docs/postcss-plugins" rel="noopener noreferrer"&gt;https://postcss.org/docs/postcss-plugins&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, I'm considering it as a slowdown to the project and baggage to maintain. We are making a trade with ourselves to invest some time now and get better developer experience together with good stylesheet performance.&lt;/p&gt;

&lt;p&gt;Imagine having all those autoprefixes, dead code elimination and modification out of the box without adding a single line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lightning CSS
&lt;/h2&gt;

&lt;p&gt;The feeling I have mentioned is potentially the goal of another tool. &lt;a href="https://lightningcss.dev/docs.html" rel="noopener noreferrer"&gt;Lightning CSS&lt;/a&gt;. Yes, it's in Rust 🙄 but more about that trend in another blog post.&lt;/p&gt;

&lt;p&gt;Anyway, if you are looking for a well-packed alternative to PostCSS with improved build times, you should take a look at this tool.&lt;/p&gt;

&lt;p&gt;Most necessary tools are included and configurable like vendor prefixes, nesting, source maps, modifications, browser targets and modern CSS syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;It's great to see changes happening in CSS tools and an even more bright future with CSS tools with RSC support (at least for some of them). My overall experience with these tools was more or less accurate. I haven't completely lost touch with them and it was very easy to come back which is positive!&lt;/p&gt;

&lt;p&gt;If you think about it. This new approach makes a big impact. We needed to consider this even in CSS-related blog posts. This will impact our future toolset for projects as well. Is it a bad thing? There is only one way to figure this out 😌&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Observability (o11y) purpose</title>
      <dc:creator>Filip Kudla</dc:creator>
      <pubDate>Wed, 25 Dec 2024 00:39:15 +0000</pubDate>
      <link>https://forem.com/filip_kudla/observability-o11y-purpose-5g4e</link>
      <guid>https://forem.com/filip_kudla/observability-o11y-purpose-5g4e</guid>
      <description>&lt;h2&gt;
  
  
  Warmup
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Introduction&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine you set a goal in your life to be at the Olympics. You are not yet sure why but let’s see how it goes. Of course, you also have prepared a plan B to just show up at your local gym at least once a week. &lt;/p&gt;

&lt;p&gt;Remember what managers repeat - Goals should be ambitious and realistic. We take the second part seriously 😇&lt;/p&gt;

&lt;p&gt;Anyway, you have started training regularly. Over time you are introducing little tweaks into your life here and there. You think it should improve or at least help in your initial goal. After some time, you have got that weird feeling. Something is wrong. Even if you are doing workouts regularly. What did we miss?&lt;/p&gt;

&lt;h2&gt;
  
  
  Step back
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Context&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It appears that we forgot about almost, well… everything 😅&lt;/p&gt;

&lt;p&gt;Speaking in programming language for a moment - our app is live… but that’s it.&lt;/p&gt;

&lt;p&gt;Let me show you a few areas that we have missed. &lt;/p&gt;

&lt;p&gt;We didn’t track anything. As youngsters say - pics or didn't happen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We don’t know if we can do more repeats over time or if we can increase the weights (metrics and monitoring - this post focus by the way). &lt;/li&gt;
&lt;li&gt;We don’t track our progress with some note or gym app (logs and perf budgets) &lt;/li&gt;
&lt;li&gt;We don’t know about our potential mistakes during workouts. We are doing exercises as we see them. Yes, we have a &lt;strong&gt;big&lt;/strong&gt; imagination (error monitoring/tracking).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also a few more but I’m out of analogies for now.&lt;/p&gt;

&lt;p&gt;Basically, you just go there. I’m not even sure if you were training or just staring at your phone the whole time. Did you? 🤨&lt;/p&gt;

&lt;h2&gt;
  
  
  marathon
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;historical data&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we want to survive, we have to analyze. This knowledge can be crucial if we want to head into the right direction. Historical data for the rescue!&lt;/p&gt;

&lt;p&gt;How are you going to validate your training plan? &lt;/p&gt;

&lt;p&gt;I would start with workout notes (there are apps for that already, you don’t need another side project 😒). Eventually “flex” image from the gym can work as well. Regular weight checks are a must-have. &lt;/p&gt;

&lt;p&gt;This unlocks better observations. It works the same way with our application. We can compare metrics, set milestones and make long-term predictions, plans and analyses.&lt;/p&gt;

&lt;p&gt;It’s a common concept to set alert conditions when some part is crucial for you. Like setting a clock to avoid sleeping through. On the other hand, you can observe your heartbeat during a workout same as you would set up some dashboards with base metrics.&lt;/p&gt;

&lt;p&gt;Usually, you have some industry standards set up that are represented by metrics. You want to follow them and keep them within your scope of interests. Web vitals metrics are a good example there. The same goes for the gym world with different techniques available and just a few of them might interest you depending on what is your goal.&lt;/p&gt;

&lt;p&gt;In the end, you build good habits around the workout. It’s healthier, motivating and productive. Over time you can introduce your custom metrics if we build strong ground level.&lt;/p&gt;

&lt;h2&gt;
  
  
  our pace
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;metrics&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have mentioned metrics. I meant that we can develop our tailored area of interest. We can depend on delivered statistics to define our condition and crossbar level.&lt;/p&gt;

&lt;p&gt;After first failures and regrets, we can also define our border lines that we shouldn't cross. We can agree with ourselves that we will go to the gym at least twice a week (our SLA - Service Level Agreement here). Usually, it's also a good habit to define a penalty for crossing this line and tell somebody about it so we can convince ourselves to respect it. In job, it’s usually our stakeholder or customer.&lt;/p&gt;

&lt;p&gt;In general, we can agree on some error degree per month for our application. Otherwise, you have to reconsider the problem and follow it to the root. This should be defined clearly for everyone. SLOs (service-level objectives) come in handy for that.&lt;/p&gt;

&lt;p&gt;For example, we expect to train for at least 1 hour per visit 80% of the time during the last month. In other words, we agree that some of our training can be short due to unknown circumstances.&lt;/p&gt;

&lt;p&gt;Or we declare to do a full body workout once a month and focus on different body parts (up to 2) every other workout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvement plans
&lt;/h2&gt;

&lt;p&gt;Based on the historical data that you were able to collect you should rethink if it's worth going there in your case. I mean you &lt;strong&gt;really&lt;/strong&gt; rock this Candy Crush saga game between exercises but after a few months, you should be able to do more than 5 push-ups 😒&lt;/p&gt;

&lt;p&gt;Jokes aside you should probably consider defining some budget for your app. For example, you want to keep (or reach) your app on the green zone score for &lt;a href="https://web.dev/articles/cls" rel="noopener noreferrer"&gt;CLS&lt;/a&gt; value based on webvital report. &lt;/p&gt;

&lt;p&gt;With such information, you can plan to improve that value in the next quarter. This can include investigation, planning&amp;amp;consultation and implementation part. After introducing improvements you can revisit your stats again and verify the results. By the way - great OKR example!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2up95iyq74bzjo3w8dw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2up95iyq74bzjo3w8dw1.png" alt="cls-values" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;source: &lt;a href="https://web.dev/articles/cls" rel="noopener noreferrer"&gt;https://web.dev/articles/cls&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Is profiling and performance measurements still an observability part?
&lt;/h3&gt;

&lt;p&gt;I would say it's the same area of interest with a different scope. Usually, we want to observe some metrics constantly. This allows us to compare results from the past. Profiling is usually used to find other kinds of problems with application tasks or registered processes/tasks. &lt;/p&gt;

&lt;p&gt;Usually, running &lt;code&gt;perf&lt;/code&gt; profiling on production is expensive in terms of resources used. The impact on our app might be noticeable, so make sure you run it only on a small subset of your production. One or a few application pods should be enough data for you.&lt;/p&gt;

&lt;p&gt;On the other hand performance measurements can probably be partially automated and collect metrics periodically. &lt;/p&gt;

&lt;p&gt;To know which one to choose we need to know how low-level our problem is. Performance tests should address some more generic purpose while profiling can help investigate certain problems and find root causes instead. The most generic example would be increased memory usage over time. Most of the time it's caused by a bug on our end.&lt;/p&gt;

&lt;p&gt;It's good to think about the &lt;code&gt;perf&lt;/code&gt; layer after your app has other more common observability data already available. Not a first line of debugging problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does observability help in the team's work?
&lt;/h3&gt;

&lt;p&gt;Of course, we need to assume that the data we collect is valuable for us. Universal example - collecting production errors.&lt;/p&gt;

&lt;p&gt;After we release our code on production we should be promptly informed that something is wrong. With data in hand, the team can take action. For example, rollback and prepare a fix, notify others about problems or both 😃&lt;/p&gt;

&lt;p&gt;The same goes for any other data and applies to various angles of help. Based on that, we can plan, make decisions and build the next iterations. It is like building a foundation.&lt;/p&gt;

&lt;p&gt;It took me a while to make a decent analogy for that. I came up with this one for now. &lt;/p&gt;

&lt;p&gt;It can be understood as another good habit for a healthier life. At the same time, a healthy life is built from many small chunks. One is our diet another is workout consistency, our routine, nature and even motivation. We can get the best and fastest results when we put everything together. We can notice very quickly if something gets off-track.&lt;/p&gt;

&lt;h2&gt;
  
  
  shared responsibility
&lt;/h2&gt;

&lt;p&gt;Allowing others to check what's up with our app can be very beneficial. This can enable us to delegate stuff outside instead of making every improvement ourselves. With such an approach, we maintain a clear and healthy responsibility split. Everybody can gain from it. Let's try with analogy to this part. &lt;/p&gt;

&lt;p&gt;Certain exercises will target selected muscles or one part of the body. Also, we can't do only one exercise for a whole training and expect different results. It's good to plan what we will do in the gym and use the proper tools/exercises to target our goal. We could do everything alone but a coach can introduce us way faster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Coach can be understood in two ways. One is a dedicated observability team that can support you when you need anything. Second, is a custom dashboard which can keep team-scoped queries in one place.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you have an observability team in your organization, it can work way better. They should provide the feedback you need for the things you want. Cooperation with such teams can lead only to good outcomes. Sharing knowledge with them is paying back in the long term as more people will learn and observe the app.&lt;/p&gt;

&lt;p&gt;There is another side of the coin tho. Don't try to store too much data in your dashboards. Otherwise, you can lose your service visibility and don't know what is going on when you observe "too much".&lt;/p&gt;

&lt;p&gt;Of course, "too much" is a very generic term. Dashboards should suggest which part is worth debugging and be informative instead scream at you that something is on fire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nyx9vivh21u0ynuq2lj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nyx9vivh21u0ynuq2lj.png" alt="this is fine meme" width="500" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finish… or just a beginning
&lt;/h2&gt;

&lt;p&gt;We have briefly touched on the observability topic. A bit unusual way. At least I hope it was original.&lt;/p&gt;

&lt;p&gt;Quick recap! I have tried to present the main observability topics there. Those can be treated as our signs of discovery. We should know where to head next.&lt;/p&gt;

&lt;p&gt;I hope I will describe some topics more and better in future posts. Especially the part about shared responsibility, example data to track/not track and how to avoid noise in the dashboards.&lt;br&gt;
Who knows, maybe even with extended technical coverage and fewer analogies. It depends on my creativity 🤞 For now, let me know if such a format is readable.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>programming</category>
      <category>observability</category>
      <category>platform</category>
    </item>
    <item>
      <title>SVG hacks for you</title>
      <dc:creator>Filip Kudla</dc:creator>
      <pubDate>Sun, 22 Dec 2024 00:26:19 +0000</pubDate>
      <link>https://forem.com/filip_kudla/svg-hacks-for-you-2nl5</link>
      <guid>https://forem.com/filip_kudla/svg-hacks-for-you-2nl5</guid>
      <description>&lt;p&gt;I got motivated by &lt;a href="https://bytes.dev/archives/293" rel="noopener noreferrer"&gt;Bytes #293&lt;/a&gt; main thing about HTML. Their motivation came from &lt;a href="https://2023.stateofhtml.com/en-US/" rel="noopener noreferrer"&gt;State of HTML 2023&lt;/a&gt; survey (and money... but let's leave the sponsored section from mailing).&lt;/p&gt;

&lt;p&gt;It appears that &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; elements are notable pain points in their daily work. It was brought in the &lt;a href="https://2023.stateofhtml.com/en-US/features/content/#content_pain_points" rel="noopener noreferrer"&gt;"Content section"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddc4ohzme0e1xboj7uhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddc4ohzme0e1xboj7uhp.png" alt="content section with 17% of svg answers (top)" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Entry point
&lt;/h1&gt;

&lt;p&gt;If you are not familiar with this stuff at all, I can help with a bunch of links for the start. After that, nothing will change but you will know something more about &lt;code&gt;svg&lt;/code&gt; &lt;br&gt;
&lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Introduction" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SVG tutorial from MDN: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Getting_Started" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Getting_Started&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tl;DR&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;SVG elements are vector graphic elements. This can be understood as a bunch of geometric figures represented in characters. You can create one for example with Adobe Illustrator or Inkscape as a free alternative.&lt;/p&gt;
&lt;h1&gt;
  
  
  Starting point
&lt;/h1&gt;

&lt;p&gt;From people's answers, we can see a few patterns. I won't pick any specific one but I will try to share some knowledge around those topics so you can find here some tips&amp;amp;tricks, sharing experience and other common knowledge around this topic.&lt;/p&gt;

&lt;p&gt;I will skip the SVG sprites topic &lt;a href="https://miro.medium.com/v2/resize:fit:1400/1*fSaamZRQfHeq_SxdqIfNkg.png" rel="noopener noreferrer"&gt;like this example&lt;/a&gt;. It's a separate topic and is not very connected to the &lt;code&gt;svg&lt;/code&gt; tag. I can just agree that you could still find a few rare use cases for them.&lt;/p&gt;
&lt;h2&gt;
  
  
  File syntax
&lt;/h2&gt;

&lt;p&gt;A proper SVG file should be a representation of the mentioned geometric figures. It's very easy to check if our icon is prepared in the right format by the designer or website where you are taking it.&lt;/p&gt;

&lt;p&gt;Wrong example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;image&lt;/span&gt; &lt;span class="na"&gt;link:href=&lt;/span&gt;&lt;span class="s"&gt;"data:image/png;base64 .../&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&amp;lt;g&amp;gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;circle&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During my career, I stepped into this a few times. It's worth to remember that. It happens when you take raster graphics, import them to a vector graphic program and try to export them in &lt;code&gt;.svg&lt;/code&gt; extension. It does not magically convert your image to a vector graphic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notable SVG tags
&lt;/h2&gt;

&lt;p&gt;I can present you a cheat sheet for most generic svg elements.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tag&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Animated attributes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;g&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;used for grouping elements&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;path /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;main tag for your actual icon. Avoid modifying the &lt;code&gt;d=""&lt;/code&gt; attribute on your own 😬 It is possible but be careful with that. &lt;a href="https://www.w3schools.com/graphics/svg_path.asp" rel="noopener noreferrer"&gt;Grab a link&lt;/a&gt; with an explanation for each character group. To animate your path use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateMotion" rel="noopener noreferrer"&gt;animateMotion&lt;/a&gt; tag&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;rect /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Basic rectangle shape in SVG. Simple as that&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;line /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Simple as that. The line between two points. Don't mistake with the &lt;code&gt;stroke&lt;/code&gt; attribute! It can also be used on the line tag.&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;defs /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;You can think about it as an enhancement version of the &lt;code&gt;g&lt;/code&gt; tag but it keeps the elements inside invisible for later use with, let's guess it... &lt;code&gt;use&lt;/code&gt; tag&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;circle /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Next basic shape. Be careful as the size is defined by radius and you position your circle with &lt;code&gt;cx&lt;/code&gt; and &lt;code&gt;cy&lt;/code&gt; attributes.&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;polygon /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Let's call it a custom shape. They are connected straight lines where the last point connects to the first point.&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;polyline /&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Very similar to the previous one but with a notable difference. The last point doesn't need to be connected to the first point.&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Please note those are only a few selected SVG elements. I have just described the most common ones. There are a lot more available for you to use. A full list can be found &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sizing and positioning
&lt;/h2&gt;

&lt;p&gt;As we are now familiar with some of the common svg tags we can go into the next paragraph of modifying the base parameters of our icon.&lt;/p&gt;

&lt;p&gt;Let's say we work with a young designer. He/She doesn't fully know how to prepare things for the web yet as you do. As a result, you sometimes get slightly different sizes of an icon with missing cut padding on the sides.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;good one&lt;/th&gt;
&lt;th&gt;wrong one&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbbount7oxbdi8pllwg5k.png" alt="Image description" width="412" height="498"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfnxuvixe31xw15ilto7.png" alt="Image description" width="400" height="352"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Classic case. I know we should have a quick call with a designer and clarify this but we want to learn some svg here. We are not doing that in this scenario. We can fix it ourselves.&lt;/p&gt;

&lt;p&gt;From the code perspective, it's all about attributes. The original SVG cross file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Created with Inkscape (http://www.inkscape.org/) --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt;
   &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"93.582886"&lt;/span&gt;
   &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"93.582893"&lt;/span&gt;
   &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24.760471 24.760474"&lt;/span&gt;
   &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.1"&lt;/span&gt;
   &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"svg1"&lt;/span&gt;
   &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:svg=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;defs&lt;/span&gt;
     &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"defs1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;g&lt;/span&gt;
     &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"layer1"&lt;/span&gt;
     &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"translate(-13.964461,-14.49055)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;rect&lt;/span&gt;
       &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline;fill:#000000;stroke-width:0.257843"&lt;/span&gt;
       &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"rect2"&lt;/span&gt;
       &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"31.409456"&lt;/span&gt;
       &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3.175"&lt;/span&gt;
       &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"-16.658115"&lt;/span&gt;
       &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"36.031288"&lt;/span&gt;
       &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"rotate(-45.885349)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;rect&lt;/span&gt;
       &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline;fill:#000000;stroke-width:0.257843"&lt;/span&gt;
       &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"rect3"&lt;/span&gt;
       &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"31.409456"&lt;/span&gt;
       &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"3.175"&lt;/span&gt;
       &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"21.914061"&lt;/span&gt;
       &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"-0.63411272"&lt;/span&gt;
       &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"rotate(44.114651)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/g&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is our raw svg exported from Inkscape. There are a few other things to fix, bear with me so we can fix them.&lt;/p&gt;

&lt;p&gt;We know that 200px image is our goal. Here we have some ugly width/height values on the main svg tag.&lt;/p&gt;

&lt;p&gt;Simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;svg
&lt;span class="gd"&gt;-   width="93.582886"
&lt;/span&gt;&lt;span class="gi"&gt;+   width="200"
&lt;/span&gt;&lt;span class="gd"&gt;-   height="93.582893"
&lt;/span&gt;&lt;span class="gi"&gt;+   height="200"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F901jgt6yk7fqymepl7u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F901jgt6yk7fqymepl7u8.png" alt="Image description" width="438" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost what we want! Let's dig further into how we can preserve padding as in the first icon.&lt;/p&gt;

&lt;p&gt;We have 2 options. We can keep the same &lt;code&gt;viewBox&lt;/code&gt; value or we can adjust each &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; value on every nested tag.&lt;/p&gt;

&lt;p&gt;The first option seems simple and it works for us quite well but there might be a catch. In my case, I had this weird &lt;code&gt;transform&lt;/code&gt; attribute on my group tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;g&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"layer1"&lt;/span&gt; &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"translate(-13.964461,-14.49055)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After removing it the result is pretty good now:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;step1 - add &lt;code&gt;viewBox&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;step2 - remove &lt;code&gt;transform&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jxze0yi2kab3jizb9ep.png" alt="Image description" width="440" height="488"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yll6aqzdtqrom8ieslx.png" alt="Image description" width="416" height="478"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Universal width/height
&lt;/h2&gt;

&lt;p&gt;We don't need to define width and height upfront to our icon. We can avoid overwriting it each time from 200px to 32px - let's treat it as an implementation detail. In that case, we can update our icon as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;svg
&lt;span class="gd"&gt;-   width="200"
-   height="200"
&lt;/span&gt;    viewBox="0 0 50 50"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our icon size is adjustable. Please note that it's vector graphics so we don't lose icon quality after resizing.&lt;/p&gt;

&lt;p&gt;So why is &lt;code&gt;viewBox&lt;/code&gt; so important?&lt;/p&gt;

&lt;p&gt;It's the key when we want to correctly scale or set a certain position to our icon. It has 4 arguments &lt;code&gt;viewBox="min-x min-y width height"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, viewBox="0 0 100 100" means the top-left corner is at (0, 0) and the viewBox is 100 units wide and 100 units high.&lt;/p&gt;

&lt;p&gt;That means you have to adjust your icon &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; attributes after changing &lt;code&gt;viewBox&lt;/code&gt; as they are set according to their value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing colors and fill
&lt;/h2&gt;

&lt;p&gt;Different icons allow different &lt;code&gt;fill&lt;/code&gt;. Of course, it can be as easy as adding a &lt;code&gt;color&lt;/code&gt; style but that's a rookie-level type of code.&lt;/p&gt;

&lt;p&gt;Real developers are adding &lt;code&gt;fill-rule="evenodd"&lt;/code&gt; to the main element and deleting all other manual &lt;code&gt;fill&lt;/code&gt; attributes from tags 😎&lt;/p&gt;

&lt;p&gt;You may wonder why.&lt;/p&gt;

&lt;p&gt;I will provide the shortest possible answer to this. To freely customize our icon colours with one line of code straight from our IDE.&lt;/p&gt;

&lt;p&gt;How is that possible you might ask.&lt;/p&gt;

&lt;p&gt;If you are dealing with a simple icon from your company's design system you should be able to import only one icon. Modifiers or duplications in size or colour are not necessary.&lt;/p&gt;

&lt;p&gt;From a code perspective, you just have to add &lt;code&gt;fill&lt;/code&gt; on the &lt;code&gt;svg&lt;/code&gt; element like you would normally do with for example colour attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="nf"&gt;#close&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a catch for &lt;code&gt;evenodd&lt;/code&gt; value which applies when you are drawing polygons or paths. It will fill only the inside of crossing path segments.&lt;/p&gt;

&lt;p&gt;Consider analyzing &lt;a href="https://developer.mozilla.org/en-US/play?id=1GVBn%2Ba2E49uDTm5grKGbhBN2woHE4ekdRzM368WaW8UHRg6m1MESjVkg1w5reu1EUK2si2vTRvETCf0" rel="noopener noreferrer"&gt;this example&lt;/a&gt; in case you struggle with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/play?id=1GVBn%2Ba2E49uDTm5grKGbhBN2woHE4ekdRzM368WaW8UHRg6m1MESjVkg1w5reu1EUK2si2vTRvETCf0" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Findt4gb46qo7jm5o6o7t.png" alt="Mozilla playground with polygon evenodd example" width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So in the case of our cross icon, it will result in something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgukhmjfg3oggutnrrm7a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgukhmjfg3oggutnrrm7a.gif" alt="demo with updated fill rule to evenodd value" width="394" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing
&lt;/h2&gt;

&lt;p&gt;Before we publish our icon to the web (or right after we download it from Figma) we should ensure it's properly optimized. This one is very important. I have caught and been caught way too many times during code review on this last mile. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://svgo.dev/" rel="noopener noreferrer"&gt;SVGO&lt;/a&gt; (or &lt;a href="https://react-svgr.com/" rel="noopener noreferrer"&gt;SVGR&lt;/a&gt; for react) is making it a very easy process. Behind the scenes, it mostly deletes all unnecessary stuff for us.&lt;/p&gt;

&lt;p&gt;In general, it is a go-to tool. Either you want to integrate it with your bundler or use it from CLI. It's ready to use right after installation as we get &lt;a href="https://svgo.dev/docs/preset-default/" rel="noopener noreferrer"&gt;default preset&lt;/a&gt; configured out of the box.&lt;/p&gt;

&lt;p&gt;Note: You can overwrite the default preset if you &lt;strong&gt;really want to&lt;/strong&gt;. Check &lt;a href="https://github.com/svg/svgo?tab=readme-ov-file#configuration" rel="noopener noreferrer"&gt;configuration in the project README&lt;/a&gt; and &lt;a href="https://svgo.dev/docs/plugins/" rel="noopener noreferrer"&gt;plugin list in docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;The final icon code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 50 50"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;g&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M9 24h32v3H9z"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline;stroke-width:.25"&lt;/span&gt; &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"rotate(135)"&lt;/span&gt; &lt;span class="na"&gt;transform-origin=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M8 24h32v3H8z"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline;stroke-width:.25"&lt;/span&gt; &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"rotate(45)"&lt;/span&gt; &lt;span class="na"&gt;transform-origin=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have reduced the size from 871 bytes with raw icon exported from inkspace to only 322 bytes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pain with animations
&lt;/h2&gt;

&lt;p&gt;The last topic that is bitter-sweet for me. It was brought in the survey answers a couple of times as well. I don't know better ways to do it except using &lt;a href="https://lottiefiles.com/" rel="noopener noreferrer"&gt;Lottie&lt;/a&gt; or manually animating elements of SVG in CSS. The second option is absolute torture when you have more than 5 elements to animate.&lt;/p&gt;

&lt;p&gt;Of course, it is possible and we can do it but being honest, there are more interesting things to do 🙈&lt;/p&gt;

&lt;p&gt;Suppose you are still curious about how to do it. I'm leaving a link to a great article &lt;a href="https://minus-ze.ro/posts/morphing-arbitrary-paths-in-svg/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It should convince you that it requires patience and takes more than 5 minutes. I wonder if an AI bot can help you with that! If yes, maybe it's a bit less painful.&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;br&gt;
Hopefully, you took something from this post and have a nice day 🍀&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
