<?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: Michael Butts</title>
    <description>The latest articles on Forem by Michael Butts (@buildoutreach).</description>
    <link>https://forem.com/buildoutreach</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%2F3817532%2F8570a5f5-15d0-4f03-badd-aed714921e65.png</url>
      <title>Forem: Michael Butts</title>
      <link>https://forem.com/buildoutreach</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/buildoutreach"/>
    <language>en</language>
    <item>
      <title>Building an Interactive Software Recommendation Quiz with Pure HTML/CSS/JS</title>
      <dc:creator>Michael Butts</dc:creator>
      <pubDate>Thu, 12 Mar 2026 05:11:42 +0000</pubDate>
      <link>https://forem.com/buildoutreach/building-an-interactive-software-recommendation-quiz-with-pure-htmlcssjs-4keg</link>
      <guid>https://forem.com/buildoutreach/building-an-interactive-software-recommendation-quiz-with-pure-htmlcssjs-4keg</guid>
      <description>&lt;p&gt;I needed a way to help contractors figure out which business software to use. Instead of building a React app, I built an interactive 5-step quiz with vanilla HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/software-quiz.html" rel="noopener noreferrer"&gt;Try the live demo here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's how it works and how you can build your own recommendation engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept
&lt;/h2&gt;

&lt;p&gt;A multi-step quiz that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asks 5 questions (trade, team size, budget, priorities, experience)&lt;/li&gt;
&lt;li&gt;Scores 7 software options against the answers&lt;/li&gt;
&lt;li&gt;Shows top 3 recommendations with match scores&lt;/li&gt;
&lt;li&gt;Has email capture and social sharing built in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in a single HTML file. No build step. No dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Question Cards with Show/Hide
&lt;/h3&gt;

&lt;p&gt;Each question is a &lt;code&gt;div&lt;/code&gt; with a &lt;code&gt;data-q&lt;/code&gt; attribute. Only one is visible at a time:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"question-card active"&lt;/span&gt; &lt;span class="na"&gt;data-q=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;What type of work do you do?&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"options"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"option"&lt;/span&gt; &lt;span class="na"&gt;data-value=&lt;/span&gt;&lt;span class="s"&gt;"hvac"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"selectOption(this)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"option-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;snowflake emoji&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"option-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;HVAC&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Heating, cooling, ventilation&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS handles the visibility:&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="nc"&gt;.question-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.question-card.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&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;h3&gt;
  
  
  2. Selection Logic
&lt;/h3&gt;

&lt;p&gt;Store answers in a simple object:&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;answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;selectOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&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;card&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&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="s1"&gt;.question-card&lt;/span&gt;&lt;span class="dl"&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;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.option&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextBtn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;h3&gt;
  
  
  3. The Scoring Engine
&lt;/h3&gt;

&lt;p&gt;This is the interesting part. Each software product has arrays of compatible values for each dimension:&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;software&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;jobber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jobber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;trades&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hvac&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="s1"&gt;plumbing&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="s1"&gt;electrical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;solo&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="s1"&gt;small&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="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;budgets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moderate&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="s1"&gt;growth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;priorities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scheduling&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="s1"&gt;invoicing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;experience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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="s1"&gt;basic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pricing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;From $49/month&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scoreMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&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;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&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;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;budgets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&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;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;priorities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&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;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;experience&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;score&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// max 12&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The weighting is deliberate: trade, size, and budget are deal-breakers (3 points each). Priority matters (2 points). Experience level is a nice-to-have (1 point).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Dynamic Results
&lt;/h3&gt;

