<?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: Kristieene Knowles</title>
    <description>The latest articles on Forem by Kristieene Knowles (@webweaversworld).</description>
    <link>https://forem.com/webweaversworld</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%2F3788309%2Ff599fad3-a221-4c07-8b59-6049fc9a5ead.png</url>
      <title>Forem: Kristieene Knowles</title>
      <link>https://forem.com/webweaversworld</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/webweaversworld"/>
    <language>en</language>
    <item>
      <title>That Moment You See ‘Deleting…’ in Git Bash</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Wed, 04 Mar 2026 20:51:34 +0000</pubDate>
      <link>https://forem.com/webweaversworld/that-moment-you-see-deleting-in-git-bash-38a7</link>
      <guid>https://forem.com/webweaversworld/that-moment-you-see-deleting-in-git-bash-38a7</guid>
      <description>&lt;p&gt;The Fear of Using Git Bash Too Early in Your Dev Journey&lt;/p&gt;

&lt;p&gt;When I first started learning development about six months ago, Git Bash felt like stepping into a control room full of buttons I didn’t understand.&lt;/p&gt;

&lt;p&gt;I had connected Git to my local VS Code environment and thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Okay, this must be what developers use… I’ll just follow along.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem was that I didn’t actually understand the commands I was running.&lt;/p&gt;

&lt;p&gt;One day I ran a command in Git Bash and suddenly my terminal started printing lines that included words like “deleting”.&lt;/p&gt;

&lt;p&gt;My brain instantly went into panic mode.&lt;/p&gt;

&lt;p&gt;Not deleting in the repo.&lt;/p&gt;

&lt;p&gt;Deleting in my actual Windows file system.&lt;/p&gt;

&lt;p&gt;Inside my /htdocs/ folder.&lt;/p&gt;

&lt;p&gt;At that moment I realised something important about Git:&lt;/p&gt;

&lt;p&gt;Git is powerful — but if you don’t understand what a command does, it can be terrifying.&lt;/p&gt;

&lt;p&gt;I aborted the command as quickly as I could, but by then the damage had already started.&lt;/p&gt;

&lt;p&gt;For a few seconds I genuinely thought I had just lost my entire working project.&lt;/p&gt;

&lt;p&gt;Thankfully, I had a backup, so I restored everything and carried on.&lt;/p&gt;

&lt;p&gt;But that moment taught me two lessons that stuck with me.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 1 — Git Isn’t Dangerous, Ignorance Is
&lt;/h2&gt;

&lt;p&gt;Git commands can look intimidating because they operate at a very powerful level of your file system.&lt;/p&gt;

&lt;p&gt;When you see words like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reset&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;clean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…it feels like you're about to destroy your project.&lt;/p&gt;

&lt;p&gt;But Git isn't the enemy.&lt;/p&gt;

&lt;p&gt;Running commands without understanding them is.&lt;/p&gt;

&lt;p&gt;Once I slowed down and actually learned what commands like checkout, pull, and reset do, Git stopped feeling scary and started feeling like a safety net.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 2 — Always Backup Your Work
&lt;/h2&gt;

&lt;p&gt;The real hero of that moment was my backup.&lt;/p&gt;

&lt;p&gt;If I hadn’t had one, I genuinely could have lost hours (or days) of work.&lt;/p&gt;

&lt;p&gt;After that experience, I decided to automate the process.&lt;/p&gt;

&lt;p&gt;I created a small PowerShell script that automatically backs up my /htdocs/ folder, so I always have a copy of my working files.&lt;/p&gt;

&lt;p&gt;Now backups happen without me even thinking about them.&lt;/p&gt;

&lt;p&gt;That one small script removed an enormous amount of stress from my workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 3 — Fear Is Part of the Learning Curve
&lt;/h2&gt;

&lt;p&gt;Looking back, the fear I felt in that moment was actually part of the learning process.&lt;/p&gt;

&lt;p&gt;Every developer eventually reaches a point where they realise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tools like Git aren’t just version control — they’re power tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And power tools require respect.&lt;/p&gt;

&lt;p&gt;Once you understand them, they stop being scary and start being incredibly useful.&lt;/p&gt;




&lt;p&gt;Final Advice for New Developers&lt;/p&gt;

&lt;p&gt;If you're just starting with Git:&lt;/p&gt;

&lt;p&gt;Don’t blindly copy commands from tutorials&lt;/p&gt;

&lt;p&gt;Take time to understand what each command does&lt;/p&gt;

&lt;p&gt;Always keep backups of your important work&lt;/p&gt;

