<?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>DEV Community: Rahil Khan</title>
    <description>The latest articles on DEV Community by Rahil Khan (@nexcodestudio).</description>
    <link>https://dev.to/nexcodestudio</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4158451%2Fad52a1e8-df85-46f4-8c3b-d379e17096c1.png</url>
      <title>DEV Community: Rahil Khan</title>
      <link>https://dev.to/nexcodestudio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nexcodestudio"/>
    <language>en</language>
    <item>
      <title>Your Site Is Probably Missing a Real 404 Page (and It's Costing You Visitors)</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Fri, 30 Oct 2026 08:29:04 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-site-is-probably-missing-a-real-404-page-and-its-costing-you-visitors-3jj3</link>
      <guid>https://dev.to/nexcodestudio/your-site-is-probably-missing-a-real-404-page-and-its-costing-you-visitors-3jj3</guid>
      <description>&lt;p&gt;Old links never fully die. Someone bookmarks a page, a blog links to an old URL, you rename a service page, and suddenly people land on a blank "Not Found" screen and leave.&lt;/p&gt;

&lt;p&gt;A proper 404 page takes ten minutes and keeps those visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a good 404 page includes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A plain sentence&lt;/strong&gt; saying the page moved or doesn't exist (no jokes that hide the meaning).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Links to your top 3–5 pages&lt;/strong&gt;: home, services, pricing, contact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A search box&lt;/strong&gt; if your site has more than a handful of pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your normal header and footer&lt;/strong&gt;, so it still looks like your site.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Make sure it really returns 404
&lt;/h2&gt;

&lt;p&gt;A common mistake is a "not found" page that returns HTTP &lt;strong&gt;200&lt;/strong&gt;. Google then treats it as a real page ("soft 404"). Check it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://yoursite.com/this-page-does-not-exist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You want to see &lt;code&gt;404&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to set it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Netlify / Vercel / Cloudflare Pages:&lt;/strong&gt; add a &lt;code&gt;404.html&lt;/code&gt; at the site root.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache:&lt;/strong&gt; &lt;code&gt;ErrorDocument 404 /404.html&lt;/code&gt; in &lt;code&gt;.htaccess&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx:&lt;/strong&gt; &lt;code&gt;error_page 404 /404.html;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress:&lt;/strong&gt; most themes ship a &lt;code&gt;404.php&lt;/code&gt;; edit it to add your key links.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: fix the links that cause 404s
&lt;/h2&gt;

&lt;p&gt;When you rename a page, add a 301 redirect from the old URL to the new one. Then check Google Search Console's "Not found (404)" report once a month for old URLs that still get traffic.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;NEXCOD builds and fixes small business websites. &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>ux</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Your contact form emails might be landing in spam. Check SPF, DKIM and DMARC in 10 minutes</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Sun, 25 Oct 2026 08:34:33 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-contact-form-emails-might-be-landing-in-spam-check-spf-dkim-and-dmarc-in-10-minutes-32i6</link>
      <guid>https://dev.to/nexcodestudio/your-contact-form-emails-might-be-landing-in-spam-check-spf-dkim-and-dmarc-in-10-minutes-32i6</guid>
      <description>&lt;p&gt;A common small-business problem: the website contact form "works", but the owner never sees the messages. Often the form is sending mail that claims to come from your domain without your domain saying it's allowed to, so Gmail and Outlook quietly file it as spam.&lt;/p&gt;

&lt;p&gt;Three DNS records fix most of this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. SPF: say which servers may send for your domain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One TXT record on your root domain listing your senders, for example Google Workspace plus a form service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v=spf1 include:_spf.google.com include:sendgrid.net ~all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only one SPF record per domain. If you already have one, add the new &lt;code&gt;include:&lt;/code&gt; to it instead of creating a second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. DKIM: sign the mail&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your email provider or form service gives you a DKIM record (usually a TXT or CNAME at something like &lt;code&gt;google._domainkey&lt;/code&gt;). Add it exactly as shown, then turn signing on in their dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. DMARC: tell inboxes what to do with failures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start in monitor mode so nothing breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_dmarc.yourdomain.com  TXT  "v=DMARC1; p=none; rua=mailto:you@yourdomain.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a couple of weeks of clean reports, move to &lt;code&gt;p=quarantine&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two form-specific checks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send the form from an address on your own domain (like &lt;code&gt;forms@yourdomain.com&lt;/code&gt;) that your SPF/DKIM covers, not from the visitor's email address. Put the visitor's address in &lt;code&gt;Reply-To&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;Submit a test and open the received email's "Show original" in Gmail. You want &lt;code&gt;SPF: PASS&lt;/code&gt;, &lt;code&gt;DKIM: PASS&lt;/code&gt; and &lt;code&gt;DMARC: PASS&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick test from the terminal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig +short TXT yourdomain.com
dig +short TXT _dmarc.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the first shows no &lt;code&gt;v=spf1&lt;/code&gt; line or the second is empty, that's your starting point.&lt;/p&gt;

&lt;p&gt;Ten minutes of DNS work can be the difference between a form that brings in clients and one that silently loses them.&lt;/p&gt;

&lt;p&gt;From NEXCOD, a small web studio that fixes and builds websites for small businesses: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>email</category>
      <category>dns</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Your Google Maps and YouTube embeds are slowing your homepage. Load them on click instead</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Sat, 24 Oct 2026 08:30:49 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-google-maps-and-youtube-embeds-are-slowing-your-homepage-load-them-on-click-instead-5a27</link>
      <guid>https://dev.to/nexcodestudio/your-google-maps-and-youtube-embeds-are-slowing-your-homepage-load-them-on-click-instead-5a27</guid>
      <description>&lt;p&gt;A lot of small-business homepages embed a Google Map in the footer and a YouTube video in the middle. Each embed is an iframe that pulls in its own scripts, fonts and images, often more than the rest of the page combined, and it loads even for visitors who never scroll that far.&lt;/p&gt;

&lt;p&gt;Two easy fixes, from least to most effort:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Lazy-load the iframe&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Browsers support native lazy loading on iframes. Add one attribute and the embed waits until the visitor scrolls near it:&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;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.google.com/maps/embed?pb=..."&lt;/span&gt;
        &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;
        &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
        &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Map to our shop"&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border:0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the &lt;code&gt;width&lt;/code&gt;/&lt;code&gt;height&lt;/code&gt; so the layout doesn't jump when it loads, and add a &lt;code&gt;title&lt;/code&gt; for screen readers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Show a placeholder and load the real embed on click&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For YouTube, show the thumbnail with a play button and only swap in the iframe when someone taps it:&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;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"yt"&lt;/span&gt; &lt;span class="na"&gt;data-id=&lt;/span&gt;&lt;span class="s"&gt;"VIDEO_ID"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Play video"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://i.ytimg.com/vi/VIDEO_ID/hqdefault.jpg"&lt;/span&gt;
       &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"360"&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;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;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;.yt&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;b&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iframe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://www.youtube-nocookie.com/embed/&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="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?autoplay=1`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autoplay; encrypted-media&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowFullscreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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="nf"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&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;For the map, a static screenshot of your location linked to &lt;code&gt;https://maps.google.com/?q=Your+Business+Name&lt;/code&gt; often does the job just as well, and it opens the Maps app directly on phones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to check the difference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run your homepage through PageSpeed Insights before and after. On sites with both embeds above the fold, the "Reduce unused JavaScript" warning usually shrinks a lot and the page becomes usable sooner on mobile.&lt;/p&gt;




&lt;p&gt;NEXCOD builds and fixes fast websites for small businesses: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>html</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Is your website accidentally hidden from Google? Check noindex and robots.txt in 5 minutes</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Fri, 23 Oct 2026 08:32:38 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/is-your-website-accidentally-hidden-from-google-check-noindex-and-robotstxt-in-5-minutes-43j2</link>
      <guid>https://dev.to/nexcodestudio/is-your-website-accidentally-hidden-from-google-check-noindex-and-robotstxt-in-5-minutes-43j2</guid>
      <description>&lt;p&gt;Your new website might be invisible to Google, and nothing on the page will tell you. The two most common reasons are a "noindex" tag left over from the build and a &lt;code&gt;robots.txt&lt;/code&gt; that blocks the whole site. Both are often switched on while a site is being built and then forgotten at launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Check for a leftover noindex tag&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your homepage, press Ctrl+U (View Source) and search for &lt;code&gt;noindex&lt;/code&gt;. If you find this, Google is being told not to list the page:&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"robots"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"noindex, nofollow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On WordPress, go to Settings → Reading and make sure &lt;strong&gt;"Discourage search engines from indexing this site"&lt;/strong&gt; is unticked. Many builders and staging tools tick it by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Check robots.txt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Visit &lt;code&gt;yourdomain.com/robots.txt&lt;/code&gt;. This blocks everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;User&lt;/span&gt;-agent: *
Disallow: /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A normal small-business site usually needs only this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User-agent: *
Disallow:
Sitemap: https://yourdomain.com/sitemap.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Check the server header too&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some hosts add the noindex as an HTTP header instead of a tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://yourdomain.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; x-robots-tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that prints &lt;code&gt;noindex&lt;/code&gt;, fix it in the host or server config.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Confirm with Google&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Google Search Console, paste your homepage URL into URL Inspection. It tells you whether the page is indexed and, if not, why. After fixing, click "Request indexing".&lt;/p&gt;

&lt;p&gt;Five minutes of checking can be the difference between a site that brings enquiries and one nobody can find.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;NEXCOD builds and fixes fast, mobile-first websites for small businesses. &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>wordpress</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Make your contact form 2x faster to fill on phones: autocomplete and inputmode in 10 minutes</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Thu, 22 Oct 2026 08:33:20 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/make-your-contact-form-2x-faster-to-fill-on-phones-autocomplete-and-inputmode-in-10-minutes-51m7</link>
      <guid>https://dev.to/nexcodestudio/make-your-contact-form-2x-faster-to-fill-on-phones-autocomplete-and-inputmode-in-10-minutes-51m7</guid>
      <description>&lt;p&gt;Most small-business contact and booking forms are filled in on phones. Two tiny HTML attributes decide whether that takes 10 seconds or a minute of fiddly typing: &lt;code&gt;autocomplete&lt;/code&gt; and &lt;code&gt;inputmode&lt;/code&gt;. Most themes leave both out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Let the browser fill details for the visitor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Phones already know the visitor's name, email, phone number and address. Tell the browser which field is which, and it offers to fill them in one tap:&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;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;  &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"tel"&lt;/span&gt;   &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"tel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"city"&lt;/span&gt;  &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"address-level2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"zip"&lt;/span&gt;   &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"postal-code"&lt;/span&gt; &lt;span class="na"&gt;inputmode=&lt;/span&gt;&lt;span class="s"&gt;"numeric"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid &lt;code&gt;autocomplete="off"&lt;/code&gt; on contact fields. It doesn't make anything safer here; it only slows people down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Show the right keyboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type="tel"&lt;/code&gt; opens the number pad, &lt;code&gt;type="email"&lt;/code&gt; adds the @ key. For numbers that aren't phone numbers (quantity, guests, PIN code), use &lt;code&gt;inputmode="numeric"&lt;/code&gt; instead of &lt;code&gt;type="number"&lt;/code&gt;, which adds spinner arrows and can mangle leading zeros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Label every field properly&lt;/strong&gt;&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;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Phone (for a quick call back)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"tel"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"tel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Placeholder text disappears as soon as someone types, so it's not a label. A real &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; also makes the tap target bigger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Test it in 2 minutes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the form on your own phone and tap the first field. If the keyboard offers your saved name/email/phone, it works. If you have to type everything by hand, your visitors do too, and some give up.&lt;/p&gt;

&lt;p&gt;Fewer abandoned forms means more enquiries from the same traffic, with zero extra ad spend.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;NEXCOD builds and fixes fast, mobile-first websites for small businesses. &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>forms</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Your hero image is probably lazy-loaded (and that's slowing your homepage): a 10-minute LCP fix</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:31:26 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-hero-image-is-probably-lazy-loaded-and-thats-slowing-your-homepage-a-10-minute-lcp-fix-51g8</link>
      <guid>https://dev.to/nexcodestudio/your-hero-image-is-probably-lazy-loaded-and-thats-slowing-your-homepage-a-10-minute-lcp-fix-51g8</guid>
      <description>&lt;p&gt;On most small-business homepages, the slowest thing a visitor waits for is the big hero photo at the top. Google calls this the &lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt; element, and it's one of the Core Web Vitals. The common mistake: a theme or plugin adds &lt;code&gt;loading="lazy"&lt;/code&gt; to &lt;em&gt;every&lt;/em&gt; image, including the hero, so the browser deliberately waits before fetching the one image people see first.&lt;/p&gt;

&lt;p&gt;Here's a 10-minute fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Find your LCP element&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Chrome DevTools, go to &lt;strong&gt;Lighthouse&lt;/strong&gt;, run a mobile report, and look for "Largest Contentful Paint element". On most local-business sites it's the hero image or a background image in the first section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Never lazy-load it&lt;/strong&gt;&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="c"&gt;&amp;lt;!-- Bad: the browser waits until layout to fetch it --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/img/hero.webp"&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Our bakery counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Good: fetched immediately, with high priority --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/img/hero.webp"&lt;/span&gt; &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt;
     &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Our bakery counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep &lt;code&gt;loading="lazy"&lt;/code&gt; for images further down the page. That's where it helps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. If the hero is a CSS background, preload it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser can't discover CSS background images until it has downloaded and parsed the stylesheet. Tell it early:&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;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"preload"&lt;/span&gt; &lt;span class="na"&gt;as=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/img/hero.webp"&lt;/span&gt; &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Make the file small enough to matter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Priority doesn't help a 3 MB JPEG. Export the hero as WebP or AVIF at the width it's actually displayed (around 1200 to 1600px for desktop) and use &lt;code&gt;srcset&lt;/code&gt; so phones get a smaller one:&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/img/hero-1200.webp"&lt;/span&gt;
     &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"/img/hero-640.webp 640w, /img/hero-1200.webp 1200w"&lt;/span&gt;
     &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"100vw"&lt;/span&gt; &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Re-test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run Lighthouse again. On the small-business sites we work on, these steps alone usually move LCP noticeably, without touching any other code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Hero image is not &lt;code&gt;loading="lazy"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Hero has &lt;code&gt;fetchpriority="high"&lt;/code&gt; (or a preload if it's a CSS background)&lt;/li&gt;
&lt;li&gt;[ ] Hero is WebP/AVIF, sized to its display width, with &lt;code&gt;srcset&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Width and height set to avoid layout shift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd rather have someone do it for you, NEXCOD builds and fixes fast websites for small businesses: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;nexcod.vercel.app&lt;/a&gt; or WhatsApp +1 289 902 5119.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>html</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Repeat visitors shouldn't re-download your logo: Cache-Control headers for small-business sites in 10 minutes</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Tue, 20 Oct 2026 08:28:49 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/repeat-visitors-shouldnt-re-download-your-logo-cache-control-headers-for-small-business-sites-in-3mck</link>
      <guid>https://dev.to/nexcodestudio/repeat-visitors-shouldnt-re-download-your-logo-cache-control-headers-for-small-business-sites-in-3mck</guid>
      <description>&lt;p&gt;Every time someone opens your site a second time, their browser asks: "do I still have a good copy of this logo, this CSS, this font?" If your server never answers that question, the browser plays safe and downloads everything again. On a small-business site with a big hero photo and a couple of web fonts, that's often 1–3 MB per visit wasted, and it's the people on slow mobile data who feel it most.&lt;/p&gt;

&lt;p&gt;The fix is one HTTP header: &lt;code&gt;Cache-Control&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Check what you're sending now&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your site, then DevTools → Network, reload, click your logo or main CSS file and look at &lt;strong&gt;Response Headers&lt;/strong&gt;. Or from a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://yoursite.com/images/logo.png | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"cache-control|expires|etag"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;Cache-Control&lt;/code&gt; at all, or &lt;code&gt;max-age=0&lt;/code&gt; on images and fonts, means repeat visitors re-download them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The simple rule set&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTML pages:&lt;/strong&gt; short or no cache, so content updates show up right away: &lt;code&gt;Cache-Control: no-cache&lt;/code&gt; (the browser keeps a copy but checks with the server first).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images, fonts, CSS, JS that change rarely:&lt;/strong&gt; cache for a long time: &lt;code&gt;Cache-Control: public, max-age=31536000, immutable&lt;/code&gt; &lt;strong&gt;only if&lt;/strong&gt; the file name changes when the file changes (e.g. &lt;code&gt;style.3f9a1c.css&lt;/code&gt;, which most build tools do for you).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static files without versioned names&lt;/strong&gt; (a plain &lt;code&gt;logo.png&lt;/code&gt; you might replace): something moderate like &lt;code&gt;max-age=604800&lt;/code&gt; (7 days).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Copy-paste configs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache (&lt;code&gt;.htaccess&lt;/code&gt;, common on shared hosting):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="sr"&gt; mod_headers.c&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="sr"&gt; "\.(png|jpe?g|webp|svg|woff2|ico)$"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Cache-Control "public, max-age=604800"
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="sr"&gt; "\.(html)$"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Cache-Control "no-cache"
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;.(png|jpe?g|webp|svg|woff2|ico)&lt;/span&gt;$ &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Cache-Control&lt;/span&gt; &lt;span class="s"&gt;"public,&lt;/span&gt; &lt;span class="s"&gt;max-age=604800"&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;Netlify (&lt;code&gt;_headers&lt;/code&gt; file in your publish folder):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="err"&gt;/&lt;/span&gt;images/*
  &lt;span class="nc"&gt;Cache&lt;/span&gt;-Control: public, max-age=604800
&lt;span class="err"&gt;/&lt;/span&gt;assets/*
  &lt;span class="nc"&gt;Cache&lt;/span&gt;-Control: public, max-age=31536000, immutable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vercel (&lt;code&gt;vercel.json&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/images/(.*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cache-Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"public, max-age=604800"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WordPress: most caching plugins have a "browser caching" toggle that writes the Apache rules above for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Verify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reload twice with DevTools open. On the second load, images and fonts should show &lt;code&gt;(memory cache)&lt;/code&gt; or &lt;code&gt;(disk cache)&lt;/code&gt; in the Size column instead of a download size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The one mistake to avoid&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't put a one-year &lt;code&gt;immutable&lt;/code&gt; cache on a file you'll later overwrite with the same name. Visitors will keep the old version for months. Long caches are for versioned file names only.&lt;/p&gt;

&lt;p&gt;Ten minutes of config, and every returning customer gets a noticeably faster site.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;NEXCOD builds and fixes fast websites for small businesses. &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>http</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Your small-business site is slow because of scripts you forgot about: a 15-minute third-party script audit</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Mon, 19 Oct 2026 08:32:51 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-small-business-site-is-slow-because-of-scripts-you-forgot-about-a-15-minute-third-party-2cb6</link>
      <guid>https://dev.to/nexcodestudio/your-small-business-site-is-slow-because-of-scripts-you-forgot-about-a-15-minute-third-party-2cb6</guid>
      <description>&lt;p&gt;Chat widgets, review badges, three analytics tags, a Facebook pixel nobody checks, an old popup plugin... Third-party scripts pile up on small-business sites, and each one adds download time, blocks the page from becoming usable, and can break when the vendor changes something.&lt;/p&gt;

&lt;p&gt;Here's the 15-minute audit we run before touching anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. List what's actually loading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your homepage, then DevTools → Network → filter by &lt;strong&gt;JS&lt;/strong&gt;, reload, and sort by &lt;strong&gt;Domain&lt;/strong&gt;. Everything not on your own domain is third-party. Or paste this in the Console:&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="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="nx"&gt;scripts&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;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;src&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;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&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;src&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&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;2. Ask three questions per script&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does someone on the team actually use the data or feature? (If nobody has opened that heatmap tool in a year, remove it.)&lt;/li&gt;
&lt;li&gt;Is it loaded twice? (Common: GA added by a theme &lt;em&gt;and&lt;/em&gt; by a plugin.)&lt;/li&gt;
&lt;li&gt;Does it need to be on every page? (A booking widget only needs the booking page.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Load the survivors politely&lt;/strong&gt;&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="c"&gt;&amp;lt;!-- Doesn't block rendering, runs after HTML is parsed --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://example-widget.com/widget.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Independent scripts like analytics can use async --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.googletagmanager.com/gtag/js?id=G-XXXX"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For heavy chat widgets, load them only after the visitor interacts:&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;let&lt;/span&gt; &lt;span class="nx"&gt;loaded&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadChat&lt;/span&gt;&lt;span class="p"&gt;()&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;loaded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;loaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;s&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example-chat.com/loader.js&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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="s1"&gt;scroll&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;mousemove&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;touchstart&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;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loadChat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;once&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;4. Re-test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run Lighthouse (or PageSpeed Insights) before and after. Removing two or three unused tags often cuts seconds off "Time to Interactive" on mobile.&lt;/p&gt;

&lt;p&gt;Fewer scripts = faster site, fewer things that can break, and less visitor data handed to vendors you forgot about.&lt;/p&gt;

&lt;p&gt;We do this audit on every site we take over at &lt;strong&gt;NEXCOD&lt;/strong&gt;. Studio: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>javascript</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>Image alt text that actually helps: 4 rules for small-business sites (plus a 1-line audit)</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Sun, 18 Oct 2026 08:33:38 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/image-alt-text-that-actually-helps-4-rules-for-small-business-sites-plus-a-1-line-audit-39lf</link>
      <guid>https://dev.to/nexcodestudio/image-alt-text-that-actually-helps-4-rules-for-small-business-sites-plus-a-1-line-audit-39lf</guid>
      <description>&lt;p&gt;Most small-business sites either skip image alt text or stuff it with keywords ("best plumber city plumber cheap plumber"). Both hurt. Good alt text helps people using screen readers, shows up when an image fails to load, and gives Google real context for image search.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 4 rules we use&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Describe what matters, in one short sentence.&lt;/strong&gt; Imagine reading the page aloud to someone over the phone.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Bad --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"img_0423.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"team.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"plumber plumbing best plumber services"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Good --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"team.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Three technicians in blue uniforms standing next to a service van"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decorative images get an empty alt.&lt;/strong&gt; Background swirls, dividers and icons next to text should be skipped by screen readers:
&lt;/li&gt;
&lt;/ol&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"divider.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Linked images describe the destination, not the picture.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"menu-thumb.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"View our full lunch menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Text inside an image goes in the alt.&lt;/strong&gt; If your banner says "20% off this week", the alt should say it too.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Quick audit:&lt;/strong&gt; open DevTools and run this in the console to list images missing alt:&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="nb"&gt;document&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;img:not([alt])&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;img&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ten minutes of fixes usually clears most accessibility warnings in Lighthouse.&lt;/p&gt;

&lt;p&gt;We bake this into every build at &lt;strong&gt;NEXCOD&lt;/strong&gt;. Studio: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>a11y</category>
      <category>seo</category>
    </item>
    <item>
      <title>Which visits turn into calls? Track WhatsApp and phone clicks in GA4 (15-minute setup)</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Sat, 17 Oct 2026 08:28:56 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/which-visits-turn-into-calls-track-whatsapp-and-phone-clicks-in-ga4-15-minute-setup-240h</link>
      <guid>https://dev.to/nexcodestudio/which-visits-turn-into-calls-track-whatsapp-and-phone-clicks-in-ga4-15-minute-setup-240h</guid>
      <description>&lt;p&gt;Most small-business sites have analytics installed, but nobody knows which visits actually turned into a call or a WhatsApp chat. Page views don't pay the bills. Clicks on "Call" and "WhatsApp" do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do (Google Analytics 4, about 15 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give your contact links a clear marker, e.g. &lt;code&gt;&amp;lt;a href="tel:+15551234567" class="track-call"&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;a href="https://wa.me/15551234567" class="track-wa"&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fire an event on click:
&lt;/li&gt;
&lt;/ol&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&amp;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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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;a.track-call, a.track-wa&lt;/span&gt;&lt;span class="dl"&gt;'&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;a&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;gtag&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;event&lt;/span&gt;&lt;span class="dl"&gt;'&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;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;track-call&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="s1"&gt;click_call&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;click_whatsapp&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;link_url&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;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;page_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&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;ol&gt;
&lt;li&gt;In GA4 go to Admin, Events, and mark &lt;code&gt;click_call&lt;/code&gt; and &lt;code&gt;click_whatsapp&lt;/code&gt; as key events.&lt;/li&gt;
&lt;li&gt;After a week, check which pages and traffic sources produce those clicks. That's where to spend effort.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No GA4? Plausible, Umami and similar privacy-friendly tools support the same custom-event idea.&lt;/p&gt;

&lt;p&gt;We set this up on client sites at &lt;strong&gt;NEXCOD&lt;/strong&gt; so owners can see what's working. Studio: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>smallbusiness</category>
      <category>analytics</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Your contact form is drowning in spam — add a honeypot field (no CAPTCHA needed)</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Fri, 16 Oct 2026 08:28:01 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/your-contact-form-is-drowning-in-spam-add-a-honeypot-field-no-captcha-needed-3l4n</link>
      <guid>https://dev.to/nexcodestudio/your-contact-form-is-drowning-in-spam-add-a-honeypot-field-no-captcha-needed-3l4n</guid>
      <description>&lt;p&gt;Most small-business sites get buried in fake "inquiry" emails. A CAPTCHA slows real customers. A honeypot is quieter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a text field named something boring like &lt;code&gt;company_url&lt;/code&gt; or &lt;code&gt;website2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Hide it with CSS (&lt;code&gt;position:absolute; left:-9999px&lt;/code&gt; or &lt;code&gt;display:none&lt;/code&gt; — bots still fill it).&lt;/li&gt;
&lt;li&gt;On submit: if that field has any value, discard the message silently. Don't tell the bot it failed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Real humans never see it. Spam drops hard. Optional: also rate-limit by IP if your host allows it.&lt;/p&gt;

&lt;p&gt;Built this into client contact forms at &lt;strong&gt;NEXCOD&lt;/strong&gt; when inbox noise was the complaint. Studio: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;https://nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>smallbusiness</category>
      <category>security</category>
      <category>forms</category>
    </item>
    <item>
      <title>Make text show up instantly: one CSS line most small-business sites miss</title>
      <dc:creator>Rahil Khan</dc:creator>
      <pubDate>Thu, 15 Oct 2026 08:36:13 +0000</pubDate>
      <link>https://dev.to/nexcodestudio/make-text-show-up-instantly-one-css-line-most-small-business-sites-miss-1le8</link>
      <guid>https://dev.to/nexcodestudio/make-text-show-up-instantly-one-css-line-most-small-business-sites-miss-1le8</guid>
      <description>&lt;p&gt;When your site loads custom fonts, Chrome often hides all text until the font file arrives. Visitors stare at a blank page for a second or two — and bounce.&lt;/p&gt;

&lt;p&gt;Fix it with one line on your &lt;code&gt;@font-face&lt;/code&gt; rule or Google Fonts link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;font-display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;swap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or on a Google Fonts URL, add &lt;code&gt;&amp;amp;display=swap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Text shows immediately in a system font, then swaps to your brand font when ready. Pair it with a similar fallback (&lt;code&gt;system-ui, Arial, sans-serif&lt;/code&gt;) so the swap is barely noticeable.&lt;/p&gt;

&lt;p&gt;This is a five-minute change that improves perceived speed on almost every small-business site we audit.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NEXCOD&lt;/strong&gt; builds and polishes websites for local and online businesses.&lt;br&gt;&lt;br&gt;
Free look: &lt;a href="https://nexcod.vercel.app" rel="noopener noreferrer"&gt;nexcod.vercel.app&lt;/a&gt; · WhatsApp +1 289 902 5119&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>performance</category>
      <category>smallbusiness</category>
    </item>
  </channel>
</rss>