&lt;p&gt;Sort by score, take top 3, render with template literals:&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;scored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;software&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;matchScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;scoreMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sw&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;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchScore&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchScore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scored&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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;`
  &amp;lt;div class="recommendation &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top-pick&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="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
    &amp;lt;div class="rec-badge"&amp;gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BEST MATCH&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="s1"&gt;Runner Up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;h3&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;Match: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchScore&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/12&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Smooth Progress Bar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.progress-fill&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#3b82f6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#8b5cf6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.4s&lt;/span&gt; &lt;span class="n"&gt;ease&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;Update width on each step transition for that satisfying fill effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why No Framework?
&lt;/h2&gt;

&lt;p&gt;For a tool like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;0 KB of JavaScript dependencies&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant load time&lt;/strong&gt; (important for SEO and user experience)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works everywhere&lt;/strong&gt; (no polyfills needed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to embed&lt;/strong&gt; (paste HTML into any site)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff is managing state manually. But with 5 questions and 7 products, that complexity is trivial.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Business Side
&lt;/h2&gt;

&lt;p&gt;This quiz pattern works for any recommendation engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lead generation&lt;/strong&gt; via email capture in results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Affiliate revenue&lt;/strong&gt; from recommendation links&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO&lt;/strong&gt; with FAQ schema for rich snippets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Viral sharing&lt;/strong&gt; with social buttons&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One tool, four growth channels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/software-quiz.html" rel="noopener noreferrer"&gt;Live demo: Contractor Software Quiz&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The pattern is reusable. Swap out the software database for your niche (hosting providers, project management tools, CRMs) and you have a recommendation engine.&lt;/p&gt;

&lt;p&gt;All the other free tools are at &lt;a href="https://toolkit.buildoutreach.io/tools/" rel="noopener noreferrer"&gt;toolkit.buildoutreach.io/tools&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What approach do you prefer for interactive content — framework or vanilla? Let me know in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Built a Complete Affiliate SEO Site in 2 Weeks Using Only AI — Here's the Full Stack</title>
      <dc:creator>Michael Butts</dc:creator>
      <pubDate>Thu, 12 Mar 2026 05:02:52 +0000</pubDate>
      <link>https://forem.com/buildoutreach/i-built-a-complete-affiliate-seo-site-in-2-weeks-using-only-ai-heres-the-full-stack-3pp</link>
      <guid>https://forem.com/buildoutreach/i-built-a-complete-affiliate-seo-site-in-2-weeks-using-only-ai-heres-the-full-stack-3pp</guid>
      <description>&lt;p&gt;I wanted to test a hypothesis: &lt;strong&gt;Can a solo operator build a legitimate, content-rich affiliate site in under 2 weeks using AI tools?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spoiler: Yes. I built &lt;a href="https://toolkit.buildoutreach.io" rel="noopener noreferrer"&gt;toolkit.buildoutreach.io&lt;/a&gt; — a contractor software review site with 26 in-depth review and comparison pages, 6 free tools, 19 blog articles, and full SEO infrastructure. Here's exactly how I did it, what worked, and what I'd do differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Vercel (free tier)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain:&lt;/strong&gt; Cloudflare DNS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content:&lt;/strong&gt; Static HTML (no framework, no CMS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO:&lt;/strong&gt; Google Search Console, IndexNow API, FAQ Schema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email:&lt;/strong&gt; Resend + Stripe (lead capture → automated drip)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Vercel Analytics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Stripe Payment Links&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Claude for content generation, research, and code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Static HTML?
&lt;/h2&gt;

&lt;p&gt;I know, I know. It's 2026. Everyone's using Next.js or Astro.&lt;/p&gt;

&lt;p&gt;But here's the thing: &lt;strong&gt;static HTML loads instantly, costs nothing to host, and Google loves it.&lt;/strong&gt; My pages hit 95+ Lighthouse scores without any optimization work. No hydration, no bundle splitting, no build step.&lt;/p&gt;

&lt;p&gt;For an affiliate content site, the content IS the product. I don't need client-side routing or server components. I need fast pages with good content.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Content Architecture
&lt;/h2&gt;

&lt;p&gt;Here's what I built in 14 days:&lt;/p&gt;

&lt;h3&gt;
  
  
  Affiliate Review Pages (26 pages)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Individual reviews:&lt;/strong&gt; Jobber, Housecall Pro, ServiceTitan, Workiz, FieldPulse, Kickserv, Joist, Buildertrend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Head-to-head comparisons:&lt;/strong&gt; Jobber vs Housecall Pro, Jobber vs ServiceTitan, Jobber vs FieldPulse, Housecall Pro vs Workiz&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Category roundups:&lt;/strong&gt; Best Field Service Software, Best CRM for Contractors, Best Scheduling Software, Best Invoicing Software, Best Estimating Software, Best Free Contractor Apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-specific guides:&lt;/strong&gt; Best HVAC Software, Best Plumbing Software, Best Electrical Contractor Software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every review follows the same structure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Quick verdict + score&lt;/li&gt;
&lt;li&gt;Pricing breakdown&lt;/li&gt;
&lt;li&gt;Feature deep-dive&lt;/li&gt;
&lt;li&gt;Pros/cons&lt;/li&gt;
&lt;li&gt;Who it's best for&lt;/li&gt;
&lt;li&gt;FAQ schema (for rich snippets)&lt;/li&gt;
&lt;li&gt;Comparison table&lt;/li&gt;
&lt;li&gt;Cross-links to related reviews&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Free Tools (6 tools)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Follow-up message generator&lt;/li&gt;
&lt;li&gt;Estimate calculator&lt;/li&gt;
&lt;li&gt;Resume bullet generator&lt;/li&gt;
&lt;li&gt;Marketing scorecard quiz&lt;/li&gt;
&lt;li&gt;47-point marketing checklist&lt;/li&gt;
&lt;li&gt;Google review link generator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tools serve two purposes: they provide genuine value (people actually use them) and they create organic backlinks when people share them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blog Content (19 articles)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;10 trade-specific marketing guides (HVAC, plumber, electrician, roofing, landscaping, painting, pest control, carpet cleaning, tree service, pressure washing)&lt;/li&gt;
&lt;li&gt;AI prompt guides for different niches&lt;/li&gt;
&lt;li&gt;Comparison articles&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SEO Infrastructure
&lt;/h2&gt;

&lt;p&gt;Content without distribution is just a hobby. Here's what I set up:&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Search Console
&lt;/h3&gt;

&lt;p&gt;Verified via HTML file upload. Submitted sitemap.xml with all 50 URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  IndexNow
&lt;/h3&gt;

&lt;p&gt;Used the IndexNow API to ping Bing and Yandex immediately after deploying new pages:&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="c1"&gt;// Simple IndexNow submission&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.indexnow.org/IndexNow&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&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;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toolkit.buildoutreach.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-key-here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;keyLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://toolkit.buildoutreach.io/your-key.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;urlList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;urls&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;h3&gt;
  
  
  Internal Cross-Linking
&lt;/h3&gt;

&lt;p&gt;This is the most underrated SEO tactic. I built &lt;strong&gt;270+ internal links&lt;/strong&gt; across all pages. Every review links to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The relevant comparison pages&lt;/li&gt;
&lt;li&gt;The category roundup it appears in&lt;/li&gt;
&lt;li&gt;The trade-specific guide where applicable&lt;/li&gt;
&lt;li&gt;Related blog articles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a dense link graph that helps Google understand the site's topical authority.&lt;/p&gt;

&lt;h3&gt;
  
  
  FAQ Schema
&lt;/h3&gt;

&lt;p&gt;Every review page includes structured FAQ data:&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;@context&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;https://schema.org&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;@type&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;FAQPage&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;mainEntity&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="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&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;Question&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;name&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;How much does Jobber cost?&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;acceptedAnswer&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&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;Answer&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;text&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;Jobber starts at $49/month...&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="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can trigger rich snippets in Google search results, dramatically increasing click-through rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email Capture + Automated Drip
&lt;/h2&gt;

&lt;p&gt;Every page has an email capture form that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates a Stripe customer (for later monetization)&lt;/li&gt;
&lt;li&gt;Sends a niche-matched welcome email via Resend&lt;/li&gt;
&lt;li&gt;Enrolls them in a 5-day automated email course&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The welcome email delivers immediate value (a marketing cheat sheet) so subscribers feel good about signing up.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1. Content is the easy part
&lt;/h3&gt;

&lt;p&gt;With AI, I can generate a high-quality 2,000-word review page in about 20 minutes. The hard part is distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Internal linking &amp;gt; external backlinks (early on)
&lt;/h3&gt;

&lt;p&gt;When you have zero domain authority, internal links are the only signals you control. Build them aggressively.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Static HTML is underrated for SEO sites
&lt;/h3&gt;

&lt;p&gt;Zero build step, instant deploys, perfect Lighthouse scores. The tradeoff (no dynamic features) doesn't matter for content sites.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Trade-specific content &amp;gt; generic content
&lt;/h3&gt;

&lt;p&gt;"Best HVAC Software" converts better than "Best Field Service Software" because the searcher is more specific about what they need.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Free tools are the best backlink generators
&lt;/h3&gt;

&lt;p&gt;People share useful tools. Nobody shares review articles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results So Far
&lt;/h2&gt;

&lt;p&gt;Honestly? &lt;strong&gt;Zero traffic and zero revenue.&lt;/strong&gt; The site is 2 weeks old. SEO takes 3-6 months to compound.&lt;/p&gt;

&lt;p&gt;But the infrastructure is solid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50 URLs indexed&lt;/li&gt;
&lt;li&gt;270+ internal links&lt;/li&gt;
&lt;li&gt;Email capture on every page&lt;/li&gt;
&lt;li&gt;Automated drip sequences&lt;/li&gt;
&lt;li&gt;Affiliate programs approved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll update this post in 90 days with real traffic and revenue numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Site
&lt;/h2&gt;

&lt;p&gt;Check it out: &lt;a href="https://toolkit.buildoutreach.io" rel="noopener noreferrer"&gt;toolkit.buildoutreach.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything's live — the reviews, the tools, the blog. If you're building an affiliate site, feel free to steal the structure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your experience with AI-assisted content sites? Has anyone else gone the static HTML route? I'd love to hear what's working for you.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>ai</category>
      <category>affiliate</category>
    </item>
    <item>
      <title>I Compared 15+ Contractor Software Tools — Here's What Actually Works in 2026</title>
      <dc:creator>Michael Butts</dc:creator>
      <pubDate>Wed, 11 Mar 2026 21:29:48 +0000</pubDate>
      <link>https://forem.com/buildoutreach/i-compared-15-contractor-software-tools-heres-what-actually-works-in-2026-2lh1</link>
      <guid>https://forem.com/buildoutreach/i-compared-15-contractor-software-tools-heres-what-actually-works-in-2026-2lh1</guid>
      <description>&lt;p&gt;I spent the last two months testing and reviewing field service management software for contractors. Not just reading feature pages — actually digging into pricing, workflows, and user feedback across platforms like Jobber, Housecall Pro, ServiceTitan, Workiz, and more.&lt;/p&gt;

&lt;p&gt;Here's the honest breakdown for anyone building in or selling to the contractor/home services space.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Market Is Bigger Than You'd Think
&lt;/h2&gt;

&lt;p&gt;The field service management (FSM) software market is projected to hit $8.5B by 2028. There are ~3.7 million contracting businesses in the US alone, and most of them are still running on whiteboards, spreadsheets, and sticky notes.&lt;/p&gt;

&lt;p&gt;The dominant players right now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jobber&lt;/strong&gt; — ~200K+ users, focused on small-mid service companies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Housecall Pro&lt;/strong&gt; — similar size, stronger marketing features
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ServiceTitan&lt;/strong&gt; — enterprise play, $9.5B valuation, recently filed for IPO&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workiz&lt;/strong&gt; — growing fast, built-in VoIP is unique&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kickserv&lt;/strong&gt; — free tier, older platform&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Found (The TL;DR)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jobber&lt;/td&gt;
&lt;td&gt;$69-349/mo&lt;/td&gt;
&lt;td&gt;Small-mid service contractors&lt;/td&gt;
&lt;td&gt;Best overall for most&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Housecall Pro&lt;/td&gt;
&lt;td&gt;$79-199/mo&lt;/td&gt;
&lt;td&gt;Marketing-focused companies&lt;/td&gt;
&lt;td&gt;Great if you want built-in review automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ServiceTitan&lt;/td&gt;
&lt;td&gt;$2,000-5,000+/mo&lt;/td&gt;
&lt;td&gt;Enterprise (5+ trucks, $1M+ rev)&lt;/td&gt;
&lt;td&gt;Overkill for 90% of contractors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workiz&lt;/td&gt;
&lt;td&gt;$65/mo+&lt;/td&gt;
&lt;td&gt;Phone-heavy businesses&lt;/td&gt;
&lt;td&gt;Best call tracking in the space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kickserv&lt;/td&gt;
&lt;td&gt;Free/$47/mo&lt;/td&gt;
&lt;td&gt;Budget-conscious&lt;/td&gt;
&lt;td&gt;Dated but functional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Joist&lt;/td&gt;
&lt;td&gt;Free/$20/mo&lt;/td&gt;
&lt;td&gt;Solo mobile estimating&lt;/td&gt;
&lt;td&gt;Best free mobile app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buildertrend&lt;/td&gt;
&lt;td&gt;$199/mo&lt;/td&gt;
&lt;td&gt;Remodelers/GCs&lt;/td&gt;
&lt;td&gt;Construction-grade estimating&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaways for Builders &amp;amp; SaaS People
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Pricing gaps create opportunity
&lt;/h3&gt;

&lt;p&gt;ServiceTitan charges $2K-5K/month. Jobber charges $69. There's a massive gap between "basic scheduling" and "enterprise everything." Builders targeting the $500K-$2M revenue contractor segment (too big for basic, too small for ServiceTitan) have a real opening.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Estimating is the most underserved workflow
&lt;/h3&gt;

&lt;p&gt;Most platforms bolt on estimating as an afterthought. Contractors consistently say "I spend 3-4 hours a week on estimates." A tool that makes estimating fast, accurate, and mobile-first could win this market segment.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Vertical SaaS is eating horizontal SaaS here
&lt;/h3&gt;

&lt;p&gt;Contractors don't want Salesforce or HubSpot. They want software that knows what a "change order" is. Every general-purpose tool I tested felt wrong for this audience. The winners are 100% vertical.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Distribution is the real moat
&lt;/h3&gt;

&lt;p&gt;The software features are converging — everyone has scheduling, invoicing, CRM. The winners are winning on distribution: Jobber's contractor community, Housecall Pro's review automation loop, ServiceTitan's enterprise sales team.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built (Free + Open Source)
&lt;/h2&gt;

&lt;p&gt;While doing this research, I built a few free tools for contractors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/estimate-calculator.html" rel="noopener noreferrer"&gt;Estimate Calculator&lt;/a&gt;&lt;/strong&gt; — Build quick estimates with labor, materials, and markup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/follow-up-generator.html" rel="noopener noreferrer"&gt;Follow-Up Message Generator&lt;/a&gt;&lt;/strong&gt; — Generate professional follow-up messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/marketing-scorecard.html" rel="noopener noreferrer"&gt;Marketing Scorecard&lt;/a&gt;&lt;/strong&gt; — 47-point assessment for contractor marketing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io/tools/review-link-generator.html" rel="noopener noreferrer"&gt;Google Review Link Generator&lt;/a&gt;&lt;/strong&gt; — Create shareable review links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full comparison guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://toolkit.buildoutreach.io/blog/best-field-service-software.html" rel="noopener noreferrer"&gt;Best Field Service Software 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://toolkit.buildoutreach.io/blog/jobber-vs-housecall-pro.html" rel="noopener noreferrer"&gt;Jobber vs Housecall Pro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://toolkit.buildoutreach.io/blog/servicetitan-review.html" rel="noopener noreferrer"&gt;ServiceTitan Review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://toolkit.buildoutreach.io/blog/free-alternatives-servicetitan-jobber.html" rel="noopener noreferrer"&gt;Free Alternatives to ServiceTitan &amp;amp; Jobber&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The open-source contractor marketing toolkit is on &lt;a href="https://github.com/Mikebutts20/contractor-marketing-toolkit" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; with templates for follow-ups, estimates, and review requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for the Dev Community
&lt;/h2&gt;

&lt;p&gt;If you're building SaaS, the "boring" vertical markets like contractor software are where the money is. Low competition, high willingness to pay, and customers who stay forever once they adopt your workflow.&lt;/p&gt;

&lt;p&gt;The hardest part isn't building — it's distribution. Getting in front of a plumber or HVAC tech is completely different from getting in front of a developer. Trade shows, Google Local Services Ads, and contractor Facebook groups are the real acquisition channels.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I've been deep in the contractor software space for the last year. Happy to answer questions about the market, tools, or building for this audience.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>business</category>
      <category>software</category>
      <category>startup</category>
    </item>
    <item>
      <title>How I Built 7 Free Marketing Tools for Contractors (and What I Learned)</title>
      <dc:creator>Michael Butts</dc:creator>
      <pubDate>Wed, 11 Mar 2026 21:29:45 +0000</pubDate>
      <link>https://forem.com/buildoutreach/how-i-built-7-free-marketing-tools-for-contractors-and-what-i-learned-36kl</link>
      <guid>https://forem.com/buildoutreach/how-i-built-7-free-marketing-tools-for-contractors-and-what-i-learned-36kl</guid>
      <description>&lt;p&gt;&lt;em&gt;A technical breakdown of building a free tool suite that helps home service businesses get more customers — using Vercel, Stripe, and Resend.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you run a plumbing, HVAC, roofing, or landscaping business, marketing probably isn't your thing. You're great at your trade, but "getting more customers" feels like a mystery.&lt;/p&gt;

&lt;p&gt;I've spent years working with contractors and noticed the same problems over and over: no follow-up system, no review strategy, no way to estimate jobs quickly. So I built a free toolkit to solve these problems — and open-sourced the templates on GitHub.&lt;/p&gt;

&lt;p&gt;Here's the technical breakdown and what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most contractor marketing advice is generic garbage: "post on social media!" or "run Google Ads!" &lt;/p&gt;

&lt;p&gt;What contractors actually need are &lt;strong&gt;specific scripts, templates, and tools&lt;/strong&gt; they can use today. Not a 47-page marketing strategy — a text message they can copy-paste to follow up with a lead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Follow-Up Message Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Select your trade, scenario (new lead, post-estimate, no-show), and tone → get 3 customized follow-up messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech stack:&lt;/strong&gt; Pure client-side JavaScript. No API calls needed. Uses template literals with trade-specific variables. Supports 20 trades × 8 scenarios × 3 tones = 480 unique combinations.&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="c1"&gt;// Simplified version of the message generation logic&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tone&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;templates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;messageBank&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;tone&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;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{trade}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tradeLabels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;trade&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{service}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;serviceTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;trade&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;&lt;strong&gt;Email capture:&lt;/strong&gt; After generating messages, users can save their "message playbook" by entering their email. This triggers a Vercel serverless function that creates a Stripe customer and sends a welcome email via Resend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Estimate Calculator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Enter project type, square footage, and location → get a price range with material and labor breakdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt; Contractors constantly need quick estimates for phone quotes. Rather than building a complex pricing engine, I used regional multipliers and industry-standard cost-per-unit data.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Google Review Link Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Enter business name → get a direct link customers can click to leave a Google review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The viral hook:&lt;/strong&gt; Every generated review link page includes a small "Powered by ContractorToolkit" watermark. Every contractor who uses it creates a tiny distribution channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Marketing Scorecard Quiz
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Answer 10 yes/no questions about your marketing → get a score and personalized recommendations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why quizzes work:&lt;/strong&gt; They're inherently shareable ("I scored 4/10 on contractor marketing!") and the results page is a natural place to recommend specific tools and resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Embeddable Estimate Widget
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Get an iframe embed code → put a working estimate calculator on your own website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The distribution play:&lt;/strong&gt; Every embedded widget is a permanent backlink AND a referral source. The contractor's customers see the tool, some visit the source.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Resume Bullet Point Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Bonus tool for a different niche:&lt;/strong&gt; I also built tools for job seekers (resume bullets) and content creators (prompt libraries). Same pattern: free tool → email capture → paid toolkit upsell.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Static HTML/CSS/JS on Vercel (zero framework, fast loads, free hosting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email:&lt;/strong&gt; Resend API with custom domain (buildoutreach.io)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Stripe Payment Links → webhook → automated PDF delivery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email automation:&lt;/strong&gt; Vercel Cron jobs trigger a 5-day email drip sequence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Vercel Analytics (built-in)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why No Framework?
&lt;/h3&gt;

&lt;p&gt;Controversial take: for content-heavy marketing sites, plain HTML outperforms React/Next.js on every metric that matters — load time, SEO, maintainability, and cost. Each page is a self-contained HTML file. No build step. No hydration. No JavaScript framework overhead.&lt;/p&gt;

&lt;p&gt;The tools that need interactivity use vanilla JS. Total JavaScript payload across all tools: ~15KB.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Email Automation System
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User enters email on any tool/article
  → Vercel API route (/api/leads)
  → Creates Stripe customer (for future purchases)
  → Sends welcome email via Resend (niche-matched template)
  → Sets metadata: { niche, source, drip_day: 0 }

Vercel Cron (daily)
  → Queries Stripe customers with drip_day &amp;lt; 5
  → Sends next email in 5-day sequence
  → Increments drip_day
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three niche-matched welcome templates (contractor, job seeker, creator) each deliver a genuine "cheat sheet" — not a sales pitch disguised as value. The 5-day drip sequence teaches real marketing concepts with soft CTAs to the paid toolkit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source Templates
&lt;/h2&gt;

&lt;p&gt;I open-sourced the core templates on GitHub: &lt;strong&gt;&lt;a href="https://github.com/Mikebutts20/contractor-marketing-toolkit" rel="noopener noreferrer"&gt;contractor-marketing-toolkit&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 phone follow-up scripts&lt;/li&gt;
&lt;li&gt;15 text message templates
&lt;/li&gt;
&lt;li&gt;5-email nurture sequence&lt;/li&gt;
&lt;li&gt;Google review request scripts&lt;/li&gt;
&lt;li&gt;Review response templates&lt;/li&gt;
&lt;li&gt;Estimate template guide&lt;/li&gt;
&lt;li&gt;47-point marketing checklist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the raw materials that power the interactive tools. Fork them, customize them, use them however you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build distribution before product.&lt;/strong&gt; I built 18 articles, 7 tools, and 3 paid products before having a single visitor. Should have validated demand first with a Reddit post or landing page test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with one tool, not seven.&lt;/strong&gt; The estimate calculator alone could have been a standalone product. Spreading across 7 tools diluted focus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interactive tools &amp;gt; static content for initial traction.&lt;/strong&gt; Blog articles need SEO time (weeks/months). Tools get shared immediately if they're genuinely useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Email capture from day one.&lt;/strong&gt; I initially launched without email capture and had to retrofit it across 20+ pages. Should have been in the template from the start.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;All tools are free at &lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io" rel="noopener noreferrer"&gt;toolkit.buildoutreach.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The templates are open source at &lt;strong&gt;&lt;a href="https://github.com/Mikebutts20/contractor-marketing-toolkit" rel="noopener noreferrer"&gt;github.com/Mikebutts20/contractor-marketing-toolkit&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you work with contractors or small businesses, I'd love to hear what tools would be most useful. Drop a comment or open an issue on the repo.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building tools for trades that don't have them yet. If you liked this, I also wrote about &lt;a href="https://toolkit.buildoutreach.io/blog/free-alternatives-servicetitan-jobber.html" rel="noopener noreferrer"&gt;free alternatives to ServiceTitan and Jobber&lt;/a&gt; for contractors who can't afford $300/month software.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>webdev</category>
      <category>startup</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I Built 7 Free Marketing Tools for Contractors (and What I Learned)</title>
      <dc:creator>Michael Butts</dc:creator>
      <pubDate>Tue, 10 Mar 2026 21:34:06 +0000</pubDate>
      <link>https://forem.com/buildoutreach/how-i-built-7-free-marketing-tools-for-contractors-and-what-i-learned-5ga</link>
      <guid>https://forem.com/buildoutreach/how-i-built-7-free-marketing-tools-for-contractors-and-what-i-learned-5ga</guid>
      <description>&lt;p&gt;&lt;em&gt;A technical breakdown of building a free tool suite that helps home service businesses get more customers — using Vercel, Stripe, and Resend.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you run a plumbing, HVAC, roofing, or landscaping business, marketing probably isn't your thing. You're great at your trade, but "getting more customers" feels like a mystery.&lt;/p&gt;

&lt;p&gt;I've spent years working with contractors and noticed the same problems over and over: no follow-up system, no review strategy, no way to estimate jobs quickly. So I built a free toolkit to solve these problems — and open-sourced the templates on GitHub.&lt;/p&gt;

&lt;p&gt;Here's the technical breakdown and what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most contractor marketing advice is generic garbage: "post on social media!" or "run Google Ads!"&lt;/p&gt;

&lt;p&gt;What contractors actually need are &lt;strong&gt;specific scripts, templates, and tools&lt;/strong&gt; they can use today. Not a 47-page marketing strategy — a text message they can copy-paste to follow up with a lead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Follow-Up Message Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Select your trade, scenario (new lead, post-estimate, no-show), and tone → get 3 customized follow-up messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech stack:&lt;/strong&gt; Pure client-side JavaScript. No API calls needed. Uses template literals with trade-specific variables. Supports 20 trades × 8 scenarios × 3 tones = 480 unique combinations.&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="c1"&gt;// Simplified version of the message generation logic&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tone&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;templates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;messageBank&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;tone&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;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{trade}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tradeLabels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;trade&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{service}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;serviceTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;trade&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;&lt;strong&gt;Email capture:&lt;/strong&gt; After generating messages, users can save their "message playbook" by entering their email. This triggers a Vercel serverless function that creates a Stripe customer and sends a welcome email via Resend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Estimate Calculator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Enter project type, square footage, and location → get a price range with material and labor breakdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt; Contractors constantly need quick estimates for phone quotes. Rather than building a complex pricing engine, I used regional multipliers and industry-standard cost-per-unit data.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Google Review Link Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Enter business name → get a direct link customers can click to leave a Google review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The viral hook:&lt;/strong&gt; Every generated review link page includes a small "Powered by ContractorToolkit" watermark. Every contractor who uses it creates a tiny distribution channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Marketing Scorecard Quiz
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Answer 10 yes/no questions about your marketing → get a score and personalized recommendations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why quizzes work:&lt;/strong&gt; They're inherently shareable ("I scored 4/10 on contractor marketing!") and the results page is a natural place to recommend specific tools and resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Embeddable Estimate Widget
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The tool:&lt;/strong&gt; Get an iframe embed code → put a working estimate calculator on your own website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The distribution play:&lt;/strong&gt; Every embedded widget is a permanent backlink AND a referral source. The contractor's customers see the tool, some visit the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Static HTML/CSS/JS on Vercel (zero framework, fast loads, free hosting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email:&lt;/strong&gt; Resend API with custom domain (buildoutreach.io)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Stripe Payment Links → webhook → automated PDF delivery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email automation:&lt;/strong&gt; Vercel Cron jobs trigger a 5-day email drip sequence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Vercel Analytics (built-in)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why No Framework?
&lt;/h3&gt;

&lt;p&gt;Controversial take: for content-heavy marketing sites, plain HTML outperforms React/Next.js on every metric that matters — load time, SEO, maintainability, and cost. Each page is a self-contained HTML file. No build step. No hydration. No JavaScript framework overhead.&lt;/p&gt;

&lt;p&gt;The tools that need interactivity use vanilla JS. Total JavaScript payload across all tools: ~15KB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source Templates
&lt;/h2&gt;

&lt;p&gt;I open-sourced the core templates on GitHub: &lt;strong&gt;&lt;a href="https://github.com/Mikebutts20/contractor-marketing-toolkit" rel="noopener noreferrer"&gt;contractor-marketing-toolkit&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 phone follow-up scripts&lt;/li&gt;
&lt;li&gt;15 text message templates&lt;/li&gt;
&lt;li&gt;5-email nurture sequence&lt;/li&gt;
&lt;li&gt;Google review request scripts&lt;/li&gt;
&lt;li&gt;Review response templates&lt;/li&gt;
&lt;li&gt;Estimate template guide&lt;/li&gt;
&lt;li&gt;47-point marketing checklist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the raw materials that power the interactive tools. Fork them, customize them, use them however you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build distribution before product.&lt;/strong&gt; I built 18 articles, 7 tools, and 3 paid products before having a single visitor. Should have validated demand first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with one tool, not seven.&lt;/strong&gt; The estimate calculator alone could have been a standalone product. Spreading across 7 tools diluted focus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interactive tools &amp;gt; static content for initial traction.&lt;/strong&gt; Blog articles need SEO time (weeks/months). Tools get shared immediately if they're genuinely useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Email capture from day one.&lt;/strong&gt; I initially launched without email capture and had to retrofit it across 20+ pages. Should have been in the template from the start.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;All tools are free at &lt;strong&gt;&lt;a href="https://toolkit.buildoutreach.io" rel="noopener noreferrer"&gt;toolkit.buildoutreach.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The templates are open source at &lt;strong&gt;&lt;a href="https://github.com/Mikebutts20/contractor-marketing-toolkit" rel="noopener noreferrer"&gt;github.com/Mikebutts20/contractor-marketing-toolkit&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you work with contractors or small businesses, I'd love to hear what tools would be most useful. Drop a comment or open an issue on the repo.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building tools for trades that don't have them yet. If you liked this, I also wrote about &lt;a href="https://toolkit.buildoutreach.io/blog/free-alternatives-servicetitan-jobber.html" rel="noopener noreferrer"&gt;free alternatives to ServiceTitan and Jobber&lt;/a&gt; for contractors who can't afford $300/month software.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
    </item>
  </channel>
</rss>