&lt;p&gt;Because one day you will see the word “deleting” fly past in a terminal…&lt;/p&gt;

&lt;p&gt;…and your heart will skip a beat.&lt;/p&gt;

&lt;p&gt;Trust me on that.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>bash</category>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>I Built My Own dev.to Feed Page Instead of Embedding a Widget</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Sat, 28 Feb 2026 20:21:11 +0000</pubDate>
      <link>https://forem.com/webweaversworld/i-built-my-own-devto-feed-page-instead-of-embedding-a-widget-fa5</link>
      <guid>https://forem.com/webweaversworld/i-built-my-own-devto-feed-page-instead-of-embedding-a-widget-fa5</guid>
      <description>&lt;p&gt;There’s an easy way to show your dev.to posts on your website.&lt;/p&gt;

&lt;p&gt;You paste in a widget.&lt;br&gt;
You let it render.&lt;br&gt;
You move on.&lt;/p&gt;

&lt;p&gt;I almost did that.&lt;/p&gt;

&lt;p&gt;But the more I looked at it, the more it felt slightly disconnected from how I build everything else.&lt;/p&gt;

&lt;p&gt;So I didn’t embed it.&lt;/p&gt;

&lt;p&gt;I built my own feed page instead.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Didn’t Use the Widget
&lt;/h2&gt;

&lt;p&gt;This wasn’t about avoiding convenience.&lt;/p&gt;

&lt;p&gt;It was about consistency.&lt;/p&gt;

&lt;p&gt;My site is fully hand-built — HTML, CSS, JavaScript, structured layouts, injection layers, theme handling. Everything is intentional.&lt;/p&gt;

&lt;p&gt;Dropping in a third-party widget would have worked, but it wouldn’t have felt like part of the system.&lt;/p&gt;

&lt;p&gt;It would’ve been something sitting inside it.&lt;/p&gt;

&lt;p&gt;And that difference matters more than it sounds.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Approach
&lt;/h2&gt;

&lt;p&gt;dev.to provides a public RSS feed. That’s data.&lt;/p&gt;

&lt;p&gt;So instead of embedding a UI component, I fetched the feed, parsed the XML, and rendered the posts as native components on my site.&lt;/p&gt;

&lt;p&gt;No iframe.&lt;br&gt;
No external styling.&lt;br&gt;
No layout overrides.&lt;/p&gt;

&lt;p&gt;Just data → structured objects → my own card components.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The posts match my design system&lt;/li&gt;
&lt;li&gt;The spacing, typography, and hover states are consistent&lt;/li&gt;
&lt;li&gt;The performance impact is minimal&lt;/li&gt;
&lt;li&gt;The page works whether someone is logged into dev.to or not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It feels integrated rather than attached.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Like About This Pattern
&lt;/h2&gt;

&lt;p&gt;RSS is simple.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s stable.&lt;/li&gt;
&lt;li&gt;It’s predictable.&lt;/li&gt;
&lt;li&gt;It doesn’t try to control your layout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation — content from presentation — is powerful.&lt;/p&gt;

&lt;p&gt;dev.to handles publishing and discovery.&lt;br&gt;
My site handles display and brand.&lt;/p&gt;

&lt;p&gt;Both do what they’re good at.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Small Architectural Win
&lt;/h2&gt;

&lt;p&gt;This isn’t a huge feature.&lt;/p&gt;

&lt;p&gt;It’s not complex.&lt;/p&gt;

&lt;p&gt;But it reinforces something I’ve been learning while building everything from scratch:&lt;/p&gt;

&lt;p&gt;Control over the surface area of your site makes everything cleaner long term.&lt;/p&gt;

&lt;p&gt;When you own the presentation layer, you’re not negotiating with someone else’s styles, scripts, or structure.&lt;/p&gt;

&lt;p&gt;You’re just working with data.&lt;/p&gt;

&lt;p&gt;And I prefer building that way.&lt;/p&gt;




&lt;p&gt;If you’re building a personal site and want your blog content there too, consider pulling the feed instead of embedding the widget.&lt;/p&gt;

&lt;p&gt;It’s a small change — but it keeps your architecture intentional.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>rss</category>
      <category>frontend</category>
    </item>
    <item>
      <title>I Built My Own Wordle Engine to Support How I Actually Think</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Sat, 28 Feb 2026 10:30:56 +0000</pubDate>
      <link>https://forem.com/webweaversworld/i-built-my-own-wordle-engine-to-support-how-i-actually-think-4igd</link>
      <guid>https://forem.com/webweaversworld/i-built-my-own-wordle-engine-to-support-how-i-actually-think-4igd</guid>
      <description>&lt;h2&gt;
  
  
  Why I Built My Own Wordle
&lt;/h2&gt;

&lt;p&gt;Like a lot of developers, I enjoy Wordle.&lt;br&gt;
But after playing for a while, I realised I didn’t just want to play it — I wanted to understand it.&lt;/p&gt;

&lt;p&gt;So instead of cloning a template, I built my own Wordle engine from scratch.&lt;/p&gt;

&lt;p&gt;Not because the world needed another clone.&lt;/p&gt;

&lt;p&gt;But because I wanted:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Full control over the word pool&lt;/li&gt;
&lt;li&gt;Seeded daily logic I understood completely&lt;/li&gt;
&lt;li&gt;A stats system I could extend cleanly&lt;/li&gt;
&lt;li&gt;And a version that reflected how I actually think when solving puzzles&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s how Web Weavers Wordle started.&lt;/p&gt;


&lt;h2&gt;
  
  
  Custom Word Pool (Under 1k → Nearly 6k Words)
&lt;/h2&gt;

&lt;p&gt;Originally, my word list was tiny — under 1,000 entries.&lt;/p&gt;

&lt;p&gt;It worked, but it felt constrained.&lt;/p&gt;

&lt;p&gt;So I rebuilt the dictionary layer entirely.&lt;/p&gt;

&lt;p&gt;Instead of a single static list, I moved to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate &lt;code&gt;.txt&lt;/code&gt; files per word length&lt;/li&gt;
&lt;li&gt;Dynamic loading&lt;/li&gt;
&lt;li&gt;A combined &lt;code&gt;VALID_SET&lt;/code&gt; for fast validation&lt;/li&gt;
&lt;li&gt;Per-length counts for UI stats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pool is now just under 6,000 words, all curated to match the theme (every answer starts with W).&lt;/p&gt;

&lt;p&gt;It’s modular, scalable, and easy to extend — without bloating the main script.&lt;/p&gt;

&lt;p&gt;That refactor alone made the project feel like a proper engine instead of a weekend experiment.&lt;/p&gt;


&lt;h2&gt;
  
  
  Daily Logic (Seeded, Predictable, Controlled)
&lt;/h2&gt;

&lt;p&gt;For the daily mode, I didn’t want randomness.&lt;/p&gt;

&lt;p&gt;I implemented seeded selection based on the local date:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;seedFromDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&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;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everyone gets the same word on the same day&lt;/li&gt;
&lt;li&gt;The day flips at local midnight&lt;/li&gt;
&lt;li&gt;No server needed&lt;/li&gt;
&lt;li&gt;No external API calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s deterministic and self-contained.&lt;/p&gt;

&lt;p&gt;Which is exactly how I like my systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  The UX Gap I Noticed
&lt;/h2&gt;

&lt;p&gt;This is where it got interesting.&lt;/p&gt;

&lt;p&gt;When solving Wordle, I don’t like filling unknown spaces with random letters.&lt;/p&gt;

&lt;p&gt;Before, if I was thinking through a word like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;W _ S T _
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would temporarily type something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;W W S T W
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just to fill the row visually.&lt;/p&gt;

&lt;p&gt;But that felt wrong.&lt;/p&gt;

&lt;p&gt;Those letters weren’t information — they were noise.&lt;/p&gt;

&lt;p&gt;So I added a new state.&lt;/p&gt;

&lt;p&gt;A manual &lt;code&gt;?&lt;/code&gt; placeholder.&lt;/p&gt;

&lt;p&gt;Now I can type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;W ? S T ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visually preserves structure&lt;/li&gt;
&lt;li&gt;Doesn’t affect validation&lt;/li&gt;
&lt;li&gt;Cannot be submitted&lt;/li&gt;
&lt;li&gt;Acts as a deliberate “unknown” marker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It sounds tiny.&lt;/p&gt;

&lt;p&gt;But it fundamentally changed how the puzzle feels to solve.&lt;/p&gt;

&lt;p&gt;It added an intentional “thinking state” between blank and evaluated.&lt;/p&gt;

&lt;p&gt;And I haven’t seen other clones do that.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Didn’t Build (Yet)
&lt;/h2&gt;

&lt;p&gt;I considered expanding daily mode to every word length.&lt;/p&gt;

&lt;p&gt;Technically, it would be easy.&lt;/p&gt;

&lt;p&gt;Architecturally? It touches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stats storage&lt;/li&gt;
&lt;li&gt;Streak logic&lt;/li&gt;
&lt;li&gt;UI distribution trees&lt;/li&gt;
&lt;li&gt;LocalStorage keys&lt;/li&gt;
&lt;li&gt;Share formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I didn’t.&lt;/p&gt;

&lt;p&gt;The current version is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stable.&lt;/li&gt;
&lt;li&gt;Clean.&lt;/li&gt;
&lt;li&gt;Focused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d rather refine than expand.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project started as curiosity.&lt;/p&gt;

&lt;p&gt;It’s now a modular, seeded, PWA-enabled Wordle engine with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nearly 6,000 words&lt;/li&gt;
&lt;li&gt;Custom daily logic&lt;/li&gt;
&lt;li&gt;Clean stats tracking&lt;/li&gt;
&lt;li&gt;Share image generation&lt;/li&gt;
&lt;li&gt;And a small UX improvement I genuinely love&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the best way to understand a system is to rebuild it.&lt;/p&gt;

&lt;p&gt;And sometimes rebuilding it lets you improve it in small, meaningful ways.&lt;/p&gt;




&lt;p&gt;The live version is here, if you'd like to try it; &lt;a href="https://webweaversworld.co.uk/html/main/wordle/index.html" rel="noopener noreferrer"&gt;https://webweaversworld.co.uk/html/main/wordle/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>gamedev</category>
      <category>indiedev</category>
    </item>
    <item>
      <title>When Regex Meets the DOM (And Suddenly It’s Not Simple Anymore)</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Thu, 26 Feb 2026 10:03:46 +0000</pubDate>
      <link>https://forem.com/webweaversworld/when-regex-meets-the-dom-and-suddenly-its-not-simple-anymore-1lpa</link>
      <guid>https://forem.com/webweaversworld/when-regex-meets-the-dom-and-suddenly-its-not-simple-anymore-1lpa</guid>
      <description>&lt;p&gt;I recently built a custom in-page “Ctrl + F”-style search and highlight feature.&lt;/p&gt;

&lt;p&gt;The goal sounded simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support multi-word queries&lt;/li&gt;
&lt;li&gt;Prefer full phrase matches&lt;/li&gt;
&lt;li&gt;Fall back to individual token matches&lt;/li&gt;
&lt;li&gt;Highlight results in the DOM&lt;/li&gt;
&lt;li&gt;Skip &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my head?&lt;/p&gt;

&lt;p&gt;“Easy. Just build a regex.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Build the Regex
&lt;/h2&gt;

&lt;p&gt;If a user searches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;power shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I generate a pattern like:&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="nx"&gt;power&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;u00A0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;shell&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;power&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;shell&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try to match the full phrase first&lt;/li&gt;
&lt;li&gt;If that fails, match individual tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On paper? Clean.&lt;/p&gt;

&lt;p&gt;In isolation? Works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Enter the DOM
&lt;/h2&gt;

&lt;p&gt;This is where things escalated.&lt;/p&gt;

&lt;p&gt;Instead of just running &lt;code&gt;string.match()&lt;/code&gt;, I had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Walk the DOM&lt;/li&gt;
&lt;li&gt;Avoid header UI&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid breaking syntax highlighting&lt;/li&gt;
&lt;li&gt;Replace only text nodes&lt;/li&gt;
&lt;li&gt;Preserve structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That meant using a &lt;code&gt;TreeWalker&lt;/code&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;walker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTreeWalker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SHOW_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;acceptNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_REJECT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code, pre, script, style&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_REJECT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_ACCEPT&lt;/span&gt;&lt;span class="p"&gt;;&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;Now we’re not just doing regex.&lt;br&gt;
We’re doing controlled DOM mutation.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 3: The Alternation Problem
&lt;/h2&gt;

&lt;p&gt;This is where it got interesting.&lt;/p&gt;

&lt;p&gt;Even though the phrase appears first in the alternation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;phrase|token1|token2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine still happily matches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;power&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shell&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PowerShell&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on context.&lt;/p&gt;

&lt;p&gt;So now the problem isn’t “regex syntax”.&lt;/p&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overlapping matches&lt;/li&gt;
&lt;li&gt;Execution order&lt;/li&gt;
&lt;li&gt;Resetting lastIndex&lt;/li&gt;
&lt;li&gt;Avoiding double mutation&lt;/li&gt;
&lt;li&gt;Preventing nested &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; elements&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4: Two Passes?
&lt;/h2&gt;

&lt;p&gt;At one point I thought:&lt;/p&gt;

&lt;p&gt;Maybe this shouldn’t be one regex.&lt;/p&gt;

&lt;p&gt;Maybe the logic should be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try phrase match&lt;/li&gt;
&lt;li&gt;If none found, then try token match&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Which sounds simple…&lt;/p&gt;

&lt;p&gt;Until you realise your DOM has already been mutated once.&lt;/p&gt;

&lt;p&gt;Now you’re managing state across passes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Realisation
&lt;/h2&gt;

&lt;p&gt;I understand JavaScript logic.&lt;/p&gt;

&lt;p&gt;I understand regex.&lt;/p&gt;

&lt;p&gt;But applying that logic safely across a live DOM tree?&lt;/p&gt;

&lt;p&gt;That’s a different tier of problem.&lt;/p&gt;

&lt;p&gt;Regex is deterministic.&lt;br&gt;
The DOM is structural and stateful.&lt;/p&gt;

&lt;p&gt;And once you start replacing text nodes, everything becomes delicate.&lt;/p&gt;




&lt;p&gt;What I Learned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regex problems are easy in isolation.&lt;/li&gt;
&lt;li&gt;DOM mutation problems are easy in isolation.&lt;/li&gt;
&lt;li&gt;Combining them multiplies complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also:&lt;/p&gt;

&lt;p&gt;The line between “simple feature” and “mini search engine” is very thin.&lt;/p&gt;

&lt;p&gt;Where I Am Now&lt;/p&gt;

&lt;p&gt;The search works.&lt;/p&gt;

&lt;p&gt;Mostly.&lt;/p&gt;

&lt;p&gt;It highlights.&lt;br&gt;
It skips protected blocks.&lt;br&gt;
It respects structure.&lt;/p&gt;

&lt;p&gt;But it’s not a browser-level &lt;code&gt;Ctrl + F&lt;/code&gt;.&lt;br&gt;
Not yet.&lt;/p&gt;

&lt;p&gt;And that’s the interesting part.&lt;/p&gt;

&lt;p&gt;I now respect the DOM far more than I did before.&lt;/p&gt;

&lt;p&gt;And I never thought I’d say this sentence naturally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I get the logic of JavaScript.&lt;br&gt;
Making that logic behave predictably inside a living DOM tree is the real challenge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There’s still refinement to do.&lt;br&gt;
Edge cases to tame.&lt;br&gt;
State to simplify.&lt;/p&gt;

&lt;p&gt;But that’s the line between “feature complete” and “actually robust.”&lt;/p&gt;

&lt;p&gt;And I’m somewhere in the middle of that line.&lt;/p&gt;

</description>
      <category>regex</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>I Learned More Building One Testimonial System Than From Months of Tutorials</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Wed, 25 Feb 2026 06:10:40 +0000</pubDate>
      <link>https://forem.com/webweaversworld/i-learned-more-building-one-testimonial-system-than-from-months-of-tutorials-23oo</link>
      <guid>https://forem.com/webweaversworld/i-learned-more-building-one-testimonial-system-than-from-months-of-tutorials-23oo</guid>
      <description>&lt;p&gt;When I first got into web development, it was very much the “web” side of things that pulled me in.&lt;/p&gt;

&lt;p&gt;HTML. CSS. Making something appear on a screen from nothing.&lt;/p&gt;

&lt;p&gt;There’s something powerful about writing a few lines of code and seeing it come alive in a browser. That never really gets old.&lt;/p&gt;

&lt;p&gt;But over time, something shifted.&lt;/p&gt;

&lt;p&gt;I started caring less about just how things looked… and more about how they &lt;em&gt;worked&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The logic.&lt;br&gt;&lt;br&gt;
The structure.&lt;br&gt;&lt;br&gt;
The “why is this doing that?” moments.&lt;/p&gt;

&lt;p&gt;Recently, I built my own testimonial system for my site. On the surface, that sounds simple. Just a form and some displayed text, right?&lt;/p&gt;

&lt;p&gt;It wasn’t.&lt;/p&gt;

&lt;p&gt;I had to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the data gets stored
&lt;/li&gt;
&lt;li&gt;How to structure it properly
&lt;/li&gt;
&lt;li&gt;Validation
&lt;/li&gt;
&lt;li&gt;Preventing abuse
&lt;/li&gt;
&lt;li&gt;Connecting front-end to database
&lt;/li&gt;
&lt;li&gt;Triggering actions after submission
&lt;/li&gt;
&lt;li&gt;And making sure it all behaves in production, not just locally
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;There were moments where I broke it.&lt;br&gt;
Moments where I misunderstood how APIs worked.&lt;br&gt;
Moments where I thought I’d finished… only to realise I hadn’t accounted for edge cases.&lt;/p&gt;

&lt;p&gt;But that’s where the learning really happened.&lt;/p&gt;

&lt;p&gt;I realised something important:&lt;/p&gt;

&lt;p&gt;You don’t become “full-stack” by calling yourself full-stack.&lt;/p&gt;

&lt;p&gt;You become it by building things that force you to learn the layers underneath.&lt;/p&gt;

&lt;p&gt;What started as “I want a testimonials page” turned into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working with databases
&lt;/li&gt;
&lt;li&gt;Understanding data flow
&lt;/li&gt;
&lt;li&gt;Thinking about security
&lt;/li&gt;
&lt;li&gt;Writing logic I didn’t think I could write a few years ago &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And honestly? That’s been the most satisfying part.&lt;/p&gt;

&lt;p&gt;Not the polished UI.&lt;br&gt;
Not the final version.&lt;/p&gt;

&lt;p&gt;The messy middle.&lt;/p&gt;

&lt;p&gt;The debugging.&lt;br&gt;
The rewrites.&lt;br&gt;
The moments where something finally clicks.&lt;/p&gt;

&lt;p&gt;I’m still learning. A lot.&lt;/p&gt;

&lt;p&gt;But every time I build something that stretches me a bit further than last time, I feel like I’m actually becoming the developer I wanted to be when I was younger.&lt;/p&gt;

&lt;p&gt;And that’s a good feeling.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fullstack</category>
      <category>learning</category>
      <category>database</category>
    </item>
    <item>
      <title>Why I Still Build Websites From Scratch in 2026</title>
      <dc:creator>Kristieene Knowles</dc:creator>
      <pubDate>Tue, 24 Feb 2026 05:15:08 +0000</pubDate>
      <link>https://forem.com/webweaversworld/why-i-still-build-websites-from-scratch-in-2026-1b3m</link>
      <guid>https://forem.com/webweaversworld/why-i-still-build-websites-from-scratch-in-2026-1b3m</guid>
      <description>&lt;p&gt;In a world of drag-and-drop builders, AI site generators, and one-click themes, choosing to build websites from scratch can feel unnecessary.&lt;/p&gt;

&lt;p&gt;But I still do.&lt;/p&gt;

&lt;p&gt;I run an independent studio, Web Weavers World, where every site is hand-coded. No templates. No visual builders. No plugin stacks layered on top of each other.&lt;/p&gt;

&lt;p&gt;That’s not because modern tools are “bad.” They’re incredibly useful. They solve real problems.&lt;/p&gt;

&lt;p&gt;I just value control.&lt;/p&gt;

&lt;p&gt;When I build from scratch, I know exactly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What loads and when&lt;/li&gt;
&lt;li&gt;Why a layout behaves the way it does&lt;/li&gt;
&lt;li&gt;How performance is impacted&lt;/li&gt;
&lt;li&gt;What the accessibility trade-offs are&lt;/li&gt;
&lt;li&gt;Which scripts are truly necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s no mystery layer.&lt;/p&gt;

&lt;p&gt;Performance matters to me. Not just Lighthouse scores, but real-world responsiveness. Clean architecture matters. Maintainability matters. Accessibility matters.&lt;/p&gt;

&lt;p&gt;And honestly ~ I enjoy it.&lt;/p&gt;

&lt;p&gt;There’s something satisfying about understanding every moving part of a system you built. From the CSS structure to the backend logic to the analytics tracking.&lt;/p&gt;

&lt;p&gt;It also forces better decisions.&lt;/p&gt;

&lt;p&gt;When you don’t have a plugin to solve everything, you think more carefully about whether something needs to exist at all.&lt;/p&gt;

&lt;p&gt;That constraint is valuable.&lt;/p&gt;

&lt;p&gt;I’m not anti-tool. I use modern workflows, automation, and analytics daily. But I choose intentional complexity over hidden complexity.&lt;/p&gt;

&lt;p&gt;That’s why I still build websites from scratch in 2026.&lt;/p&gt;

&lt;p&gt;Curious how others approach this ~ are you all-in on frameworks and builders, or do you still enjoy the raw build process too?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>performance</category>
      <category>indiedev</category>
    </item>
  </channel>
</rss>
