<?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: Ryan VerWey</title>
    <description>The latest articles on DEV Community by Ryan VerWey (@rverwey).</description>
    <link>https://dev.to/rverwey</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%2F1213395%2Fb0a67ef6-3d3c-41a1-b327-06e902153dc4.png</url>
      <title>DEV Community: Ryan VerWey</title>
      <link>https://dev.to/rverwey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rverwey"/>
    <language>en</language>
    <item>
      <title>Publish First, Syndicate Later: Automating Dev.to Without Losing SEO Credit</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Fri, 21 Aug 2026 14:43:05 +0000</pubDate>
      <link>https://dev.to/rverwey/publish-first-syndicate-later-automating-devto-without-losing-seo-credit-4akm</link>
      <guid>https://dev.to/rverwey/publish-first-syndicate-later-automating-devto-without-losing-seo-credit-4akm</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.ryanverwey.dev/blog/automate-nextjs-blog-devto-canonical-delay" rel="noopener noreferrer"&gt;ryanverwey.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you publish articles on a Next.js portfolio or agency website, Dev.to can be a useful syndication channel. You get distribution in a developer community, another place for people to discover your work, and a canonical backlink pointing to the original article on your own domain.&lt;/p&gt;

&lt;p&gt;The important part is order.&lt;/p&gt;

&lt;p&gt;Publish on your website first. Give search engines time to crawl your original page. Then publish the Dev.to copy with a canonical URL that points back to your site. That is how you use syndication for reach without teaching Google that the copy is the source of truth.&lt;/p&gt;

&lt;p&gt;This guide walks through a practical setup: a Next.js blog, an RSS feed or local Markdown files, a Dev.to API key stored as a GitHub secret, a daily GitHub Actions workflow, and a script that waits three days before posting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Publish the original post on your own domain, wait three days, then post the Dev.to copy with &lt;code&gt;canonical_url&lt;/code&gt; set to your original URL. Include the cover image, convert body images to absolute URLs, and send no more than four Dev.to tags.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Syndicate to Dev.to at All?
&lt;/h2&gt;

&lt;p&gt;Your portfolio blog is the source of truth. That is where you own the domain, the analytics, the internal links, the service pages, the calls to action, and the long-term SEO value.&lt;/p&gt;

&lt;p&gt;Dev.to is different. It is a discovery channel.&lt;/p&gt;

&lt;p&gt;When you syndicate correctly, Dev.to can help with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Getting technical articles in front of readers who may never find your personal site first.&lt;/li&gt;
&lt;li&gt;Creating a clean attribution path from a high-authority community platform back to your original post.&lt;/li&gt;
&lt;li&gt;Building repeatable distribution without manually copying every article.&lt;/li&gt;
&lt;li&gt;Keeping your writing workflow centered on your own website, not on rented platforms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The danger is duplicate content confusion. If the same article appears on your site and on Dev.to at the same time, Google has to decide which URL represents the original. Google recommends using canonical links in the HTML head and using absolute URLs for canonical annotations. DEV also documents a canonical URL field for imported or manually created posts, specifically so the original source can keep SEO credit.&lt;/p&gt;

&lt;p&gt;That is why the delay matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Three-Day Delay Does
&lt;/h2&gt;

&lt;p&gt;A three-day delay is not a magic ranking switch. It is a practical buffer.&lt;/p&gt;

&lt;p&gt;When a new article goes live on your portfolio, you want search engines to see your domain first. The delay gives you time to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the post.&lt;/li&gt;
&lt;li&gt;Confirm the article URL returns &lt;code&gt;200&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Confirm the canonical tag on your site points to itself.&lt;/li&gt;
&lt;li&gt;Let your sitemap, RSS feed, and internal links expose the original before Dev.to sees the copy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After that delay, the Dev.to version should point back to the original with &lt;code&gt;canonical_url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Think of the Dev.to article as a syndicated copy with a signpost. The signpost says, "This is useful here, but the original lives over there."&lt;/p&gt;

&lt;p&gt;For high-priority posts, you can also request indexing in Google Search Console. Treat that as an acceleration option, not as a required step in the recurring automation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcy8ru7zm2xeix8326dh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcy8ru7zm2xeix8326dh.webp" alt="Canonical syndication timeline showing original publication, sitemap discovery, crawler review, a three-day delay window, and the syndicated copy pointing back to the source article" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Are Building
&lt;/h2&gt;

&lt;p&gt;The automation has six parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Next.js blog source, usually Markdown or MDX files.&lt;/li&gt;
&lt;li&gt;A canonical URL for every article on your own domain.&lt;/li&gt;
&lt;li&gt;An RSS feed or script that can read each article's title, summary, body, date, image, and tags.&lt;/li&gt;
&lt;li&gt;A Dev.to API key stored outside your repo.&lt;/li&gt;
&lt;li&gt;A sync script that publishes only eligible posts.&lt;/li&gt;
&lt;li&gt;A scheduled GitHub Actions workflow that runs daily.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The workflow should do this every time it runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read all local blog posts.&lt;/li&gt;
&lt;li&gt;Skip posts newer than three days.&lt;/li&gt;
&lt;li&gt;Build the original URL from the post slug.&lt;/li&gt;
&lt;li&gt;Check Dev.to for an existing article with that canonical URL.&lt;/li&gt;
&lt;li&gt;Convert MDX or HTML-only content into Dev.to-friendly Markdown.&lt;/li&gt;
&lt;li&gt;Make images absolute so they work away from your website.&lt;/li&gt;
&lt;li&gt;Send up to four relevant Dev.to tags.&lt;/li&gt;
&lt;li&gt;Create the Dev.to article with &lt;code&gt;canonical_url&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjtbh4qni4m1o8ydioi5v.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjtbh4qni4m1o8ydioi5v.webp" alt="Dark-mode GitHub Actions style automation workflow showing content parsing, eligibility filtering, image URL conversion, tag normalization, secret-protected API publishing, and successful publication" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Confirm Your Next.js Blog Has Stable Slugs
&lt;/h2&gt;

&lt;p&gt;Most Next.js portfolio blogs use one file per post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;content/blog/my-article-slug.mdx
content/blog/another-article.mdx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filename becomes the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.yourdomain.com/blog/my-article-slug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you automate anything, make that contract reliable. Your script needs one predictable way to turn a file into a URL.&lt;/p&gt;

&lt;p&gt;For example:&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;SITE_URL&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://www.yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&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="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;mdx&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canonicalUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not use localhost URLs, preview deployment URLs, random query strings, or relative canonical paths. The canonical URL should be the final public article URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Add Self-Referential Canonical Tags on Your Site
&lt;/h2&gt;

&lt;p&gt;Every original article should include a canonical tag in the HTML head that points to itself:&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;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.yourdomain.com/blog/my-article-slug"&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;In the Next.js App Router, this usually belongs in &lt;code&gt;generateMetadata&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Metadata&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateMetadata&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;PageProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Metadata&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getBlogPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&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;canonical&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://www.yourdomain.com/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alternates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;openGraph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;images&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="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;630&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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="na"&gt;twitter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;card&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;summary_large_image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banner&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this matters: your own page should clearly say, "I am the canonical version." The Dev.to copy will later say the same thing from the other direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Make Your Blog Frontmatter Syndication-Ready
&lt;/h2&gt;

&lt;p&gt;Each post needs enough metadata to become a Dev.to article without manual cleanup.&lt;/p&gt;

&lt;p&gt;Use a frontmatter shape like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Improve&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Portfolio&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Website"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-08-18"&lt;/span&gt;
&lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;practical&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;guide&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;improving&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;portfolio&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;website&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;better&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;structure,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;speed,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;images,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;calls&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action."&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Next.js"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SEO"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Portfolio"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Web&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Development"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Web&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Development"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;banner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/images/blog/example-cover.webp"&lt;/span&gt;
&lt;span class="na"&gt;updatedTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-08-18"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key fields for Dev.to are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Becomes the Dev.to article title.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;summary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Becomes the Dev.to description.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Controls the three-day delay.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;banner&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Becomes the Dev.to &lt;code&gt;main_image&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Becomes Dev.to topic tags.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use a public image for &lt;code&gt;banner&lt;/code&gt;. Dev.to is not reading your site from the same origin, so a local image path like &lt;code&gt;/images/blog/cover.webp&lt;/code&gt; needs to be converted to &lt;code&gt;https://www.yourdomain.com/images/blog/cover.webp&lt;/code&gt; before publishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Decide How Images Should Travel
&lt;/h2&gt;

&lt;p&gt;Images fail in syndication more often than text.&lt;/p&gt;

&lt;p&gt;There are two image types to handle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The article cover image.&lt;/li&gt;
&lt;li&gt;Images inside the article body.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the cover image, send Dev.to a public image URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;main_image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;absoluteUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For body images, convert local paths to absolute URLs before publishing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeImageUrlsAbsolute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;siteUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;markdown&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="sr"&gt;/!&lt;/span&gt;&lt;span class="se"&gt;\\[&lt;/span&gt;&lt;span class="sr"&gt;([^&lt;/span&gt;&lt;span class="se"&gt;\\]&lt;/span&gt;&lt;span class="sr"&gt;]*&lt;/span&gt;&lt;span class="se"&gt;)\\&lt;/span&gt;&lt;span class="sr"&gt;]&lt;/span&gt;&lt;span class="se"&gt;\\((\\&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`![&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;siteUrl&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="s2"&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;If your posts use custom MDX components like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BlogImage
  src="/images/blog/example.webp"
  alt="Dashboard on a laptop"
  caption="Use real images that explain the article."
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert them before sending to Dev.to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;convertBlogImages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;siteUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;markdown&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="sr"&gt;/&amp;lt;BlogImage&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sr"&gt;s+&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?)\\&lt;/span&gt;&lt;span class="sr"&gt;s*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sr"&gt;/gs, &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;_, attrs&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; =&amp;gt; &lt;/span&gt;&lt;span class="err"&gt;{
&lt;/span&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/src=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&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;alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/alt=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;caption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/caption=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&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;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;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageUrl&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;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&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="nx"&gt;src&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;siteUrl&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="s2"&gt;`&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`![&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;caption&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n*&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;*`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;image&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;Why this matters: the Dev.to API accepts Markdown. It does not understand your custom React components. Convert the content before it leaves your site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpw6vi89m9q3gfei0m7fm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpw6vi89m9q3gfei0m7fm.webp" alt="Canonical signal matrix comparing the original portfolio article and the DEV.to syndicated copy across publishing order, canonical signals, image handling, topic tags, and failure modes" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Make Search Console Optional
&lt;/h2&gt;

&lt;p&gt;The normal workflow should not depend on a person submitting every URL by hand. Your automation should rely on stable article URLs, self-referential canonicals, a sitemap, internal links, RSS discovery, and the three-day Dev.to delay.&lt;/p&gt;

&lt;p&gt;For high-priority posts, request indexing for the original article as an optional acceleration step.&lt;/p&gt;

&lt;p&gt;Click-by-click:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://search.google.com/search-console" rel="noopener noreferrer"&gt;Google Search Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Select the property for your website.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;URL Inspection&lt;/strong&gt; search bar at the top.&lt;/li&gt;
&lt;li&gt;Paste the full original article URL.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Wait for Google to inspect the URL.&lt;/li&gt;
&lt;li&gt;If the page is live, click &lt;strong&gt;Request Indexing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Wait for the confirmation message.&lt;/li&gt;
&lt;li&gt;Let the automated Dev.to workflow handle normal syndication after the three-day delay.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is not required for Dev.to automation to work. It is useful when a post is especially important, timely, or tied to a campaign. For routine posts, let the automated workflow run without a manual Search Console task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Create a Dev.to API Key
&lt;/h2&gt;

&lt;p&gt;Do this from the Dev.to website:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to Dev.to.&lt;/li&gt;
&lt;li&gt;Click your profile image in the top-right corner.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Extensions&lt;/strong&gt; in the settings sidebar.&lt;/li&gt;
&lt;li&gt;Scroll to &lt;strong&gt;DEV Community API Keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Type a short label, such as &lt;code&gt;GitHub blog syndication&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Generate API Key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Copy the key once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not paste the key into your source code. Do not commit it to GitHub. Do not put it in a public blog post, screenshot, issue, pull request, or README.&lt;/p&gt;

&lt;p&gt;The key belongs in your automation environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Store the API Key as a GitHub Secret
&lt;/h2&gt;

&lt;p&gt;If your portfolio is on GitHub, store the key as a repository secret:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your GitHub repository.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the left sidebar, click &lt;strong&gt;Secrets and variables&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;New repository secret&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name the secret &lt;code&gt;DEVTO_API_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Paste the Dev.to API key into the value field.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add secret&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your workflow will read it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;DEVTO_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEVTO_API_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That keeps the key out of your repo while still making it available to the scheduled job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Install the Packages Your Script Needs
&lt;/h2&gt;

&lt;p&gt;For an MDX or Markdown blog, a small Node script can usually do the job.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;gray-matter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you already have &lt;code&gt;gray-matter&lt;/code&gt;, you can skip that. Node 18 and newer includes &lt;code&gt;fetch&lt;/code&gt;, so you do not need a separate HTTP client in most modern Next.js projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 9: Add a Safe Tag Mapper
&lt;/h2&gt;

&lt;p&gt;Dev.to tags should be short, lowercase, and relevant. Most posts should use no more than four.&lt;/p&gt;

&lt;p&gt;Your website tags may be human-readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Web Development&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SEO&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Content Marketing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dev.to tags should look more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webdev&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;nextjs&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;seo&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;productivity&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;p&gt;Add a mapper:&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;TAG_MAP&lt;/span&gt; &lt;span class="o"&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;Web Development&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;webdev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SEO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;seo&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;Content Marketing&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;contentmarketing&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;Web Design&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;webdesign&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;JavaScript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Nextjs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextjs&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;normalizeDevToTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&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;normalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tags&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;tag&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;TAG_MAP&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;tag&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;tag&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;tag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&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="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="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalized&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;4&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;Why this matters: tags are distribution channels on Dev.to. Bad tags make the article harder to discover, and too many tags can cause publishing problems. Keep the set focused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10: Write the Sync Script
&lt;/h2&gt;

&lt;p&gt;Create a file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scripts/publish-devto.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a complete generic version you can adapt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:fs/promises&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;matter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray-matter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SITE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SITE_URL&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://www.yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DEVTO_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEVTO_API_KEY&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BLOG_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&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;blog&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;THREE_DAYS_MS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TAG_MAP&lt;/span&gt; &lt;span class="o"&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;Web Development&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;webdev&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;Web Design&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;webdesign&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SEO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;seo&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;Content Marketing&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;contentmarketing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;JavaScript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Nextjs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;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;DEVTO_API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing DEVTO_API_KEY.&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;postSlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fileName&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="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;mdx&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;canonicalForSlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;absoluteUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://&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="nx"&gt;url&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE_URL&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;normalizeDevToTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&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;const&lt;/span&gt; &lt;span class="nx"&gt;normalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tags&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;tag&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;TAG_MAP&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;tag&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;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&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="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="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalized&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;4&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;isAtLeastThreeDaysOld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&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;publishedTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getTime&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="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;publishedTime&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;publishedTime&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;THREE_DAYS_MS&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;convertBlogImages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;markdown&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="sr"&gt;/&amp;lt;BlogImage&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?)\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;/g&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="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;attrs&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;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/src=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&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;alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/alt=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;caption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/caption=&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]([^&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)[&lt;/span&gt;&lt;span class="sr"&gt;"'&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&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;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;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`![&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;absoluteUrl&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="s2"&gt;)`&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;caption&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n*&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;*`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;image&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;makeMarkdownPortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;convertBlogImages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&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="sr"&gt;/!&lt;/span&gt;&lt;span class="se"&gt;\[([^\]]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)\]\((\/[^&lt;/span&gt;&lt;span class="sr"&gt;)&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)\)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`![&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;absoluteUrl&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="s2"&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;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;Callout&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;gt; &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="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;Callout&amp;gt;/g&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;devToRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&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;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="s2"&gt;`https://dev.to/api&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&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="s1"&gt;api-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DEVTO_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&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="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&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="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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Dev.to request failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getExistingArticles&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;articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;for &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;page&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="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;page&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;batch&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;devToRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/articles/me/all?page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;per_page=100`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;batch&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;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&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;articles&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;publishArticle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;post&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="nx"&gt;canonicalUrl&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;devToRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/articles&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="s1"&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;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;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body_markdown&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="na"&gt;main_image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;absoluteUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;canonicalUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;normalizeDevToTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;published&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;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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;existingArticles&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;getExistingArticles&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;existingCanonicals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existingArticles&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;article&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;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&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="nb"&gt;Boolean&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;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BLOG_DIR&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;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;mdx&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="k"&gt;for &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;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&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;fullPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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="nx"&gt;BLOG_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&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;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;postSlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;canonicalUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;canonicalForSlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&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;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;matter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&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="nf"&gt;isAtLeastThreeDaysOld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&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="s2"&gt;`Skipping &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: younger than three days.`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;continue&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;existingCanonicals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonicalUrl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&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="s2"&gt;`Skipping &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: already syndicated.`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;continue&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;attribution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`*Originally published on [your portfolio](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;canonicalUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;).*`&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;attribution&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;makeMarkdownPortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;article&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;publishArticle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&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="nx"&gt;canonicalUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&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="s2"&gt;`Published &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3500&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;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are four important safety checks in that script:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It refuses to run without &lt;code&gt;DEVTO_API_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It skips posts younger than three days.&lt;/li&gt;
&lt;li&gt;It checks existing Dev.to posts by &lt;code&gt;canonical_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It spaces out publish requests to avoid unnecessary API pressure.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 11: Add Package Scripts
&lt;/h2&gt;

&lt;p&gt;Add scripts to &lt;code&gt;package.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;"scripts"&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;"publish:devto"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node scripts/publish-devto.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"publish:devto:dry-run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node scripts/publish-devto.mjs --dry-run"&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;If you want a safer first version, add a dry-run mode before allowing writes. A dry run should print what would be published without calling &lt;code&gt;POST /articles&lt;/code&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run publish:devto:dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script should print skipped and published posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Skipping new-post: younger than three days.
Skipping old-post: already syndicated.
Published eligible-post: https://dev.to/username/eligible-post-slug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 12: Create the GitHub Actions Workflow
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/workflows/devto-syndication.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use a daily schedule plus a manual trigger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dev.to Syndication&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;25&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;13&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;syndicate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DEVTO_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEVTO_API_KEY }}&lt;/span&gt;
      &lt;span class="na"&gt;SITE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://www.yourdomain.com&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check out repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish eligible posts to Dev.to&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run publish:devto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cron time does not need to be exact. Pick a quiet time. The script controls eligibility, not the workflow schedule.&lt;/p&gt;

&lt;p&gt;Why daily works: a post published Monday at noon becomes eligible Thursday at noon. The next daily run after that will post it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 13: Test the Workflow Without Publishing
&lt;/h2&gt;

&lt;p&gt;Before publishing anything, test locally with a dry run or a temporary logging-only script.&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;New posts are skipped.&lt;/li&gt;
&lt;li&gt;Old posts are eligible.&lt;/li&gt;
&lt;li&gt;Existing Dev.to posts are skipped.&lt;/li&gt;
&lt;li&gt;Canonical URLs are absolute and correct.&lt;/li&gt;
&lt;li&gt;Cover images are absolute.&lt;/li&gt;
&lt;li&gt;Body images are absolute.&lt;/li&gt;
&lt;li&gt;Tags are lowercase and limited to four.&lt;/li&gt;
&lt;li&gt;No API key is printed in the logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then run the GitHub Action manually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your GitHub repository.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Dev.to Syndication&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Run workflow&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose the branch.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Run workflow&lt;/strong&gt; again.&lt;/li&gt;
&lt;li&gt;Open the workflow run.&lt;/li&gt;
&lt;li&gt;Watch the log output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The logs should show skipped or published posts, but never the API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 14: Verify the Dev.to Article
&lt;/h2&gt;

&lt;p&gt;After the first publish, open the Dev.to article and check it manually.&lt;/p&gt;

&lt;p&gt;Confirm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The title is correct.&lt;/li&gt;
&lt;li&gt;The cover image appears.&lt;/li&gt;
&lt;li&gt;Body images appear.&lt;/li&gt;
&lt;li&gt;Code blocks are readable.&lt;/li&gt;
&lt;li&gt;Tables still make sense.&lt;/li&gt;
&lt;li&gt;The top attribution link points to the original post.&lt;/li&gt;
&lt;li&gt;The Dev.to canonical URL points to the original post.&lt;/li&gt;
&lt;li&gt;Tags are relevant and not spammy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you use the Dev.to editor, you can also check the canonical manually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Dev.to post.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open the post settings.&lt;/li&gt;
&lt;li&gt;Find &lt;strong&gt;Canonical URL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Confirm it matches your original article URL exactly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the basic Markdown editor, the same value may appear as frontmatter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;canonical_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://www.yourdomain.com/blog/my-article-slug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 15: Keep the Original URL Stable
&lt;/h2&gt;

&lt;p&gt;Canonical syndication depends on stable URLs.&lt;/p&gt;

&lt;p&gt;Avoid changing slugs after syndication. If you must change one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a permanent redirect from the old URL to the new URL.&lt;/li&gt;
&lt;li&gt;Update the Dev.to article's &lt;code&gt;canonical_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update the attribution link.&lt;/li&gt;
&lt;li&gt;Re-submit the new original URL in Google Search Console.&lt;/li&gt;
&lt;li&gt;Confirm the old URL does not return a broken page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Broken canonical URLs waste the value of the whole setup. A canonical tag that points to a 404 is not helping the original article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 16: Build a Post-Publish Checklist
&lt;/h2&gt;

&lt;p&gt;Automation should reduce manual work, not remove responsibility.&lt;/p&gt;

&lt;p&gt;Use this automation-first checklist for every new article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Article is live on your own domain.&lt;/li&gt;
&lt;li&gt;[ ] Original page returns &lt;code&gt;200&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Original page has a self-referential canonical URL.&lt;/li&gt;
&lt;li&gt;[ ] Original page has a usable title and meta description.&lt;/li&gt;
&lt;li&gt;[ ] Cover image is public and absolute.&lt;/li&gt;
&lt;li&gt;[ ] Body images are public or convertible to absolute URLs.&lt;/li&gt;
&lt;li&gt;[ ] Three days have passed.&lt;/li&gt;
&lt;li&gt;[ ] Dev.to copy includes &lt;code&gt;canonical_url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Dev.to copy includes the article image.&lt;/li&gt;
&lt;li&gt;[ ] Dev.to copy uses no more than four relevant tags.&lt;/li&gt;
&lt;li&gt;[ ] Dev.to copy includes attribution to the original post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional for priority posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Google Search Console indexing request is submitted for the original URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Helps With Canonical Link Equity
&lt;/h2&gt;

&lt;p&gt;"Link juice" is casual SEO language for link equity, authority, or ranking signals that flow through links and canonical relationships. The phrase is imperfect, but the practical goal is clear: you want the original article on your domain to receive the strongest possible credit.&lt;/p&gt;

&lt;p&gt;The setup supports that goal in four ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your site publishes first.&lt;/li&gt;
&lt;li&gt;Your original page declares itself canonical.&lt;/li&gt;
&lt;li&gt;Dev.to declares your original page as canonical.&lt;/li&gt;
&lt;li&gt;The Dev.to body includes a visible attribution link back to the original.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google still makes its own canonicalization decisions, and canonical tags are signals, not commands. But consistent signals matter. If your own page, your sitemap, your RSS feed, your Dev.to copy, and your internal links all point to the same original URL, you are making the decision easy for crawlers.&lt;/p&gt;

&lt;p&gt;That is the real purpose of the three-day delay. It gives the original article a head start before the high-authority duplicate appears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes to Avoid
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Do not publish to Dev.to immediately.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Give your site time to be crawled first. Three days is a practical default.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not forget the canonical URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without &lt;code&gt;canonical_url&lt;/code&gt;, Dev.to may become the stronger version in search simply because the platform has more authority than your portfolio.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not use relative image paths.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dev.to cannot reliably render &lt;code&gt;/images/blog/example.webp&lt;/code&gt; unless it knows your domain. Convert it to &lt;code&gt;https://www.yourdomain.com/images/blog/example.webp&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not send every website tag to Dev.to.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pick four relevant tags. Treat tags like reader targeting, not keyword stuffing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not expose your API key.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use GitHub Secrets, environment variables, or your deployment platform's secret manager.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not rewrite internal links to Dev.to.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the goal is canonical value for your site, keep links pointing back to your original domain where appropriate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Fallback: RSS Import
&lt;/h2&gt;

&lt;p&gt;If you do not want to use the API yet, Dev.to also supports RSS imports.&lt;/p&gt;

&lt;p&gt;Click-by-click:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to Dev.to.&lt;/li&gt;
&lt;li&gt;Click your profile image.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Extensions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Find &lt;strong&gt;Publishing to DEV Community from RSS&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Paste your RSS feed URL.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Mark the RSS source as canonical URL by default&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Save the feed settings.&lt;/li&gt;
&lt;li&gt;Review imported drafts before publishing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RSS import is simpler. The API workflow gives you more control over the three-day delay, image conversion, existing-post checks, and tag mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Recommended Workflow
&lt;/h2&gt;

&lt;p&gt;For a Next.js portfolio, the cleanest process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the blog post in your repo.&lt;/li&gt;
&lt;li&gt;Use an absolute cover image URL.&lt;/li&gt;
&lt;li&gt;Deploy the original post to your domain.&lt;/li&gt;
&lt;li&gt;Let the post sit for three days while your sitemap, feed, and internal links expose the original.&lt;/li&gt;
&lt;li&gt;Optionally request indexing in Google Search Console for priority posts.&lt;/li&gt;
&lt;li&gt;Run a scheduled GitHub Action every day.&lt;/li&gt;
&lt;li&gt;Have the script publish only eligible posts to Dev.to.&lt;/li&gt;
&lt;li&gt;Send &lt;code&gt;canonical_url&lt;/code&gt; with every Dev.to article.&lt;/li&gt;
&lt;li&gt;Include the main image and convert local body images.&lt;/li&gt;
&lt;li&gt;Limit Dev.to tags to four.&lt;/li&gt;
&lt;li&gt;Periodically audit Dev.to to make sure every syndicated article points back to the original.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the balance: own the original, syndicate for reach, and make every duplicate point back to your domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DEV Community Help, &lt;a href="https://dev.to/help/organizations/importing-your-organizations-content"&gt;"Importing Your Organization's Content"&lt;/a&gt;, accessed August 18, 2026.&lt;/li&gt;
&lt;li&gt;Forem API Docs, &lt;a href="https://developers.forem.com/api/v0#tag/articles/operation/createArticle" rel="noopener noreferrer"&gt;"Create a new article"&lt;/a&gt;, accessed August 18, 2026.&lt;/li&gt;
&lt;li&gt;Google Search Central, &lt;a href="https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls" rel="noopener noreferrer"&gt;"How to specify a canonical with rel=canonical and other methods"&lt;/a&gt;, accessed August 18, 2026.&lt;/li&gt;
&lt;li&gt;DEV Team, &lt;a href="https://dev.to/devteam/revamped-rss-feed-imports-3j1e"&gt;"Revamped RSS Feed Imports"&lt;/a&gt;, March 9, 2026.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>devto</category>
      <category>seo</category>
      <category>contentstrategy</category>
    </item>
    <item>
      <title>Social Media Content Calendar for Small Business Leads</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:30:52 +0000</pubDate>
      <link>https://dev.to/rverwey/social-media-content-calendar-for-small-business-leads-1g2d</link>
      <guid>https://dev.to/rverwey/social-media-content-calendar-for-small-business-leads-1g2d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/social-media-content-calendar-small-business-leads-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A social media content calendar should do more than remind you to post. For a small business, the useful version connects each post to an audience, a clear offer, a website destination, a tracking link, and a follow-up decision. That is how social media starts supporting leads instead of only producing likes.&lt;/p&gt;

&lt;p&gt;The short answer: plan one month at a time, publish consistently, send interested people to the right website page, tag links with campaign parameters, and review both platform insights and website traffic before changing the next month. Meta Business Suite can schedule Facebook and Instagram content and show paid and organic activity, while Google Analytics can identify campaigns that referred traffic to your site (Meta Business Help Center, n.d.-a; Google Analytics Help, n.d.-a).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; A strong content calendar is a conversion system. Every planned post should have a business role: awareness, trust-building, traffic, lead capture, retention, or direct offer support.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Most Content Calendars Fail
&lt;/h2&gt;

&lt;p&gt;Most small business calendars fail because they start with empty dates instead of business goals. The owner asks, "What should we post on Tuesday?" instead of "What decision do we want a real customer to make this month?"&lt;/p&gt;

&lt;p&gt;That produces a familiar pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Random holidays that do not connect to the offer.&lt;/li&gt;
&lt;li&gt;Platform trends copied without a clear audience fit.&lt;/li&gt;
&lt;li&gt;Posts that get engagement but send nobody to the website.&lt;/li&gt;
&lt;li&gt;Links with no UTM tracking, so traffic becomes hard to attribute.&lt;/li&gt;
&lt;li&gt;No review cycle, so the same weak content repeats next month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A calendar is useful only when it reduces guesswork. For Echo Effect clients, that means connecting platform execution with the website, landing pages, service pages, analytics, and reporting. If your posts create interest but the website does not explain the next step, the calendar is doing only half the job.&lt;/p&gt;

&lt;p&gt;For deeper social execution, see Echo Effect's &lt;a href="https://dev.to/products/social-media"&gt;social media consulting services&lt;/a&gt;. If your website is the weak link after the click, review the &lt;a href="https://dev.to/products/web-design"&gt;web design and development services&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should a Small Business Content Calendar Include?
&lt;/h2&gt;

&lt;p&gt;A practical social media content calendar should include the fields that affect publishing, measurement, and conversion. Keep it simple enough to use every week.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Calendar Field&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Platform&lt;/td&gt;
&lt;td&gt;Facebook, Instagram, LinkedIn, and X behave differently, so do not paste the same plan everywhere.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audience&lt;/td&gt;
&lt;td&gt;Name who the post is for: new prospects, warm leads, past customers, partners, or referral sources.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content role&lt;/td&gt;
&lt;td&gt;Label the post as awareness, education, proof, offer, event, retention, or community.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Format&lt;/td&gt;
&lt;td&gt;Choose the right asset: short video, carousel, static image, text post, story, article link, or poll.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Website destination&lt;/td&gt;
&lt;td&gt;Map the post to a service page, contact page, blog article, booking page, or landing page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tracking link&lt;/td&gt;
&lt;td&gt;Use consistent UTM parameters so campaigns can be found in analytics.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Owner and status&lt;/td&gt;
&lt;td&gt;Track draft, review, approved, scheduled, published, and measured.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Result&lt;/td&gt;
&lt;td&gt;Record useful outcomes: clicks, leads, comments, saves, replies, form starts, or booked calls.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Meta Business Suite supports creating and scheduling Facebook and Instagram posts from desktop, and its Insights area helps businesses understand paid and organic activity across a Facebook Page and Instagram account (Meta Business Help Center, n.d.-a; Meta Business Help Center, n.d.-b). That gives owners a starting point, but platform data should not be the only source of truth.&lt;/p&gt;

&lt;p&gt;Your website analytics matter because they show what happened after the click. Google Analytics describes the Traffic acquisition report as a way to understand where website and app visitors came from (Google Analytics Help, n.d.-b). If social media is meant to drive leads, then website sessions, engaged visits, form actions, and consultation requests deserve attention alongside reach and engagement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0covca54iewe4yhnvwgf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0covca54iewe4yhnvwgf.webp" alt="Notebook page labeled marketing strategy beside a keyboard on a desk" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A content calendar works best when each post has a business role before it has a caption.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do You Build a Calendar That Drives Leads?
&lt;/h2&gt;

&lt;p&gt;Start with the offer, not the platform. If the business goal is consultation requests, the calendar should support the path from curiosity to contact.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Pick One Monthly Business Goal
&lt;/h3&gt;

&lt;p&gt;Choose one primary goal for the month:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;More consultation requests.&lt;/li&gt;
&lt;li&gt;More calls from a service page.&lt;/li&gt;
&lt;li&gt;More traffic to a new blog article.&lt;/li&gt;
&lt;li&gt;More quote requests for one service.&lt;/li&gt;
&lt;li&gt;More retargeting audience growth before a paid campaign.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One goal does not mean every post is promotional. It means every post has a job in the same customer journey. A contractor might spend the month educating homeowners about when a repair becomes urgent. A consultant might spend the month explaining one problem, showing proof of expertise, and sending prospects to a discovery call.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Map Content Roles Across the Month
&lt;/h3&gt;

&lt;p&gt;Use a balanced mix. A simple weekly rhythm might look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Content Role&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monday&lt;/td&gt;
&lt;td&gt;Education&lt;/td&gt;
&lt;td&gt;Explain a common customer problem in plain language.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wednesday&lt;/td&gt;
&lt;td&gt;Proof&lt;/td&gt;
&lt;td&gt;Show a process, before-and-after context, or client-safe result without inventing claims.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Friday&lt;/td&gt;
&lt;td&gt;Offer&lt;/td&gt;
&lt;td&gt;Link to the relevant service page or consultation page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weekend&lt;/td&gt;
&lt;td&gt;Community&lt;/td&gt;
&lt;td&gt;Ask a useful question, recap an event, or share a practical tip.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;LinkedIn's own Pages best practices frame a company page as a way to establish thought leadership, build brand awareness, and move an audience to action (LinkedIn Marketing Solutions, n.d.). That same principle applies across platforms: content should not only fill space, it should help the audience understand why the business is credible and what to do next.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Connect Posts to the Right Website Page
&lt;/h3&gt;

&lt;p&gt;Do not send every post to the homepage. Match the link to the intent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A beginner education post can link to a blog article.&lt;/li&gt;
&lt;li&gt;A comparison post can link to a service page.&lt;/li&gt;
&lt;li&gt;A high-intent offer post can link to the contact page.&lt;/li&gt;
&lt;li&gt;A paid social campaign can link to a focused landing page.&lt;/li&gt;
&lt;li&gt;A trust-building post can link to an about page, review section, or case-study-style article if one exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where social media and web development overlap. The calendar creates attention, but the website captures demand. If the website is slow, vague, hard to use on mobile, or missing a clear call to action, stronger posting will not fix the lead path. Pair this article with the &lt;a href="https://dev.to/blog/local-business-website-essentials"&gt;local business website essentials guide&lt;/a&gt; and the &lt;a href="https://dev.to/blog/core-web-vitals-small-business-checklist-2026"&gt;Core Web Vitals checklist&lt;/a&gt; when auditing the destination pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Use UTM Links Before You Publish
&lt;/h3&gt;

&lt;p&gt;UTM parameters are small pieces of text added to a URL so analytics tools can identify campaign traffic. Google's URL builder documentation explains that campaign parameters help identify campaigns that refer traffic (Google Analytics Help, n.d.-a).&lt;/p&gt;

&lt;p&gt;For a small business, keep naming consistent:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UTM Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;utm_source&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;facebook&lt;/code&gt;, &lt;code&gt;instagram&lt;/code&gt;, &lt;code&gt;linkedin&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;utm_medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;organic_social&lt;/code&gt;, &lt;code&gt;paid_social&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;utm_campaign&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;august_2026_consultation_push&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;utm_content&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;service_page_carousel&lt;/code&gt;, &lt;code&gt;owner_tip_video&lt;/code&gt;, &lt;code&gt;faq_post&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use lowercase names, avoid spaces, and document the pattern inside the calendar. The goal is not analytics perfection. The goal is to stop guessing whether social posts are creating website demand.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Review the Calendar Like a Sales Tool
&lt;/h3&gt;

&lt;p&gt;At the end of the month, do not ask only which post got the most likes. Ask better questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which posts drove qualified website traffic?&lt;/li&gt;
&lt;li&gt;Which links produced form starts, calls, bookings, or email inquiries?&lt;/li&gt;
&lt;li&gt;Which posts created real conversations with prospects?&lt;/li&gt;
&lt;li&gt;Which platform reached the best-fit audience?&lt;/li&gt;
&lt;li&gt;Which content role was missing?&lt;/li&gt;
&lt;li&gt;Which website page failed to move visitors forward?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Meta insights can help identify content performance on Facebook and Instagram, while Google Analytics can show acquisition patterns after people reach the website (Meta Business Help Center, n.d.-b; Google Analytics Help, n.d.-b). Neither system tells the whole story alone. Use both.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgik9694j7ejoz4bn4kh1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgik9694j7ejoz4bn4kh1.webp" alt="To-do list beside a laptop on a dark workspace" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The best calendar is simple enough to use weekly and specific enough to guide better decisions next month.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A 30-Day Content Calendar Framework
&lt;/h2&gt;

&lt;p&gt;Use this as a starter structure for one service line.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Week&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;th&gt;Content Ideas&lt;/th&gt;
&lt;th&gt;Website Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Problem awareness&lt;/td&gt;
&lt;td&gt;Common mistakes, warning signs, myths, quick tips&lt;/td&gt;
&lt;td&gt;Educational blog article&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Trust and expertise&lt;/td&gt;
&lt;td&gt;Process explanation, FAQ, service comparison, behind-the-scenes workflow&lt;/td&gt;
&lt;td&gt;Service page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Proof and specificity&lt;/td&gt;
&lt;td&gt;Review-safe quote, project detail without private data, checklist, decision guide&lt;/td&gt;
&lt;td&gt;Related article or about page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Offer and conversion&lt;/td&gt;
&lt;td&gt;Consultation invitation, limited-scope audit, downloadable checklist, direct next step&lt;/td&gt;
&lt;td&gt;Contact page or landing page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This framework keeps the month balanced. It avoids a feed that is all selling and avoids a feed that is all education with no business outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Metrics Should You Track?
&lt;/h2&gt;

&lt;p&gt;Track metrics in layers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Useful Metrics&lt;/th&gt;
&lt;th&gt;What It Tells You&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Platform reach&lt;/td&gt;
&lt;td&gt;Reach, impressions, profile visits&lt;/td&gt;
&lt;td&gt;Did the post get seen by enough people?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform engagement&lt;/td&gt;
&lt;td&gt;Comments, saves, shares, replies, link clicks&lt;/td&gt;
&lt;td&gt;Did the topic create interest or action?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Website behavior&lt;/td&gt;
&lt;td&gt;Sessions, engaged sessions, landing page views&lt;/td&gt;
&lt;td&gt;Did the click become a real visit?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lead behavior&lt;/td&gt;
&lt;td&gt;Form submissions, calls, bookings, quote requests&lt;/td&gt;
&lt;td&gt;Did the visit create a business opportunity?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sales context&lt;/td&gt;
&lt;td&gt;Lead quality, close rate, common objections&lt;/td&gt;
&lt;td&gt;Did the content attract the right audience?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Vanity metrics are not useless, but they are incomplete. A post with modest reach and two qualified consultation requests can be more valuable than a viral post from people who will never buy.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Social Media Content Calendars for Small Businesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How far ahead should a small business plan social media content?
&lt;/h3&gt;

&lt;p&gt;Plan one month at a time, then review weekly. Monthly planning gives enough structure for campaigns and approvals, while weekly review keeps the calendar flexible when offers, events, or customer questions change.&lt;/p&gt;

&lt;h3&gt;
  
  
  How often should a small business post?
&lt;/h3&gt;

&lt;p&gt;Posting frequency depends on the platform, audience, and internal capacity. A sustainable schedule that gets reviewed and improved is better than an aggressive schedule that collapses after two weeks. Start with three to five useful posts per week across your priority platforms, then adjust based on real engagement and lead quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should every post link to the website?
&lt;/h3&gt;

&lt;p&gt;No. Some posts should create trust, start conversations, or answer questions directly on the platform. But every calendar should include regular posts that send interested people to a relevant website page, especially when the goal is leads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need paid ads with a content calendar?
&lt;/h3&gt;

&lt;p&gt;Not always. Organic planning can improve consistency and clarify which messages resonate. Paid ads make more sense when the offer, website destination, audience, tracking, and creative have already been tested enough to spend with discipline.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the biggest content calendar mistake?
&lt;/h3&gt;

&lt;p&gt;The biggest mistake is planning posts without a measurement loop. If you do not review what created traffic, leads, conversations, and customer questions, the calendar becomes a publishing habit instead of a marketing system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Echo Effect manage this for my business?
&lt;/h3&gt;

&lt;p&gt;Yes. Echo Effect's social media services include strategy, content creation, scheduling, platform optimization, reporting, and paid campaign support. The right fit depends on your goals, platforms, approval process, and whether your website is ready to convert visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;A social media content calendar should make your marketing easier to run and easier to measure. The useful version connects posts to business goals, audience intent, website destinations, tracking links, and monthly decisions.&lt;/p&gt;

&lt;p&gt;If your business is posting inconsistently, relying on vanity metrics, or sending social traffic to weak website pages, Echo Effect can help build a cleaner system. Start with the &lt;a href="https://dev.to/products/social-media"&gt;social media consulting service&lt;/a&gt;, review your website's role in the funnel with &lt;a href="https://dev.to/products/web-design"&gt;web design and development&lt;/a&gt;, or &lt;a href="https://dev.to/contact"&gt;schedule a consultation&lt;/a&gt; to map the next 30 days around leads instead of guesswork.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Google Analytics Help. (n.d.-a). &lt;a href="https://support.google.com/analytics/answer/10917952?hl=en" rel="noopener noreferrer"&gt;URL builders: Collect campaign data with custom URLs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Google Analytics Help. (n.d.-b). &lt;a href="https://support.google.com/analytics/answer/12923437?hl=en" rel="noopener noreferrer"&gt;[GA4] Traffic acquisition report&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;LinkedIn Marketing Solutions. (n.d.). &lt;a href="https://business.linkedin.com/advertise/linkedin-pages/best-practices" rel="noopener noreferrer"&gt;LinkedIn Pages best practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Meta Business Help Center. (n.d.-a). &lt;a href="https://www.facebook.com/business/help/942827662903020" rel="noopener noreferrer"&gt;Create and manage posts in Meta Business Suite on desktop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Meta Business Help Center. (n.d.-b). &lt;a href="https://www.facebook.com/business/help/700570830721044" rel="noopener noreferrer"&gt;About Insights in Meta Business Suite on desktop&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>socialmedia</category>
      <category>marketing</category>
      <category>contentmarketing</category>
      <category>business</category>
    </item>
    <item>
      <title>Website Accessibility Checklist for Small Businesses in 2026</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:28:12 +0000</pubDate>
      <link>https://dev.to/rverwey/website-accessibility-checklist-for-small-businesses-in-2026-55lh</link>
      <guid>https://dev.to/rverwey/website-accessibility-checklist-for-small-businesses-in-2026-55lh</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/website-accessibility-checklist-small-business-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Website accessibility is not a side task for small business websites anymore. It affects whether people can read your content, use your forms, compare your services, request a quote, and trust your business.&lt;/p&gt;

&lt;p&gt;It also affects search visibility. Search engines and AI answer systems need clear text, useful headings, descriptive images, crawlable pages, and accurate structured data. Those are accessibility basics too.&lt;/p&gt;

&lt;p&gt;As of August 3, 2026, the practical benchmark for most small business website work is still WCAG 2.2, while W3C is actively developing WCAG 3.0 as the next major version of its accessibility guidance (W3C, 2023, 2026a). That does not mean every local business needs to become a legal expert. It means every business needs a repeatable accessibility review before design problems become customer problems.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Start with the customer journey. Make navigation, headings, text, images, forms, buttons, color contrast, keyboard access, and mobile layouts usable before chasing cosmetic design changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Accessibility Belongs in Your 2026 Website Plan
&lt;/h2&gt;

&lt;p&gt;An inaccessible website quietly blocks customers.&lt;/p&gt;

&lt;p&gt;A visitor may not be able to read low-contrast text. A keyboard user may not be able to open a menu. A screen reader user may not understand an image, button, form error, or service comparison. A mobile visitor may miss a call button because a sticky banner covers it. A person with a cognitive disability may abandon a confusing page before contacting the business.&lt;/p&gt;

&lt;p&gt;Those are not only compliance concerns. They are revenue concerns.&lt;/p&gt;

&lt;p&gt;The U.S. Department of Justice explains that inaccessible web content can deny people with disabilities equal access to communication, goods, services, programs, and activities. DOJ guidance also says businesses open to the public and state and local governments have ADA responsibilities related to accessible web content (U.S. Department of Justice, 2022).&lt;/p&gt;

&lt;p&gt;There is one important nuance. The 2024 DOJ web accessibility rule sets specific technical requirements for state and local governments under ADA Title II, not every private small business website. Still, the rule is a strong signal because it uses WCAG 2.1 Level AA as the required technical standard for covered public entities (U.S. Department of Justice, 2024). Private businesses should talk with qualified legal counsel about their specific obligations, but from a website quality standpoint, WCAG remains the most practical framework to follow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1487014679447-9f8336841d58%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1487014679447-9f8336841d58%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Laptop showing a product website during a small business accessibility review" width="1200" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Accessibility work should be tied to real customer tasks: reading service details, comparing options, using forms, and contacting the business.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What WCAG 2.2 and WCAG 3 Mean for Small Businesses
&lt;/h2&gt;

&lt;p&gt;WCAG stands for Web Content Accessibility Guidelines. W3C says WCAG 2.2 covers recommendations for making web content more accessible to people with disabilities, including people with blindness, low vision, deafness, limited movement, cognitive limitations, and combinations of disabilities (W3C, 2023).&lt;/p&gt;

&lt;p&gt;WCAG 2.2 is the current stable recommendation. WCAG 3.0 is not final. W3C published an updated WCAG 3 Working Draft on March 3, 2026, and describes WCAG 3 as the future successor to the WCAG 2 series (W3C, 2026a, 2026b).&lt;/p&gt;

&lt;p&gt;For a small business owner, the takeaway is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use WCAG 2.2 as the practical checklist today.&lt;/li&gt;
&lt;li&gt;Do not wait for WCAG 3.0 to start fixing obvious barriers.&lt;/li&gt;
&lt;li&gt;Build habits that will age well: clear structure, readable design, usable forms, keyboard support, and tested customer journeys.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good accessibility is not about passing a scan once. Automated scans are useful, but they cannot tell whether your offer is clear, whether your form error makes sense, or whether a person using a screen reader understands the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2026 Accessibility Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist when reviewing a homepage, service page, contact page, quote form, landing page, or blog post.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Make the Page Structure Obvious
&lt;/h3&gt;

&lt;p&gt;A good page should make sense before anyone sees the colors or images.&lt;/p&gt;

&lt;p&gt;Check for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One clear H1 that describes the page.&lt;/li&gt;
&lt;li&gt;H2 sections that answer real customer questions.&lt;/li&gt;
&lt;li&gt;Short paragraphs that are easy to scan.&lt;/li&gt;
&lt;li&gt;Lists for steps, requirements, features, and comparisons.&lt;/li&gt;
&lt;li&gt;Internal links with descriptive anchor text.&lt;/li&gt;
&lt;li&gt;Page titles and meta descriptions that match the visible content.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This helps accessibility, SEO, AEO, and GEO at the same time. People skim headings. Search engines use structure to understand topics. AI answer systems need direct, well-labeled answers they can summarize without guessing.&lt;/p&gt;

&lt;p&gt;For example, a service page should answer "What do you do?", "Who is this for?", "What is included?", "How much does it usually involve?", "Where do you serve customers?", and "How do I contact you?" in visible text.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Write Alt Text for People First
&lt;/h3&gt;

&lt;p&gt;Alt text is not a keyword stuffing field. It is a text alternative for images that need one.&lt;/p&gt;

&lt;p&gt;Google's image SEO guidance says descriptive filenames, titles, and alt text help Google understand image subject matter, and that images should be placed near relevant text on relevant pages (Google Search Central, n.d.-a). W3C's image tutorial explains that informative image alternatives should convey the meaning or content shown visually, not merely list objects in the image (W3C, n.d.).&lt;/p&gt;

&lt;p&gt;Use this simple rule:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If an image explains something important, describe what matters.&lt;/li&gt;
&lt;li&gt;If an image is decorative, leave it empty or handle it as decorative in the code.&lt;/li&gt;
&lt;li&gt;If an image is a link or button, describe the action.&lt;/li&gt;
&lt;li&gt;If the image includes text, include the useful text in the page body whenever possible.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bad alt text: "SEO web design business accessibility 2026."&lt;/p&gt;

&lt;p&gt;Better alt text: "Customer using a laptop to review a small business service page."&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use Color Contrast That Works in Real Life
&lt;/h3&gt;

&lt;p&gt;Low-contrast design is one of the fastest ways to make a website feel polished and unusable at the same time.&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Body text against the page background.&lt;/li&gt;
&lt;li&gt;Button text against button colors.&lt;/li&gt;
&lt;li&gt;Navigation links in hover and active states.&lt;/li&gt;
&lt;li&gt;Form labels, placeholders, helper text, and errors.&lt;/li&gt;
&lt;li&gt;Light text over images.&lt;/li&gt;
&lt;li&gt;Dark mode and light mode variants if the site supports both.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not rely on your own monitor. Test on a phone, in sunlight, at lower brightness, and with browser zoom. If the page gets harder to read, customers will feel it before they can explain it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Make Every Interactive Element Keyboard Usable
&lt;/h3&gt;

&lt;p&gt;Keyboard access is essential for people who cannot use a mouse, people using assistive technology, and power users who navigate quickly.&lt;/p&gt;

&lt;p&gt;Test with the &lt;code&gt;Tab&lt;/code&gt;, &lt;code&gt;Shift + Tab&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;, &lt;code&gt;Space&lt;/code&gt;, and &lt;code&gt;Escape&lt;/code&gt; keys.&lt;/p&gt;

&lt;p&gt;Make sure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Menus can be opened and closed.&lt;/li&gt;
&lt;li&gt;Buttons show visible focus styles.&lt;/li&gt;
&lt;li&gt;Modal windows do not trap people incorrectly.&lt;/li&gt;
&lt;li&gt;Dropdowns can be operated without a mouse.&lt;/li&gt;
&lt;li&gt;Forms can be completed in a logical order.&lt;/li&gt;
&lt;li&gt;Skip links or clear navigation patterns help users reach content quickly.&lt;/li&gt;
&lt;li&gt;Focus does not disappear behind sticky headers, cookie banners, or chat widgets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where many custom designs fail. A beautiful menu that only works with a mouse is not finished.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Fix Forms Before Anything Else
&lt;/h3&gt;

&lt;p&gt;Forms are where accessibility problems become lost leads.&lt;/p&gt;

&lt;p&gt;Review every form field:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does it have a visible label?&lt;/li&gt;
&lt;li&gt;Is the required status clear?&lt;/li&gt;
&lt;li&gt;Is the error message specific?&lt;/li&gt;
&lt;li&gt;Can the error be understood by screen readers?&lt;/li&gt;
&lt;li&gt;Does the form preserve user input after an error?&lt;/li&gt;
&lt;li&gt;Can the form be completed on mobile?&lt;/li&gt;
&lt;li&gt;Does the confirmation message explain what happens next?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a small business website, the contact form is often the money path. A form that looks modern but fails accessibility, validation, or email delivery is a business problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Keep Mobile Layouts Stable and Simple
&lt;/h3&gt;

&lt;p&gt;Mobile accessibility is not only about screen size. It is about touch targets, readable text, page stability, keyboard behavior, and friction.&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buttons are easy to tap.&lt;/li&gt;
&lt;li&gt;Text does not require zooming.&lt;/li&gt;
&lt;li&gt;The phone number is selectable and tappable.&lt;/li&gt;
&lt;li&gt;Menus do not cover the page.&lt;/li&gt;
&lt;li&gt;Forms do not jump when the keyboard opens.&lt;/li&gt;
&lt;li&gt;Review widgets, maps, chat tools, and popups do not block the primary call to action.&lt;/li&gt;
&lt;li&gt;Content remains readable when text size is increased.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mobile is often the first visit, especially for local service searches. If the mobile experience is difficult, the business may never get a second chance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1634944902853-3e977c2de8b6%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1634944902853-3e977c2de8b6%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Hand using an adaptive keyboard device for computer input" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Accessible websites support different input methods, including keyboards, assistive devices, touch screens, and screen readers.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Match Structured Data to Visible Content
&lt;/h3&gt;

&lt;p&gt;Structured data helps search systems understand the page, but it must match what users can actually see.&lt;/p&gt;

&lt;p&gt;Google says it uses structured data to understand content and gather information about people, organizations, products, and other entities on the web (Google Search Central, n.d.-b). For small businesses, useful structured data often includes Organization, LocalBusiness, Service, FAQPage where appropriate, BreadcrumbList, and BlogPosting.&lt;/p&gt;

&lt;p&gt;The accessibility connection is straightforward: do not hide critical facts in code only. If the page schema says the business serves Florida, the page should visibly say that. If the schema describes a service, the page should clearly explain that service. If an FAQ is marked up, the question and answer should be visible to readers.&lt;/p&gt;

&lt;p&gt;This supports GEO because AI systems need reliable entity signals. It supports SEO because search systems can better classify the page. It supports accessibility because people get the same information machines get.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Review Third-Party Widgets
&lt;/h3&gt;

&lt;p&gt;Many accessibility failures come from tools added after launch:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Chat widgets.&lt;/li&gt;
&lt;li&gt;Review embeds.&lt;/li&gt;
&lt;li&gt;Booking calendars.&lt;/li&gt;
&lt;li&gt;Social feeds.&lt;/li&gt;
&lt;li&gt;Ad scripts.&lt;/li&gt;
&lt;li&gt;Cookie banners.&lt;/li&gt;
&lt;li&gt;CRM forms.&lt;/li&gt;
&lt;li&gt;Payment widgets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not assume a vendor widget is accessible because the vendor is large. Test it. If it blocks a form, traps focus, lacks labels, creates layout shifts, or makes the mobile page harder to use, it needs configuration or replacement.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Test With Real Tasks
&lt;/h3&gt;

&lt;p&gt;A scan can find missing alt text. It cannot tell you whether a customer can confidently hire you.&lt;/p&gt;

&lt;p&gt;Run task-based tests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the main service.&lt;/li&gt;
&lt;li&gt;Compare two service options.&lt;/li&gt;
&lt;li&gt;Read a pricing or process explanation.&lt;/li&gt;
&lt;li&gt;Find the service area.&lt;/li&gt;
&lt;li&gt;Submit the contact form.&lt;/li&gt;
&lt;li&gt;Tap the phone number.&lt;/li&gt;
&lt;li&gt;Navigate the page with only a keyboard.&lt;/li&gt;
&lt;li&gt;Increase browser zoom to 200%.&lt;/li&gt;
&lt;li&gt;Turn on a screen reader and listen to the page structure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If those tasks are difficult, fix the design before adding more features.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Accessibility Improves SEO, AEO, and GEO
&lt;/h2&gt;

&lt;p&gt;Accessibility is not a separate lane from search. It strengthens the same signals that help people and machines understand a website.&lt;/p&gt;

&lt;p&gt;Accessible pages tend to have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clear headings.&lt;/li&gt;
&lt;li&gt;Descriptive links.&lt;/li&gt;
&lt;li&gt;Useful image descriptions.&lt;/li&gt;
&lt;li&gt;Text that can be crawled and read aloud.&lt;/li&gt;
&lt;li&gt;Stable mobile layouts.&lt;/li&gt;
&lt;li&gt;Logical form labels.&lt;/li&gt;
&lt;li&gt;Accurate structured data.&lt;/li&gt;
&lt;li&gt;Fewer confusing interactions.&lt;/li&gt;
&lt;li&gt;More complete answers to customer questions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That combination helps traditional SEO because search engines can parse the page. It helps AEO because direct answers are easier to extract. It helps GEO because AI answer systems need clear source material before they can cite or summarize a business accurately.&lt;/p&gt;

&lt;p&gt;For a small business, the goal is not to sound technical. The goal is to be understandable everywhere a customer may encounter you: Google, AI search, a screen reader, a phone browser, a desktop browser, and a referral link.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should a Small Business Fix First?
&lt;/h2&gt;

&lt;p&gt;Start with the pages that make money.&lt;/p&gt;

&lt;p&gt;Prioritize:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Homepage.&lt;/li&gt;
&lt;li&gt;Contact page.&lt;/li&gt;
&lt;li&gt;Primary service pages.&lt;/li&gt;
&lt;li&gt;Paid ad landing pages.&lt;/li&gt;
&lt;li&gt;Booking or quote forms.&lt;/li&gt;
&lt;li&gt;High-traffic blog posts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then fix the highest-friction items:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Missing or confusing headings.&lt;/li&gt;
&lt;li&gt;Low contrast text.&lt;/li&gt;
&lt;li&gt;Buttons and links without clear names.&lt;/li&gt;
&lt;li&gt;Forms without labels or useful errors.&lt;/li&gt;
&lt;li&gt;Menus that fail keyboard or mobile users.&lt;/li&gt;
&lt;li&gt;Images that explain important content but have no useful alt text.&lt;/li&gt;
&lt;li&gt;Popups that cover the call to action.&lt;/li&gt;
&lt;li&gt;Structured data that does not match visible content.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This order keeps the work practical. Accessibility does not need to become an endless audit before anything improves.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Website Accessibility for Small Businesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is website accessibility?
&lt;/h3&gt;

&lt;p&gt;Website accessibility means people with disabilities can perceive, navigate, understand, and interact with your website. That includes people using screen readers, keyboards, captions, zoom, voice control, assistive devices, and different visual or cognitive supports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does every small business website need to follow WCAG?
&lt;/h3&gt;

&lt;p&gt;Legal obligations depend on the business, jurisdiction, website function, and customer relationship. From a design and risk standpoint, WCAG 2.2 is the best practical framework for improving accessibility. Businesses should consult qualified legal counsel for legal advice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does accessibility help SEO?
&lt;/h3&gt;

&lt;p&gt;Yes, when it improves clarity and usability. Clear headings, descriptive links, alt text, readable content, mobile usability, and accurate structured data all help search systems understand pages better. Accessibility should be done for people first, with SEO as a secondary benefit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are accessibility overlay widgets enough?
&lt;/h3&gt;

&lt;p&gt;No. An overlay cannot fix poor structure, unclear content, unlabeled forms, weak contrast, broken keyboard navigation, or inaccessible third-party widgets by itself. Accessibility needs to be built into the page and tested in the customer journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can small businesses get tax help for accessibility work?
&lt;/h3&gt;

&lt;p&gt;Some eligible small businesses may be able to claim the Disabled Access Credit for qualified access expenditures. The IRS says eligible small businesses use Form 8826 to claim the credit and that the credit is part of the general business credit (Internal Revenue Service, n.d.). Talk with a tax professional before relying on any tax benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Accessible websites are better business websites. They are easier to read, easier to navigate, easier to cite, easier to trust, and easier to use when a customer is ready to act.&lt;/p&gt;

&lt;p&gt;In 2026, small businesses should treat accessibility as part of website maintenance, not as a one-time redesign feature. Start with the money pages, fix the customer journey, use WCAG 2.2 as the practical standard, watch WCAG 3.0 as it develops, and make sure the information in your page content, images, forms, and structured data tells the same story.&lt;/p&gt;

&lt;p&gt;Echo Effect helps small businesses build websites that work for people, search engines, and AI answer systems. If your site has never had an accessibility review, start with the homepage, service pages, and contact form. That is where the fastest improvements usually live.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Google Search Central. (n.d.-a). &lt;em&gt;Image SEO best practices&lt;/em&gt;. Google for Developers. Retrieved August 3, 2026, from &lt;a href="https://developers.google.com/search/docs/appearance/google-images" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/google-images&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-b). &lt;em&gt;Intro to how structured data markup works&lt;/em&gt;. Google for Developers. Retrieved August 3, 2026, from &lt;a href="https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Internal Revenue Service. (n.d.). &lt;em&gt;About Form 8826, Disabled Access Credit&lt;/em&gt;. Retrieved August 3, 2026, from &lt;a href="https://www.irs.gov/forms-pubs/about-form-8826" rel="noopener noreferrer"&gt;https://www.irs.gov/forms-pubs/about-form-8826&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;U.S. Department of Justice. (2022, March 18). &lt;em&gt;Guidance on web accessibility and the ADA&lt;/em&gt;. ADA.gov. &lt;a href="https://www.ada.gov/resources/web-guidance/" rel="noopener noreferrer"&gt;https://www.ada.gov/resources/web-guidance/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;U.S. Department of Justice. (2024, March 8). &lt;em&gt;Fact sheet: New rule on the accessibility of web content and mobile apps provided by state and local governments&lt;/em&gt;. ADA.gov. &lt;a href="https://www.ada.gov/resources/2024-03-08-web-rule/" rel="noopener noreferrer"&gt;https://www.ada.gov/resources/2024-03-08-web-rule/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W3C. (2023, October 5). &lt;em&gt;Web Content Accessibility Guidelines (WCAG) 2.2&lt;/em&gt;. &lt;a href="https://www.w3.org/TR/WCAG22/" rel="noopener noreferrer"&gt;https://www.w3.org/TR/WCAG22/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W3C. (n.d.). &lt;em&gt;Informative images&lt;/em&gt;. Web Accessibility Initiative. Retrieved August 3, 2026, from &lt;a href="https://www.w3.org/WAI/tutorials/images/informative/" rel="noopener noreferrer"&gt;https://www.w3.org/WAI/tutorials/images/informative/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W3C. (2026a, March 3). &lt;em&gt;For review: WCAG 3 Working Draft, March 2026&lt;/em&gt;. Web Accessibility Initiative. &lt;a href="https://www.w3.org/WAI/news/2026-03-03/wcag3/" rel="noopener noreferrer"&gt;https://www.w3.org/WAI/news/2026-03-03/wcag3/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W3C. (2026b). &lt;em&gt;WCAG 3 introduction&lt;/em&gt;. Web Accessibility Initiative. Retrieved August 3, 2026, from &lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/" rel="noopener noreferrer"&gt;https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>a11y</category>
      <category>webdesign</category>
      <category>seo</category>
    </item>
    <item>
      <title>Passkeys Are Becoming Default: Small Business Checklist</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:27:37 +0000</pubDate>
      <link>https://dev.to/rverwey/passkeys-are-becoming-default-small-business-checklist-4bl</link>
      <guid>https://dev.to/rverwey/passkeys-are-becoming-default-small-business-checklist-4bl</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/passkeys-default-small-business-checklist-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Passwords are not disappearing overnight, but the direction is clear: business sign-ins are moving toward passkeys and phishing-resistant authentication.&lt;/p&gt;

&lt;p&gt;The current event that should get every small business owner's attention is Microsoft's July 2026 Entra ID update. Microsoft says passkeys will become the default authentication experience in Entra ID beginning September 1, 2026. Microsoft-provided SMS and voice authentication delivery will then be retired on February 1, 2027 for public cloud tenants (Microsoft, 2026a, 2026b).&lt;/p&gt;

&lt;p&gt;That does not only matter to enterprise IT teams. It matters to small businesses using Microsoft 365, Google Workspace, customer portals, booking platforms, CRMs, ecommerce accounts, website admin panels, password managers, payment processors, social media tools, and ad accounts.&lt;/p&gt;

&lt;p&gt;The short answer: if your business still relies on passwords, SMS codes, shared admin logins, or vendor-owned accounts, 2026 is the year to clean that up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Passkeys use public-key cryptography and device verification instead of reusable passwords. For most small businesses, the practical plan is to protect high-value accounts first, keep recovery clear, train staff, and phase out SMS MFA where stronger options are available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Is a Passkey?
&lt;/h2&gt;

&lt;p&gt;A passkey is a passwordless sign-in method built on FIDO and WebAuthn standards. Instead of typing a password that can be stolen or reused, the user verifies themselves on a trusted device with a fingerprint, face scan, screen lock, PIN, hardware security key, or credential manager.&lt;/p&gt;

&lt;p&gt;The important part happens behind the scenes. The website stores a public key. The user's device or credential provider keeps the private key. During sign-in, the device proves possession of the private key without sending a password to the website. web.dev explains that this design reduces phishing risk and credential theft because the private key signs a challenge for the valid domain, and the server verifies the result with the stored public key (Kitamura, 2026).&lt;/p&gt;

&lt;p&gt;In plain English: a passkey is harder to steal than a password because there is no shared password to type into a fake login page.&lt;/p&gt;

&lt;p&gt;Passkeys can be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Synced passkeys:&lt;/strong&gt; Stored in a credential manager such as iCloud Keychain, Google Password Manager, or another supported provider, then synced across the user's devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Device-bound passkeys:&lt;/strong&gt; Stored on a specific device, such as a phone, computer, Microsoft Authenticator passkey, Windows Hello credential, or FIDO2 hardware security key.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both categories can be useful. The right choice depends on the account, user, device ownership, recovery needs, and risk level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1633265486064-086b219458ec%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1633265486064-086b219458ec%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Combination lock and smart cards on a computer keyboard representing older authentication methods" width="1200" height="801"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Small businesses should not wait for a forced migration before replacing weak sign-in methods on critical accounts.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters Right Now
&lt;/h2&gt;

&lt;p&gt;Microsoft's announcement gives the market a clear signal. SMS and voice codes helped many organizations adopt MFA, but Microsoft now describes them as phishable methods that provide weaker protection than passkeys. Microsoft also says users enabled for SMS or voice in Entra ID will be auto-enabled and nudged to register passkeys beginning September 1, 2026, and users who still depend on Microsoft-provided SMS or voice after February 1, 2027 will face a blocking registration prompt before continuing to sign in (Microsoft, 2026a).&lt;/p&gt;

&lt;p&gt;This is not an isolated vendor preference. The broader identity market has been moving this way for years.&lt;/p&gt;

&lt;p&gt;The FIDO Alliance reported in its 2026 global passkey research that passkeys have reached 5 billion active credentials, 90% consumer awareness, and 75% consumer enablement on at least some accounts. It also reported that 68% of surveyed organizations were deploying, piloting, or rolling out passkeys for employee authentication (FIDO Alliance, 2026).&lt;/p&gt;

&lt;p&gt;The business case is not only security. FIDO's 2025 Passkey Index reported a 93% success rate for passkey logins compared with 63% for other methods among participating platforms. The same report said passkey sign-ins averaged 8.5 seconds compared with 31.2 seconds for traditional MFA methods, a 73% decrease in login time (FIDO Alliance, 2025).&lt;/p&gt;

&lt;p&gt;For a small business, that means authentication is both a security issue and a workflow issue. Every failed login, reset ticket, locked-out employee, vendor handoff, and forgotten password wastes time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Business Risk: Not Just "Hackers"
&lt;/h2&gt;

&lt;p&gt;Most small businesses do not lose accounts because a genius attacker breaks cryptography. They lose accounts because of ordinary operational gaps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One shared admin account controls the website.&lt;/li&gt;
&lt;li&gt;A former vendor still has access.&lt;/li&gt;
&lt;li&gt;SMS MFA is tied to a phone number nobody owns anymore.&lt;/li&gt;
&lt;li&gt;Password reset email goes to a stale inbox.&lt;/li&gt;
&lt;li&gt;A staff member reuses a password from a personal account.&lt;/li&gt;
&lt;li&gt;A fake Microsoft 365 login page captures credentials.&lt;/li&gt;
&lt;li&gt;A social media account has no recovery owner.&lt;/li&gt;
&lt;li&gt;A password manager vault has no business continuity plan.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Passkeys do not fix every one of those problems by themselves. They do reduce the risk that a reused or phished password becomes the easy way in. They also force the business to answer questions that should already be documented: who owns each account, which devices are trusted, how access is recovered, and who can approve changes.&lt;/p&gt;

&lt;p&gt;That is why passkey planning belongs in website maintenance, SEO, AEO, and GEO work. If attackers take over your website admin, Google Business Profile, social accounts, or email domain, the damage is not limited to IT. It can break lead flow, damage local search trust, interrupt ad campaigns, and pollute the public signals that search engines and AI answer systems use to understand your business.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Protect First
&lt;/h2&gt;

&lt;p&gt;Do not start with every account in the company. Start with the accounts that can change money, identity, website content, customer data, or public trust.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Account type&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Microsoft 365 or Google Workspace admins&lt;/td&gt;
&lt;td&gt;Controls email, identity, reset paths, files, and often domain trust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Domain registrar and DNS&lt;/td&gt;
&lt;td&gt;Controls where the website, email, and verification records point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Website hosting and CMS admin&lt;/td&gt;
&lt;td&gt;Controls public pages, forms, plugins, redirects, and scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Payment, banking, payroll, and invoicing&lt;/td&gt;
&lt;td&gt;Direct financial risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Password manager administrator&lt;/td&gt;
&lt;td&gt;Controls access to many other systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Google Business Profile and ad accounts&lt;/td&gt;
&lt;td&gt;Controls local visibility, paid traffic, and brand trust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Facebook, Instagram, LinkedIn, and YouTube&lt;/td&gt;
&lt;td&gt;Controls public reputation and customer communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;CRM, booking, and form tools&lt;/td&gt;
&lt;td&gt;Controls customer records and lead flow&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If a small business only has time for one security improvement this month, protect the accounts at the top of that list.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Passkey Rollout Checklist
&lt;/h2&gt;

&lt;p&gt;This checklist is written for small business owners, office managers, agencies, and web teams. You do not need to implement everything in one day. You do need a written migration path.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Inventory Accounts and Owners
&lt;/h3&gt;

&lt;p&gt;Create a simple account inventory. Include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Account name.&lt;/li&gt;
&lt;li&gt;Business purpose.&lt;/li&gt;
&lt;li&gt;Primary owner.&lt;/li&gt;
&lt;li&gt;Backup owner.&lt;/li&gt;
&lt;li&gt;Login URL.&lt;/li&gt;
&lt;li&gt;MFA method.&lt;/li&gt;
&lt;li&gt;Recovery email or phone.&lt;/li&gt;
&lt;li&gt;Vendor access.&lt;/li&gt;
&lt;li&gt;Last access review date.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This does not need to be fancy. A secure password manager, spreadsheet, or internal IT document can work if access is controlled.&lt;/p&gt;

&lt;p&gt;The goal is to eliminate mystery. If nobody knows who owns the domain registrar, the business has a security and continuity problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Move Admins First
&lt;/h3&gt;

&lt;p&gt;Roll passkeys or phishing-resistant MFA to administrators before general staff. Admin accounts can reset users, change DNS, install plugins, delete files, alter billing, and grant vendor access.&lt;/p&gt;

&lt;p&gt;For Microsoft Entra users, Microsoft recommends identifying users enabled for SMS or voice, enabling passkeys, using registration campaigns, and communicating the change before the rollout hits users (Microsoft, 2026a, 2026b).&lt;/p&gt;

&lt;p&gt;For other systems, the same pattern applies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify who still uses password-only sign-in or SMS MFA.&lt;/li&gt;
&lt;li&gt;Confirm the platform supports passkeys, FIDO2 security keys, or another phishing-resistant method.&lt;/li&gt;
&lt;li&gt;Pilot with owners and admins.&lt;/li&gt;
&lt;li&gt;Document recovery.&lt;/li&gt;
&lt;li&gt;Roll out to the rest of the team.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Keep Recovery Strong
&lt;/h3&gt;

&lt;p&gt;Weak recovery can undo strong authentication. If support can remove MFA after someone answers easy questions, attackers will target the recovery process instead of the login screen.&lt;/p&gt;

&lt;p&gt;web.dev recommends notifying users after passkey registration so unauthorized passkey creation can be detected (Kitamura, 2026). For businesses, that principle should expand into a broader recovery plan.&lt;/p&gt;

&lt;p&gt;Document:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who can approve account recovery.&lt;/li&gt;
&lt;li&gt;How identity is verified before resetting access.&lt;/li&gt;
&lt;li&gt;Which email receives security alerts.&lt;/li&gt;
&lt;li&gt;Where backup codes are stored.&lt;/li&gt;
&lt;li&gt;Which devices can create or use passkeys.&lt;/li&gt;
&lt;li&gt;What happens when a phone, laptop, or security key is lost.&lt;/li&gt;
&lt;li&gt;How vendor access is removed at the end of a project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not rely on one phone number, one employee, or one vendor relationship as the only recovery path.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Separate Shared Work From Shared Logins
&lt;/h3&gt;

&lt;p&gt;Many small businesses still share one login because "everyone needs access." That is exactly the habit passkeys should help replace.&lt;/p&gt;

&lt;p&gt;Use individual accounts with role-based access whenever possible. A social media scheduler, CMS, ad account, Google Business Profile, CRM, or password manager should allow named users or roles. Shared logins make it hard to revoke access, audit activity, and recover safely.&lt;/p&gt;

&lt;p&gt;If a platform only supports one login, store it in a business password manager, protect the vault with strong MFA, and document who can use it. Then plan to move away from that platform if account sharing creates material risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Choose Passkey Types Intentionally
&lt;/h3&gt;

&lt;p&gt;Synced passkeys are convenient because users can access accounts across devices through their credential provider. Device-bound passkeys can be stricter because they stay tied to a specific authenticator or security key.&lt;/p&gt;

&lt;p&gt;NIST's SP 800-63 Revision 4, finalized in July 2025, explicitly integrates syncable authenticators such as synced passkeys into its updated digital identity guidance (NIST, 2025). That is a signal that synced passkeys are part of mainstream identity planning, not a niche convenience feature.&lt;/p&gt;

&lt;p&gt;For small businesses:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use synced passkeys for lower-risk employee workflows where convenience and recovery matter.&lt;/li&gt;
&lt;li&gt;Consider device-bound passkeys or hardware security keys for owners, admins, finance, and critical systems.&lt;/li&gt;
&lt;li&gt;Avoid letting unmanaged personal devices become the only path into business-critical accounts.&lt;/li&gt;
&lt;li&gt;Keep at least two recovery-capable owners for critical systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6. Train People Before Prompts Appear
&lt;/h3&gt;

&lt;p&gt;Passkey adoption fails when users see a security prompt they do not understand. Explain the change before rollout.&lt;/p&gt;

&lt;p&gt;Your internal note should answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is changing?&lt;/li&gt;
&lt;li&gt;Why are passwords and SMS codes being reduced?&lt;/li&gt;
&lt;li&gt;Which accounts are affected first?&lt;/li&gt;
&lt;li&gt;What device should the person use?&lt;/li&gt;
&lt;li&gt;What should they do if they lose a device?&lt;/li&gt;
&lt;li&gt;Who should they contact before approving a strange prompt?&lt;/li&gt;
&lt;li&gt;What does a real registration flow look like?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep the language simple. A staff member does not need a cryptography lesson. They need to know which prompts are expected and which prompts should be reported.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1585079374502-415f8516dcc3%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1585079374502-415f8516dcc3%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Fingerprint scanner representing biometric verification for account access" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Passkeys reduce phishing risk, but the rollout still needs clear ownership, secure recovery, and user training.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Website and SEO Implications
&lt;/h2&gt;

&lt;p&gt;Passkeys may sound like an internal IT topic, but they have direct website consequences.&lt;/p&gt;

&lt;p&gt;Your website and marketing accounts are usually connected to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Domain DNS.&lt;/li&gt;
&lt;li&gt;Website hosting.&lt;/li&gt;
&lt;li&gt;CMS admin.&lt;/li&gt;
&lt;li&gt;Email delivery.&lt;/li&gt;
&lt;li&gt;Analytics.&lt;/li&gt;
&lt;li&gt;Google Search Console.&lt;/li&gt;
&lt;li&gt;Google Business Profile.&lt;/li&gt;
&lt;li&gt;Ad platforms.&lt;/li&gt;
&lt;li&gt;Social media profiles.&lt;/li&gt;
&lt;li&gt;Forms, booking tools, and CRM systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any of those accounts are compromised, your SEO and AEO work can be damaged quickly. Attackers can add spam pages, change redirects, break forms, swap tracking scripts, abuse email, alter business details, publish fake posts, or block crawlers.&lt;/p&gt;

&lt;p&gt;Google's 2026 guidance for generative AI features says AI search visibility still depends on foundational SEO: helpful content, crawlability, technical structure, page experience, and high-quality supporting images or video (Google Search Central, 2026). A compromised or unstable site weakens those signals.&lt;/p&gt;

&lt;p&gt;The AEO and GEO lesson is simple: trustworthy content requires trustworthy operations. A business cannot expect search engines and AI answer systems to cite accurate information if account security allows the public facts about the business to be changed by the wrong person.&lt;/p&gt;

&lt;p&gt;For related visibility work, read Echo Effect's guides to &lt;a href="https://dev.to/blog/answer-engine-optimization-2026"&gt;answer engine optimization&lt;/a&gt;, &lt;a href="https://dev.to/blog/ai-crawler-access-small-business-websites-2026"&gt;AI crawler access&lt;/a&gt;, and &lt;a href="https://dev.to/blog/small-business-website-vulnerability-checklist-2026"&gt;website vulnerability management&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passkeys Are Not Magic
&lt;/h2&gt;

&lt;p&gt;Passkeys are a major improvement, but they are not a complete security program.&lt;/p&gt;

&lt;p&gt;They do not replace:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Device updates.&lt;/li&gt;
&lt;li&gt;Malware protection.&lt;/li&gt;
&lt;li&gt;Vendor offboarding.&lt;/li&gt;
&lt;li&gt;Backup planning.&lt;/li&gt;
&lt;li&gt;Least-privilege access.&lt;/li&gt;
&lt;li&gt;Secure recovery.&lt;/li&gt;
&lt;li&gt;Phishing awareness.&lt;/li&gt;
&lt;li&gt;Website patching.&lt;/li&gt;
&lt;li&gt;Monitoring for suspicious changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They also introduce practical questions. Which devices are allowed? What happens when an employee leaves? Can the business recover if the owner's phone is lost? Are passkeys stored in a personal credential manager or a managed business system? Do vendors need their own accounts?&lt;/p&gt;

&lt;p&gt;Those questions are solvable, but they should be answered before a forced platform change creates urgency.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Passkeys for Small Businesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should every small business use passkeys?
&lt;/h3&gt;

&lt;p&gt;Most small businesses should use passkeys where important platforms support them, especially for email, domain, hosting, website, finance, and admin accounts. If passkeys are not available, use the strongest MFA option available and plan to upgrade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are passkeys better than SMS codes?
&lt;/h3&gt;

&lt;p&gt;Yes for most business sign-in scenarios. SMS codes can be phished, intercepted, socially engineered, or affected by SIM-swap attacks. Passkeys are designed to be phishing-resistant because they use cryptographic keys tied to the legitimate domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a passkey be stolen?
&lt;/h3&gt;

&lt;p&gt;A passkey is much harder to steal than a password, but no system is perfect. Attackers may still target devices, recovery processes, malware, support desks, or compromised credential providers. That is why passkeys should be paired with device security and strong recovery rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if an employee loses their phone?
&lt;/h3&gt;

&lt;p&gt;The business needs a documented recovery process before rollout. Keep at least two account owners for critical systems, store recovery codes securely, and make sure recovery does not depend on one person, one phone number, or one vendor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do passkeys help SEO?
&lt;/h3&gt;

&lt;p&gt;Indirectly, yes. Passkeys do not make a page rank higher by themselves. They help protect the accounts that control website content, DNS, analytics, business listings, ads, and crawl visibility. Stronger account security protects the trust signals that SEO, AEO, and GEO depend on.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I do this week?
&lt;/h3&gt;

&lt;p&gt;Start with your highest-risk accounts. Review Microsoft 365 or Google Workspace admins, domain registrar access, hosting, CMS admin accounts, password manager ownership, Google Business Profile, ad accounts, and social media profiles. Turn on passkeys or phishing-resistant MFA where available.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Passkeys are moving from optional upgrade to default expectation. Microsoft's 2026 Entra timeline makes that obvious, and broader FIDO adoption data shows the market is ready.&lt;/p&gt;

&lt;p&gt;Small businesses should not treat this as an enterprise-only issue. Your website, email, domain, ads, social profiles, CRM, booking tools, and payment systems all depend on identity security.&lt;/p&gt;

&lt;p&gt;Start with ownership. Protect the accounts that can change public trust or move money. Replace SMS MFA where stronger options are available. Train users before prompts appear. Keep recovery documented. Review access monthly.&lt;/p&gt;

&lt;p&gt;Good authentication is not separate from digital marketing anymore. It protects the systems that keep your website live, your lead flow working, your local business details accurate, and your search visibility trustworthy.&lt;/p&gt;

&lt;p&gt;Echo Effect helps small businesses build and maintain websites with practical security, SEO, AEO, and GEO in mind. If your business does not know who owns every critical login, start there before the next forced platform change starts the clock.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Cybersecurity and Infrastructure Security Agency. (n.d.). &lt;em&gt;Require multifactor authentication&lt;/em&gt;. Retrieved July 27, 2026, from &lt;a href="https://www.cisa.gov/audiences/small-and-medium-businesses/secure-your-business/require-multifactor-authentication" rel="noopener noreferrer"&gt;https://www.cisa.gov/audiences/small-and-medium-businesses/secure-your-business/require-multifactor-authentication&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FIDO Alliance. (2025, October). &lt;em&gt;Passkey Index&lt;/em&gt;. &lt;a href="https://fidoalliance.org/wp-content/uploads/2025/10/FIDO-Passkey-Index-October-2025.pdf" rel="noopener noreferrer"&gt;https://fidoalliance.org/wp-content/uploads/2025/10/FIDO-Passkey-Index-October-2025.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FIDO Alliance. (2026, May 7). &lt;em&gt;The state of passkeys 2026: Global consumer and workforce report&lt;/em&gt;. &lt;a href="https://fidoalliance.org/the-state-of-passkeys-2026-global-consumer-and-workforce-report/" rel="noopener noreferrer"&gt;https://fidoalliance.org/the-state-of-passkeys-2026-global-consumer-and-workforce-report/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (2026, July 10). &lt;em&gt;Optimizing your website for generative AI features on Google Search&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/fundamentals/ai-optimization-guide" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/fundamentals/ai-optimization-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kitamura, E. (2026, April 9). &lt;em&gt;Create a passkey for passwordless logins&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/articles/passkey-registration" rel="noopener noreferrer"&gt;https://web.dev/articles/passkey-registration&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft. (2026a, July 21). &lt;em&gt;Passkeys by default and retirement of Microsoft-provided SMS and voice authentication&lt;/em&gt;. Microsoft Learn. &lt;a href="https://learn.microsoft.com/en-us/entra/identity/authentication/concept-sms-voice-retirement" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/entra/identity/authentication/concept-sms-voice-retirement&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft. (2026b, July 13). &lt;em&gt;Microsoft Entra ID security updates: Passkeys are the default authentication method in Entra ID&lt;/em&gt;. Microsoft Security Blog. &lt;a href="https://www.microsoft.com/en-us/security/blog/2026/07/13/microsoft-entra-id-security-updates-passkeys-are-the-default-authentication-method-in-entra-id/" rel="noopener noreferrer"&gt;https://www.microsoft.com/en-us/security/blog/2026/07/13/microsoft-entra-id-security-updates-passkeys-are-the-default-authentication-method-in-entra-id/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;National Institute of Standards and Technology. (2025, July). &lt;em&gt;SP 800-63 Digital Identity Guidelines&lt;/em&gt;. &lt;a href="https://pages.nist.gov/800-63-4/" rel="noopener noreferrer"&gt;https://pages.nist.gov/800-63-4/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Website Vulnerability Checklist for Small Businesses in 2026</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:27:33 +0000</pubDate>
      <link>https://dev.to/rverwey/website-vulnerability-checklist-for-small-businesses-in-2026-47lo</link>
      <guid>https://dev.to/rverwey/website-vulnerability-checklist-for-small-businesses-in-2026-47lo</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/small-business-website-vulnerability-checklist-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Website security used to feel like an enterprise problem. In 2026, it is a small business website problem too.&lt;/p&gt;

&lt;p&gt;Verizon's 2026 Data Breach Investigations Report found that 31% of breaches now start with software vulnerabilities, making vulnerability exploitation the top breach entry point in the report's public summary (Verizon, 2026a, 2026b). That is not just a warning for banks, hospitals, or SaaS companies. It matters for service businesses, local retailers, restaurants, contractors, medical offices, law firms, and consultants whose websites collect leads, connect to email, load third-party scripts, and depend on plugins, packages, themes, forms, analytics, booking tools, or hosting panels.&lt;/p&gt;

&lt;p&gt;The short answer: a small business website needs a maintenance process, not a one-time launch. If no one is checking updates, reviewing dependencies, testing forms, watching logs, and removing unused software, the site gets riskier every month.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Treat website vulnerability management like bookkeeping. Assign an owner, review it on a schedule, document what changed, and fix high-risk issues before they become emergencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Vulnerability Exploitation Is a Business Issue
&lt;/h2&gt;

&lt;p&gt;A vulnerable website does not need to hold credit card data to hurt the business. Attackers can abuse ordinary marketing sites in several ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inject spam pages that damage search visibility.&lt;/li&gt;
&lt;li&gt;Steal form submissions or customer contact details.&lt;/li&gt;
&lt;li&gt;Redirect visitors to scams.&lt;/li&gt;
&lt;li&gt;Use the site to host malware.&lt;/li&gt;
&lt;li&gt;Abuse server resources and increase hosting costs.&lt;/li&gt;
&lt;li&gt;Break the lead path by taking forms, pages, or booking tools offline.&lt;/li&gt;
&lt;li&gt;Expose admin accounts, API keys, or SMTP credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point is often missed. Many small business websites connect to services that are more sensitive than the public page itself. A contact form may connect to Microsoft 365 SMTP. A booking widget may connect to a calendar. An analytics script may connect to ad accounts. A plugin may store an API key. A neglected website can become a doorway into tools the business depends on.&lt;/p&gt;

&lt;p&gt;This is why security belongs in the same conversation as SEO, AEO, and GEO. Search engines and AI answer systems need stable, trustworthy, crawlable pages. If a website gets defaced, injected with spam, blocked by browsers, or knocked offline, visibility suffers along with customer trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed in 2026
&lt;/h2&gt;

&lt;p&gt;The most important shift is speed. Verizon reported that vulnerability exploitation rose to 31% of breaches and surpassed stolen credentials as the leading entry point (Verizon, 2026a). Verizon's public news summary also says attackers are using AI to accelerate exploitation, shrinking the response window from months to hours (Verizon, 2026b).&lt;/p&gt;

&lt;p&gt;That does not mean AI is the root cause of every attack. It means old maintenance habits are no longer good enough. Waiting a quarter to apply a critical patch is too slow when attackers can scan the internet, find known vulnerable software, and automate exploitation quickly.&lt;/p&gt;

&lt;p&gt;For small businesses, the practical lesson is simple: do not wait until the website visibly breaks. Most serious website security work is boring on purpose. It is version checks, patch notes, backups, access reviews, log checks, and test deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1642783327549-db8f4487dd68%3Fauto%3Dformat%26fit%3Dcrop%26fm%3Djpg%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D%26ixlib%3Drb-4.1.0%26q%3D60%26w%3D3000" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1642783327549-db8f4487dd68%3Fauto%3Dformat%26fit%3Dcrop%26fm%3Djpg%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D%26ixlib%3Drb-4.1.0%26q%3D60%26w%3D3000" alt="Laptop screen showing a security threat alert" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Small business website security should focus on fast detection, fast patching, and clean recovery before a warning becomes visible to customers.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Five Risk Areas to Review First
&lt;/h2&gt;

&lt;p&gt;Small businesses do not need a 60-page security program to start. They need to focus on the website surfaces that most often create practical risk.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Risk area&lt;/th&gt;
&lt;th&gt;What to check first&lt;/th&gt;
&lt;th&gt;Business reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Access control&lt;/td&gt;
&lt;td&gt;Admin users, roles, MFA, staging access&lt;/td&gt;
&lt;td&gt;Prevent unauthorized site changes and private content exposure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security misconfiguration&lt;/td&gt;
&lt;td&gt;Debug mode, public backups, headers, runtime versions&lt;/td&gt;
&lt;td&gt;Reduce quiet mistakes that make a normal site easy to abuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Software supply chain&lt;/td&gt;
&lt;td&gt;Plugins, packages, themes, lockfiles, abandoned tools&lt;/td&gt;
&lt;td&gt;Limit risk from third-party code your business depends on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Injection&lt;/td&gt;
&lt;td&gt;Forms, search, booking tools, custom integrations&lt;/td&gt;
&lt;td&gt;Protect databases, lead data, and connected business systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-site scripting&lt;/td&gt;
&lt;td&gt;Displayed user input, widgets, unsafe scripts&lt;/td&gt;
&lt;td&gt;Protect visitors from attacker-controlled scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  1. Access Control
&lt;/h3&gt;

&lt;p&gt;OWASP lists Broken Access Control as the number one risk in the OWASP Top 10:2025, and its introduction says this category remains the most serious application security risk (OWASP Foundation, 2025a, 2025b).&lt;/p&gt;

&lt;p&gt;For a small business website, access control usually means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Admin logins.&lt;/li&gt;
&lt;li&gt;CMS roles.&lt;/li&gt;
&lt;li&gt;Customer portal permissions.&lt;/li&gt;
&lt;li&gt;Staging site protection.&lt;/li&gt;
&lt;li&gt;File uploads.&lt;/li&gt;
&lt;li&gt;Private pages.&lt;/li&gt;
&lt;li&gt;API routes.&lt;/li&gt;
&lt;li&gt;Form submission endpoints.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The question is not only "Can someone log in?" The better question is "Can someone access something they should not be able to access?"&lt;/p&gt;

&lt;p&gt;Use strong passwords, require multifactor authentication where available, remove former vendors and employees, avoid shared admin accounts, protect staging sites, and limit each user to the access they actually need.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Security Misconfiguration
&lt;/h3&gt;

&lt;p&gt;OWASP moved Security Misconfiguration to number two in the 2025 list, noting that modern software increasingly depends on configuration choices (OWASP Foundation, 2025b). That matters because small business sites often combine hosting settings, DNS records, CDN rules, form settings, cache settings, environment variables, redirects, robots rules, and third-party scripts.&lt;/p&gt;

&lt;p&gt;Common misconfigurations include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Public staging sites indexed by Google.&lt;/li&gt;
&lt;li&gt;Debug mode left on in production.&lt;/li&gt;
&lt;li&gt;Overly broad file permissions.&lt;/li&gt;
&lt;li&gt;Missing security headers.&lt;/li&gt;
&lt;li&gt;Old PHP or Node versions.&lt;/li&gt;
&lt;li&gt;Exposed environment files.&lt;/li&gt;
&lt;li&gt;Public admin paths without rate limiting.&lt;/li&gt;
&lt;li&gt;Backups stored inside the public web root.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Misconfiguration is dangerous because the site can look normal while the risk is sitting in plain sight.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Software Supply Chain Failures
&lt;/h3&gt;

&lt;p&gt;OWASP added Software Supply Chain Failures as a top-three risk in 2025 (OWASP Foundation, 2025c). This category is especially relevant for modern websites because few sites are built from one piece of software. A simple business website may depend on dozens or hundreds of packages, plugins, themes, build tools, hosting adapters, and third-party scripts.&lt;/p&gt;

&lt;p&gt;The business owner does not need to audit every line of code personally. They do need someone to own these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What platform, framework, plugins, packages, and themes does the site use?&lt;/li&gt;
&lt;li&gt;Which dependencies are outdated or abandoned?&lt;/li&gt;
&lt;li&gt;Are updates tested before production?&lt;/li&gt;
&lt;li&gt;Can a bad update be rolled back quickly?&lt;/li&gt;
&lt;li&gt;Are lockfiles, plugin inventories, and hosting versions documented?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If nobody can answer those questions, the website is harder to defend and harder to recover.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Injection
&lt;/h3&gt;

&lt;p&gt;CISA and the FBI warned in March 2024 that SQL injection remains a persistent class of defect despite decades of known mitigations. Their Secure by Design alert explains that SQL injection happens when user-supplied input is inserted into a SQL command, and recommends parameterized queries with prepared statements as the standard defense (CISA &amp;amp; FBI, 2024a).&lt;/p&gt;

&lt;p&gt;Small businesses usually encounter injection risk through forms, search boxes, booking tools, old plugins, custom dashboards, and poorly built integrations.&lt;/p&gt;

&lt;p&gt;The fix is not "sanitize harder" as a vague slogan. The fix is to use secure framework defaults, parameterized database access, server-side validation, and code review on every feature that accepts user input.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Cross-Site Scripting
&lt;/h3&gt;

&lt;p&gt;CISA and the FBI also warned that cross-site scripting remains preventable and should not be present in software products. Their September 2024 alert says XSS can allow malicious scripts to be injected into web applications, and recommends input validation, output encoding, code reviews, threat modeling, and adversarial testing (CISA &amp;amp; FBI, 2024b).&lt;/p&gt;

&lt;p&gt;For small businesses, XSS risk often appears in places that accept or display content:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Contact forms.&lt;/li&gt;
&lt;li&gt;Review widgets.&lt;/li&gt;
&lt;li&gt;Blog comments.&lt;/li&gt;
&lt;li&gt;Search results.&lt;/li&gt;
&lt;li&gt;Admin dashboards.&lt;/li&gt;
&lt;li&gt;Customer messages.&lt;/li&gt;
&lt;li&gt;User-uploaded content.&lt;/li&gt;
&lt;li&gt;Embedded third-party scripts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Modern frameworks help, but they do not eliminate every edge case. Be careful with custom HTML, unsafe script injection, poorly reviewed plugins, and any feature that displays untrusted text.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Website Vulnerability Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist monthly, and immediately after a high-severity advisory affects your website stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confirm Ownership
&lt;/h3&gt;

&lt;p&gt;Assign one person or vendor to own website maintenance. "The hosting company probably handles it" is not a plan. Hosting providers may patch infrastructure, but they usually do not update your custom code, plugins, content system, DNS rules, analytics scripts, or business workflows.&lt;/p&gt;

&lt;p&gt;Your owner should document:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Website platform and version.&lt;/li&gt;
&lt;li&gt;Hosting provider.&lt;/li&gt;
&lt;li&gt;DNS provider.&lt;/li&gt;
&lt;li&gt;CMS admin users.&lt;/li&gt;
&lt;li&gt;Framework and package manager.&lt;/li&gt;
&lt;li&gt;Plugins, apps, themes, and integrations.&lt;/li&gt;
&lt;li&gt;Contact form delivery path.&lt;/li&gt;
&lt;li&gt;Backup location and restore process.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Patch the Stack
&lt;/h3&gt;

&lt;p&gt;Review the full stack, not only the visible website.&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CMS core.&lt;/li&gt;
&lt;li&gt;Plugins and themes.&lt;/li&gt;
&lt;li&gt;JavaScript packages.&lt;/li&gt;
&lt;li&gt;Server runtime, such as Node or PHP.&lt;/li&gt;
&lt;li&gt;Framework versions.&lt;/li&gt;
&lt;li&gt;Hosting build images.&lt;/li&gt;
&lt;li&gt;Form libraries.&lt;/li&gt;
&lt;li&gt;Email dependencies.&lt;/li&gt;
&lt;li&gt;Analytics and marketing scripts.&lt;/li&gt;
&lt;li&gt;CDN, cache, and WAF settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;NIST's Secure Software Development Framework recommends secure development practices that reduce vulnerabilities in released software, mitigate the impact of issues that still slip through, and address root causes to prevent recurrence (Souppaya et al., 2022). In plain terms, patching should be part of the way the website is managed, not a panic task after something goes wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove What You Do Not Use
&lt;/h3&gt;

&lt;p&gt;Unused software is easy to ignore and hard to defend. Remove inactive plugins, old themes, unused packages, abandoned scripts, test pages, stale admin accounts, and old integrations.&lt;/p&gt;

&lt;p&gt;Every unused dependency is another thing that can become vulnerable without providing business value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protect Admin Access
&lt;/h3&gt;

&lt;p&gt;Lock down the accounts that can change the site.&lt;/p&gt;

&lt;p&gt;At minimum:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Require unique passwords.&lt;/li&gt;
&lt;li&gt;Enable multifactor authentication where possible.&lt;/li&gt;
&lt;li&gt;Remove former employees and vendors.&lt;/li&gt;
&lt;li&gt;Avoid shared administrator accounts.&lt;/li&gt;
&lt;li&gt;Limit admin roles.&lt;/li&gt;
&lt;li&gt;Review password reset emails.&lt;/li&gt;
&lt;li&gt;Rate limit login attempts where the platform supports it.&lt;/li&gt;
&lt;li&gt;Keep recovery codes in a secure place.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access control is usually cheaper to fix before an incident than after an account is abused.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the Lead Path After Updates
&lt;/h3&gt;

&lt;p&gt;Security updates can break important workflows if they are rushed. After every material update, test the actual customer path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Homepage loads.&lt;/li&gt;
&lt;li&gt;Service pages load.&lt;/li&gt;
&lt;li&gt;Contact form submits.&lt;/li&gt;
&lt;li&gt;Email notification arrives.&lt;/li&gt;
&lt;li&gt;Calendar or booking link works.&lt;/li&gt;
&lt;li&gt;Phone links and CTA buttons work.&lt;/li&gt;
&lt;li&gt;Blog posts render.&lt;/li&gt;
&lt;li&gt;Images load.&lt;/li&gt;
&lt;li&gt;Sitemap and robots.txt still respond.&lt;/li&gt;
&lt;li&gt;Analytics and conversion tracking still fire.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good maintenance protects security and revenue at the same time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1762340915700-356b34475448%3Fauto%3Dformat%26fit%3Dcrop%26fm%3Djpg%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D%26ixlib%3Drb-4.1.0%26q%3D60%26w%3D3000" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1762340915700-356b34475448%3Fauto%3Dformat%26fit%3Dcrop%26fm%3Djpg%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D%26ixlib%3Drb-4.1.0%26q%3D60%26w%3D3000" alt="Security software quick scan screen" width="3000" height="1871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A useful maintenance plan checks vulnerable areas regularly, documents what changed, and confirms the customer journey still works.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Ask Your Web Developer or Agency
&lt;/h2&gt;

&lt;p&gt;If someone else manages your website, send these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What platform, framework, CMS, plugins, and runtime versions are live right now?&lt;/li&gt;
&lt;li&gt;Which parts of the site accept user input?&lt;/li&gt;
&lt;li&gt;Are any plugins, packages, or themes abandoned?&lt;/li&gt;
&lt;li&gt;How quickly do we patch critical vulnerabilities?&lt;/li&gt;
&lt;li&gt;Do we test updates before production?&lt;/li&gt;
&lt;li&gt;What backup can we restore from today?&lt;/li&gt;
&lt;li&gt;How often are admin users reviewed?&lt;/li&gt;
&lt;li&gt;Is multifactor authentication enabled for admin access?&lt;/li&gt;
&lt;li&gt;Are forms protected against spam and abuse?&lt;/li&gt;
&lt;li&gt;Do we monitor uptime, form failures, and crawl errors?&lt;/li&gt;
&lt;li&gt;Who gets notified when a security advisory affects our stack?&lt;/li&gt;
&lt;li&gt;What would we do if the site were defaced or blocked tomorrow?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The answer does not need to be complicated. It does need to be specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Small Business Website Vulnerabilities
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How often should a small business update its website?
&lt;/h3&gt;

&lt;p&gt;Review website software monthly at minimum. Apply critical security patches as soon as they are available, especially when the affected software is internet-facing or accepts user input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a brochure website still at risk?
&lt;/h3&gt;

&lt;p&gt;Yes. A brochure site can still be abused if it has forms, admin access, plugins, scripts, a CMS, hosting credentials, or outdated dependencies. Static sites usually have a smaller attack surface, but they still need domain, hosting, DNS, and form security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will security updates hurt SEO?
&lt;/h3&gt;

&lt;p&gt;They should not if they are tested properly. The SEO risk comes from broken redirects, missing metadata, failed pages, blocked crawlers, broken images, bad canonicals, or forms that stop working after an update.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the fastest way to reduce risk this week?
&lt;/h3&gt;

&lt;p&gt;Remove unused plugins and accounts, enable multifactor authentication on admin accounts, verify backups, update critical software, and test the contact form. Those steps reduce common risk quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do small businesses need a vulnerability scanner?
&lt;/h3&gt;

&lt;p&gt;Many do, but a scanner is not a substitute for ownership. Scanners can find exposed software, missing headers, outdated dependencies, and common flaws. Someone still needs to review findings, prioritize fixes, and confirm the repair.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Website vulnerability management is now part of small business operations. The 2026 DBIR shows why: attackers are exploiting software flaws at scale, and the window to respond is getting shorter.&lt;/p&gt;

&lt;p&gt;You do not need enterprise complexity to improve security. You need a clear owner, a monthly review, fast critical patching, clean backups, limited admin access, dependency awareness, and testing after every meaningful change.&lt;/p&gt;

&lt;p&gt;That same discipline supports SEO, AEO, and GEO. A website that stays patched, stable, fast, and trustworthy is easier for customers to use, easier for search engines to crawl, and easier for AI answer systems to cite accurately.&lt;/p&gt;

&lt;p&gt;Echo Effect helps small businesses build and maintain websites with performance, search visibility, and practical security in mind. If your current site has no patch owner, no backup plan, or no clear inventory, start with a technical website audit before the next vulnerability turns into lost leads.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Cybersecurity and Infrastructure Security Agency, &amp;amp; Federal Bureau of Investigation. (2024a, March). &lt;em&gt;Secure by design alert: Eliminating SQL injection vulnerabilities in software&lt;/em&gt;. &lt;a href="https://www.ic3.gov/CSA/2024/240325.pdf" rel="noopener noreferrer"&gt;https://www.ic3.gov/CSA/2024/240325.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cybersecurity and Infrastructure Security Agency, &amp;amp; Federal Bureau of Investigation. (2024b, September). &lt;em&gt;Secure by design alert: Eliminating cross-site scripting vulnerabilities&lt;/em&gt;. &lt;a href="https://www.ic3.gov/CSA/2024/240917.pdf" rel="noopener noreferrer"&gt;https://www.ic3.gov/CSA/2024/240917.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OWASP Foundation. (2025a). &lt;em&gt;A01:2025 Broken access control&lt;/em&gt;. &lt;a href="https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/" rel="noopener noreferrer"&gt;https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OWASP Foundation. (2025b). &lt;em&gt;Introduction: OWASP Top 10:2025&lt;/em&gt;. &lt;a href="https://owasp.org/Top10/2025/0x00_2025-Introduction/" rel="noopener noreferrer"&gt;https://owasp.org/Top10/2025/0x00_2025-Introduction/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OWASP Foundation. (2025c). &lt;em&gt;A03:2025 Software supply chain failures&lt;/em&gt;. &lt;a href="https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/" rel="noopener noreferrer"&gt;https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Souppaya, M., Scarfone, K., &amp;amp; Dodson, D. (2022). &lt;em&gt;Secure Software Development Framework (SSDF) version 1.1: Recommendations for mitigating the risk of software vulnerabilities&lt;/em&gt; (NIST Special Publication 800-218). National Institute of Standards and Technology. &lt;a href="https://csrc.nist.gov/pubs/sp/800/218/final" rel="noopener noreferrer"&gt;https://csrc.nist.gov/pubs/sp/800/218/final&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verizon. (2026a). &lt;em&gt;2026 Data Breach Investigations Report&lt;/em&gt;. &lt;a href="https://www.verizon.com/business/resources/reports/dbir/" rel="noopener noreferrer"&gt;https://www.verizon.com/business/resources/reports/dbir/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verizon. (2026b, May). &lt;em&gt;Breach entry point, 2026 DBIR finds&lt;/em&gt;. &lt;a href="https://www.verizon.com/about/news/breach-industry-wide-dbir-finds" rel="noopener noreferrer"&gt;https://www.verizon.com/about/news/breach-industry-wide-dbir-finds&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>cybersecurity</category>
      <category>webdesign</category>
    </item>
    <item>
      <title>Should Small Businesses Block AI Crawlers in 2026?</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:26:56 +0000</pubDate>
      <link>https://dev.to/rverwey/should-small-businesses-block-ai-crawlers-in-2026-3f43</link>
      <guid>https://dev.to/rverwey/should-small-businesses-block-ai-crawlers-in-2026-3f43</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/ai-crawler-access-small-business-websites-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AI crawlers are no longer a side issue for publishers and large media companies. They are now part of how customers discover local services, compare businesses, ask buying questions, and decide which website is worth trusting.&lt;/p&gt;

&lt;p&gt;That creates a practical question for small business owners: should your website allow AI crawlers, block them, or split the difference?&lt;/p&gt;

&lt;p&gt;The short answer is this: most small businesses should allow search and user-requested AI crawlers that can send visibility back to the business, but they should be more cautious about training crawlers, unknown bots, and automated traffic that creates cost without a clear business return. The right answer is not "allow everything" or "block everything." It is a written access policy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; If your website depends on discovery, do not blindly block every AI crawler. Separate search, agent, and training use cases, then decide what each category is allowed to do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why AI Crawler Access Changed in 2026
&lt;/h2&gt;

&lt;p&gt;For years, the crawler bargain was easy to understand. Search engines crawled public pages, indexed them, and sent people back through organic search results. Website owners allowed crawling because the traffic was worth it.&lt;/p&gt;

&lt;p&gt;AI search complicates that bargain. Some bots crawl to build search indexes that can cite and link to your website. Some fetch pages because a user asked an assistant a specific question. Others collect public content for model training, where the business value to the website owner is harder to measure.&lt;/p&gt;

&lt;p&gt;Cloudflare framed this shift clearly in its July 1, 2026 update on AI traffic controls. It separated AI bot activity into three main use cases: Search, Agent, and Training. Search crawlers collect or index content so they can answer future questions. Agent traffic acts in real time on a person's behalf. Training crawlers collect content that may be absorbed into an AI model (Lee &amp;amp; Becker, 2026).&lt;/p&gt;

&lt;p&gt;That distinction matters. A small business may want ChatGPT, Perplexity, Claude, or Google to cite its service pages in answers. That same business may not want every training crawler copying its full blog archive forever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1543286386-713bdd548da4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1543286386-713bdd548da4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Analytics dashboard with charts used to monitor crawler and search performance" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI crawler policy should be tied to measurable visibility, traffic, server behavior, and lead quality.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three AI Bot Categories That Matter
&lt;/h2&gt;

&lt;p&gt;Small businesses do not need to memorize every user agent on the internet. They need a decision framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Search crawlers
&lt;/h3&gt;

&lt;p&gt;Search crawlers are the easiest category to justify allowing when visibility is the goal. These bots help AI-powered search products discover and cite websites.&lt;/p&gt;

&lt;p&gt;OpenAI's crawler documentation says &lt;code&gt;OAI-SearchBot&lt;/code&gt; is used to surface websites in ChatGPT search features. OpenAI also explains that site owners can allow &lt;code&gt;OAI-SearchBot&lt;/code&gt; for search visibility while disallowing &lt;code&gt;GPTBot&lt;/code&gt; for training use, because those settings are independent (OpenAI, n.d.).&lt;/p&gt;

&lt;p&gt;Perplexity documents a similar split. &lt;code&gt;PerplexityBot&lt;/code&gt; is designed to surface and link websites in Perplexity search results, while &lt;code&gt;Perplexity-User&lt;/code&gt; supports user-triggered fetches when someone asks a question (Perplexity, n.d.).&lt;/p&gt;

&lt;p&gt;For a small business website, search crawlers usually deserve access to public marketing pages, service pages, blog posts, case studies, reviews, and FAQs. Those are the pages that can earn citations, impressions, and qualified leads.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Agent and user-requested crawlers
&lt;/h3&gt;

&lt;p&gt;Agent traffic is different from background crawling. It may happen because a real person asks an AI assistant to compare providers, summarize a service page, check pricing, or find contact information.&lt;/p&gt;

&lt;p&gt;OpenAI says &lt;code&gt;ChatGPT-User&lt;/code&gt; is used for certain user actions in ChatGPT and Custom GPTs, is not automatic web crawling, and is not used to determine whether content appears in search (OpenAI, n.d.). Anthropic lists &lt;code&gt;Claude-User&lt;/code&gt; as user-directed retrieval and warns that disabling it may reduce visibility for user-directed web search (Anthropic, n.d.).&lt;/p&gt;

&lt;p&gt;This kind of traffic can be valuable because it may happen close to a buying decision. A customer might ask, "Find a Florida web design agency that works with small businesses and understands SEO." If an assistant cannot fetch your public pages, your business may not be considered.&lt;/p&gt;

&lt;p&gt;Agent traffic still needs guardrails. Forms, checkout flows, booking tools, and account areas should be protected from abuse. Public informational pages can usually be available.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Training crawlers
&lt;/h3&gt;

&lt;p&gt;Training crawlers are the most sensitive category. They collect content that may be used to improve AI foundation models. That may benefit the broader AI ecosystem, but the return to an individual small business is usually indirect.&lt;/p&gt;

&lt;p&gt;OpenAI describes &lt;code&gt;GPTBot&lt;/code&gt; as a crawler for content that may be used in training its generative AI foundation models. Anthropic describes &lt;code&gt;ClaudeBot&lt;/code&gt; as a crawler that collects web content that could contribute to model training (Anthropic, n.d.; OpenAI, n.d.).&lt;/p&gt;

&lt;p&gt;Some businesses will allow training crawlers because they want maximum exposure and do not publish sensitive or proprietary material. Others will block training crawlers while keeping search crawlers open. That is a reasonable middle ground.&lt;/p&gt;

&lt;h2&gt;
  
  
  Robots.txt Is a Traffic Signal, Not a Security Wall
&lt;/h2&gt;

&lt;p&gt;The first tool most site owners hear about is &lt;code&gt;robots.txt&lt;/code&gt;. It is useful, but it is often misunderstood.&lt;/p&gt;

&lt;p&gt;Google Search Central explains that &lt;code&gt;robots.txt&lt;/code&gt; tells crawlers which URLs they can access and is mainly used to manage crawler traffic. Google is explicit that &lt;code&gt;robots.txt&lt;/code&gt; is not a mechanism for keeping a page out of Google Search results, and private material should be protected with stronger controls such as &lt;code&gt;noindex&lt;/code&gt; or password protection when appropriate (Google Search Central, 2025).&lt;/p&gt;

&lt;p&gt;The limitation is important: &lt;code&gt;robots.txt&lt;/code&gt; is a request. Respectable crawlers usually honor it. Bad or careless crawlers may ignore it.&lt;/p&gt;

&lt;p&gt;That means &lt;code&gt;robots.txt&lt;/code&gt; is good for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expressing crawler policy.&lt;/li&gt;
&lt;li&gt;Reducing wasteful crawling.&lt;/li&gt;
&lt;li&gt;Allowing or disallowing named AI bots.&lt;/li&gt;
&lt;li&gt;Separating search crawlers from training crawlers when a vendor supports that split.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is not good for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Protecting confidential content.&lt;/li&gt;
&lt;li&gt;Stopping hostile scraping by itself.&lt;/li&gt;
&lt;li&gt;Blocking all bot traffic at the network level.&lt;/li&gt;
&lt;li&gt;Guaranteeing that a disallowed URL cannot appear anywhere online.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If information should not be public, it should not be protected only by &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Google Says About AI Search Visibility
&lt;/h2&gt;

&lt;p&gt;Google's guidance is useful because it cuts through a lot of bad advice. Google says the same foundational SEO best practices still apply to AI Overviews and AI Mode. Pages need to be crawlable, indexed, eligible for snippets, internally discoverable, useful to users, and supported by visible text, relevant media, and structured data that matches the visible content (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;p&gt;Google also says there are no extra technical requirements to appear as a supporting link in AI Overviews or AI Mode, beyond being indexed and eligible for Google Search with a snippet (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;p&gt;For crawler policy, this creates a simple rule: if you want Google Search and Google's AI features to understand a public page, do not block Googlebot from crawling it. Google says AI features in Search use Googlebot crawling controls, while snippet and preview controls such as &lt;code&gt;nosnippet&lt;/code&gt;, &lt;code&gt;data-nosnippet&lt;/code&gt;, &lt;code&gt;max-snippet&lt;/code&gt;, and &lt;code&gt;noindex&lt;/code&gt; limit what can be shown from pages (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;p&gt;That is different from Google-Extended, which Google describes separately for limiting AI training and grounding in some other Google systems (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;p&gt;The practical takeaway: do not confuse search visibility controls with training opt-out controls. They are related, but they are not the same decision.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1516321497487-e288fb19713f%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1516321497487-e288fb19713f%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Team reviewing website strategy around a laptop and printed notes" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The best AI access policy is a business decision first, then a technical configuration.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical AI Crawler Policy for Small Businesses
&lt;/h2&gt;

&lt;p&gt;Here is a simple starting policy for a service business that wants visibility but does not want to give away control blindly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allow search crawlers for public marketing content
&lt;/h3&gt;

&lt;p&gt;Allow crawlers that are explicitly tied to search discovery and citation, such as Googlebot, OAI-SearchBot, PerplexityBot, and other reputable search-oriented bots, unless you have a specific reason to block them.&lt;/p&gt;

&lt;p&gt;Public pages that should usually stay crawlable include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Homepage.&lt;/li&gt;
&lt;li&gt;Service pages.&lt;/li&gt;
&lt;li&gt;About page.&lt;/li&gt;
&lt;li&gt;Contact page.&lt;/li&gt;
&lt;li&gt;Blog posts.&lt;/li&gt;
&lt;li&gt;FAQs.&lt;/li&gt;
&lt;li&gt;Case studies and portfolio pages.&lt;/li&gt;
&lt;li&gt;Public reviews or testimonials.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These pages support SEO, AEO, and GEO because they tell search systems and answer engines who you are, what you do, where you serve customers, and why you are credible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consider blocking training crawlers if your content is proprietary
&lt;/h3&gt;

&lt;p&gt;If your site includes original research, paid resources, detailed templates, premium guides, proprietary methods, or content you do not want used for model training, consider blocking training-specific user agents while keeping search-specific crawlers available.&lt;/p&gt;

&lt;p&gt;This is the key nuance many businesses miss. Blocking every AI bot may reduce discoverability. Allowing every AI bot may give away more than the business intends. Splitting the policy by use case is the more mature option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep user-requested fetchers available for public pages
&lt;/h3&gt;

&lt;p&gt;User-requested fetchers can help assistants answer questions about your business in the moment. For a small business, that can be valuable.&lt;/p&gt;

&lt;p&gt;The safer approach is to allow them to retrieve public content while protecting forms, private tools, admin routes, staging environments, and anything that should require authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use WAF and bot tools for enforcement
&lt;/h3&gt;

&lt;p&gt;When crawler behavior becomes abusive, use stronger controls than &lt;code&gt;robots.txt&lt;/code&gt;. A web application firewall, CDN bot management, rate limiting, and IP verification can help separate legitimate bots from spoofed user agents.&lt;/p&gt;

&lt;p&gt;Perplexity's documentation, for example, recommends using both user-agent and official IP range conditions when configuring WAF rules for its bots (Perplexity, n.d.). That same principle applies broadly: a user-agent string alone is easy to fake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitor the outcome
&lt;/h3&gt;

&lt;p&gt;Crawler policy is not a one-time setting. Review it monthly or quarterly.&lt;/p&gt;

&lt;p&gt;Watch for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Drops in Google Search Console impressions.&lt;/li&gt;
&lt;li&gt;Important pages disappearing from AI search citations.&lt;/li&gt;
&lt;li&gt;Sudden spikes in bot traffic.&lt;/li&gt;
&lt;li&gt;Server load tied to suspicious crawlers.&lt;/li&gt;
&lt;li&gt;AI referrals that convert into leads.&lt;/li&gt;
&lt;li&gt;Branded search growth after AI visibility.&lt;/li&gt;
&lt;li&gt;Crawl errors caused by CDN or WAF rules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google says Search Console can measure performance in generative AI features and warns against relying on third-party tools that claim access to internal AI ranking systems (Google Search Central, n.d.-b). Treat your own lead data as the final test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Pay Per Crawl Fits
&lt;/h2&gt;

&lt;p&gt;Cloudflare introduced Pay Per Crawl in 2025 as a private beta that lets content owners allow, charge, or block AI crawler access. The system uses HTTP status code &lt;code&gt;402 Payment Required&lt;/code&gt; and gives publishers a way to set a price per request across a domain (Allen &amp;amp; Newton, 2025).&lt;/p&gt;

&lt;p&gt;For most small businesses, this is not the first move. A local service business usually makes money from being discovered, contacted, and hired, not from charging crawlers to read its service pages.&lt;/p&gt;

&lt;p&gt;But Pay Per Crawl matters as a signal. The web is moving toward more explicit access rules. Website owners are asking better questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who is crawling my content?&lt;/li&gt;
&lt;li&gt;What are they using it for?&lt;/li&gt;
&lt;li&gt;Do they send users back?&lt;/li&gt;
&lt;li&gt;Do they respect my stated preferences?&lt;/li&gt;
&lt;li&gt;Can I measure the business return?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those questions are healthy, even if the answer for a small business is still "allow search, monitor agents, restrict training where appropriate."&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: AI Crawlers and Small Business Websites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should small businesses block all AI crawlers?
&lt;/h3&gt;

&lt;p&gt;Usually, no. Blocking all AI crawlers can reduce visibility in AI-powered search and user-requested answers. Most small businesses should separate search crawlers, user-requested agents, and training crawlers, then make a different decision for each category.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will blocking training crawlers hurt SEO?
&lt;/h3&gt;

&lt;p&gt;Not necessarily. Some vendors separate search and training crawlers. For example, OpenAI says site owners can allow &lt;code&gt;OAI-SearchBot&lt;/code&gt; while disallowing &lt;code&gt;GPTBot&lt;/code&gt;. The risk comes from blocking crawlers that are tied to search discovery or from blocking major search engines by mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is robots.txt enough to protect private content?
&lt;/h3&gt;

&lt;p&gt;No. &lt;code&gt;robots.txt&lt;/code&gt; is not a security control. It communicates crawler preferences, but it does not hide private material from the web. Use authentication, password protection, &lt;code&gt;noindex&lt;/code&gt;, server rules, or access controls for content that should not be public.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Google require llms.txt for AI Overviews or AI Mode?
&lt;/h3&gt;

&lt;p&gt;No. Google says no new machine-readable file, AI text file, special AI markup, or special schema is required to appear in AI Overviews or AI Mode. Foundational SEO still matters most: crawlability, helpful content, internal links, page experience, visible text, relevant media, and accurate structured data (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;h3&gt;
  
  
  What should a small business do this month?
&lt;/h3&gt;

&lt;p&gt;Review &lt;code&gt;robots.txt&lt;/code&gt;, confirm public pages are crawlable, decide whether training crawlers should be allowed, check CDN or WAF rules for accidental blocks, and monitor Search Console after any access change. The goal is controlled discoverability, not panic blocking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;AI crawler access is now part of SEO, AEO, and GEO strategy. It affects whether your business can be found, cited, summarized, compared, and recommended by AI-powered search tools.&lt;/p&gt;

&lt;p&gt;The smartest policy for most small businesses is selective access.&lt;/p&gt;

&lt;p&gt;Allow crawlers that support search visibility. Keep public pages available to user-requested assistants. Consider limiting training crawlers when your content is proprietary or when the business return is unclear. Use &lt;code&gt;robots.txt&lt;/code&gt; to state preferences, WAF rules to enforce suspicious traffic controls, and Search Console plus lead data to measure whether the policy is helping.&lt;/p&gt;

&lt;p&gt;Do not let fear make your business invisible. Do not let hype make your website a free-for-all. Treat crawler access like every other digital marketing decision: define the goal, measure the return, and adjust when the data changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Echo Effect helps small businesses build websites that are readable by people, search engines, and AI answer systems. If your crawler policy, robots.txt file, or AI visibility strategy is unclear, schedule a discovery call and we will identify the highest-impact fixes first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Allen, W., &amp;amp; Newton, S. (2025, July 1). &lt;em&gt;Introducing pay per crawl: Enabling content owners to charge AI crawlers for access&lt;/em&gt;. Cloudflare. &lt;a href="https://blog.cloudflare.com/introducing-pay-per-crawl/" rel="noopener noreferrer"&gt;https://blog.cloudflare.com/introducing-pay-per-crawl/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anthropic. (n.d.). &lt;em&gt;Does Anthropic crawl data from the web, and how can site owners block the crawler?&lt;/em&gt; Claude Help Center. Retrieved July 13, 2026, from &lt;a href="https://support.claude.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler" rel="noopener noreferrer"&gt;https://support.claude.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-a). &lt;em&gt;AI features and your website&lt;/em&gt;. Google for Developers. Retrieved July 13, 2026, from &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/ai-features&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-b). &lt;em&gt;Optimizing your website for generative AI features on Google Search&lt;/em&gt;. Google for Developers. Retrieved July 13, 2026, from &lt;a href="https://developers.google.com/search/docs/fundamentals/ai-optimization-guide" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/fundamentals/ai-optimization-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (2025, December 10). &lt;em&gt;Robots.txt introduction and guide&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/crawling-indexing/robots/intro" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/crawling-indexing/robots/intro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lee, J.-H., &amp;amp; Becker, B. (2026, July 1). &lt;em&gt;Your site, your rules: New AI traffic options for all customers&lt;/em&gt;. Cloudflare. &lt;a href="https://blog.cloudflare.com/content-independence-day-ai-options/" rel="noopener noreferrer"&gt;https://blog.cloudflare.com/content-independence-day-ai-options/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI. (n.d.). &lt;em&gt;Overview of OpenAI crawlers&lt;/em&gt;. OpenAI Developers. Retrieved July 13, 2026, from &lt;a href="https://developers.openai.com/api/docs/bots" rel="noopener noreferrer"&gt;https://developers.openai.com/api/docs/bots&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perplexity. (n.d.). &lt;em&gt;Perplexity crawlers&lt;/em&gt;. Perplexity Docs. Retrieved July 13, 2026, from &lt;a href="https://docs.perplexity.ai/docs/resources/perplexity-crawlers" rel="noopener noreferrer"&gt;https://docs.perplexity.ai/docs/resources/perplexity-crawlers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Interop 2026 Website Upgrades for Small Businesses</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:26:52 +0000</pubDate>
      <link>https://dev.to/rverwey/interop-2026-website-upgrades-for-small-businesses-30ba</link>
      <guid>https://dev.to/rverwey/interop-2026-website-upgrades-for-small-businesses-30ba</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/interop-2026-small-business-website-upgrades" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Interop 2026 is one of the most practical web development stories of the year because it is not about one framework, one browser, or one vendor. It is about making important web platform features work more consistently across Chrome, Edge, Firefox, and Safari.&lt;/p&gt;

&lt;p&gt;For small businesses, that matters more than it sounds. Browser inconsistency turns into expensive rework, broken forms, awkward mobile menus, glitchy popups, unreliable animations, and website features that behave differently for different customers.&lt;/p&gt;

&lt;p&gt;As of July 6, 2026, the smart move is not to chase every new feature. The smart move is to modernize around features that are becoming reliable, supported, and useful for real customer journeys.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Interop 2026 helps browser teams improve the same high-priority web features during the same year. Small businesses should use it as a signal to plan safer upgrades for menus, dialogs, page transitions, responsive layouts, mobile behavior, accessibility, and AI-search-ready content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Is Interop 2026?
&lt;/h2&gt;

&lt;p&gt;Interop 2026 is a coordinated cross-browser effort run by representatives from major browser engine contributors, including Apple, Google, Igalia, Microsoft, and Mozilla. The project selects focus areas that matter to developers and users, then tracks browser progress through automated Web Platform Tests (Andrew, 2026; Web Platform Tests, 2026).&lt;/p&gt;

&lt;p&gt;The 2026 focus areas include features such as anchor positioning, container style queries, dialogs and popovers, view transitions, scroll-driven animations, scroll snap, web compatibility fixes, WebRTC, WebTransport, and mobile testing work (Web Platform Tests, 2026; Wu &amp;amp; Simmons, 2026).&lt;/p&gt;

&lt;p&gt;That list may sound technical, but the business outcome is simple: websites should be easier to build once and trust across modern browsers.&lt;/p&gt;

&lt;p&gt;That is especially useful for small business sites because customers do not care which browser caused a bug. If a menu fails on iPhone, a booking form shifts on Android, or a modal traps keyboard focus on desktop, the business owns the bad experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Baseline Belongs in the Same Conversation
&lt;/h2&gt;

&lt;p&gt;Interop is about improving cross-browser consistency. Baseline is about knowing when a web platform feature is ready to use.&lt;/p&gt;

&lt;p&gt;web.dev explains that Baseline gives developers clear information about which features are supported across the core browser set: Chrome, Edge, Firefox, and Safari on desktop and mobile. A feature can be "newly available" when all core browsers support it, then "widely available" after 30 months have passed (Google Chrome Developers, n.d.).&lt;/p&gt;

&lt;p&gt;For a business owner, Baseline is useful because it turns a vague question into a practical one.&lt;/p&gt;

&lt;p&gt;Instead of asking, "Can our website use this new feature?" ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is it Baseline?&lt;/li&gt;
&lt;li&gt;Is it supported by the browsers our customers actually use?&lt;/li&gt;
&lt;li&gt;Does it improve conversion, accessibility, performance, or maintenance?&lt;/li&gt;
&lt;li&gt;Can we ship it without adding heavy JavaScript?&lt;/li&gt;
&lt;li&gt;Can we keep a simple fallback for older browsers?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That mindset prevents two common mistakes: using outdated techniques forever because they feel safe, or adopting new features too early because they feel exciting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1517180102446-f3ece451e9d8%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1517180102446-f3ece451e9d8%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Developer reviewing website code on a laptop during a browser compatibility update" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Modern web upgrades should reduce complexity, not add it. Interop and Baseline help teams choose native browser features with stronger support.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Business Website Upgrades Worth Watching
&lt;/h2&gt;

&lt;p&gt;Not every Interop 2026 focus area belongs on a brochure site. A small business website does not need experimental complexity to look modern. It needs dependable navigation, clear content, fast pages, usable forms, accessible interactions, and crawlable answers.&lt;/p&gt;

&lt;p&gt;These are the areas most likely to matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Better Popups, Dialogs, and Menus
&lt;/h3&gt;

&lt;p&gt;Dialogs and popovers are part of the Interop 2026 focus list. The work includes improvements around the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element and Popover API, including open states and behavior for subordinate popovers (Andrew, 2026).&lt;/p&gt;

&lt;p&gt;That matters because many websites still use custom JavaScript for dropdowns, modals, tooltips, announcement bars, cookie notices, quote prompts, and mobile navigation. Custom overlays are easy to get wrong. They can trap focus, block content, fail screen readers, or create layout shifts.&lt;/p&gt;

&lt;p&gt;Native browser primitives can reduce that risk when used carefully. For small businesses, the priority should be practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile menus that open and close predictably.&lt;/li&gt;
&lt;li&gt;Quote request popups that do not block the whole page.&lt;/li&gt;
&lt;li&gt;Tooltips that support keyboard and touch users.&lt;/li&gt;
&lt;li&gt;Cookie notices that do not cover important actions.&lt;/li&gt;
&lt;li&gt;Form dialogs that keep focus where users expect it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to add more popups. The goal is to make necessary overlays less fragile.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. More Reliable Responsive Layouts
&lt;/h3&gt;

&lt;p&gt;Container style queries and anchor positioning are also Interop 2026 focus areas. Container style queries let styles respond to a container's properties rather than only the viewport. Anchor positioning lets one element be positioned relative to another, such as placing a tooltip beside the field it explains (Andrew, 2026; Web Platform Tests, 2026).&lt;/p&gt;

&lt;p&gt;For small business websites, this can make component design more reliable. Service cards, pricing tables, testimonial blocks, FAQ sections, and lead forms often appear in different layouts across the site. A component that adapts based on its own container can be easier to reuse without layout hacks.&lt;/p&gt;

&lt;p&gt;That can improve maintainability and page speed. When native CSS handles layout decisions, a site may need less JavaScript and fewer brittle breakpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cleaner Page Transitions
&lt;/h3&gt;

&lt;p&gt;View transitions continued from prior Interop work into 2026. WebKit notes that cross-document view transitions can create smoother animated transitions between pages, reducing abrupt jumps when users navigate a site (Wu &amp;amp; Simmons, 2026).&lt;/p&gt;

&lt;p&gt;This is not a license to animate everything. Overdone motion hurts usability.&lt;/p&gt;

&lt;p&gt;Used carefully, page transitions can make service pages, galleries, product pages, and portfolio pages feel smoother without turning the site into a heavy app. They can also help preserve orientation when users move through related pages.&lt;/p&gt;

&lt;p&gt;The practical rule is simple: motion should clarify the experience. If it distracts from the call to action, remove it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Stronger Mobile Testing
&lt;/h3&gt;

&lt;p&gt;Interop 2026 includes mobile testing as an investigation area. WebKit specifically points to mobile-specific infrastructure work for dynamic viewport changes, which are crucial for responsive mobile web experiences (Wu &amp;amp; Simmons, 2026).&lt;/p&gt;

&lt;p&gt;That matters because small business traffic often comes from mobile moments: someone needs a quote, checks reviews, looks up hours, compares services, or tries to tap a phone number.&lt;/p&gt;

&lt;p&gt;A mobile site should pass these checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first screen explains what the business does.&lt;/li&gt;
&lt;li&gt;The primary action is visible and easy to tap.&lt;/li&gt;
&lt;li&gt;Forms do not jump when the keyboard opens.&lt;/li&gt;
&lt;li&gt;Sticky headers do not hide content.&lt;/li&gt;
&lt;li&gt;Menus work with touch, keyboard, and screen readers.&lt;/li&gt;
&lt;li&gt;Images are sharp but not oversized.&lt;/li&gt;
&lt;li&gt;Contact information is crawlable text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mobile is not a smaller desktop site. It is often the main sales path.&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Supports SEO, AEO, and GEO
&lt;/h2&gt;

&lt;p&gt;Interop and Baseline are web development topics, but they directly affect search visibility.&lt;/p&gt;

&lt;p&gt;Google Search Central says Core Web Vitals measure real-world user experience for loading performance, interactivity, and visual stability. Google recommends good Core Web Vitals for Search and general user experience, with LCP at 2.5 seconds or faster, INP under 200 milliseconds, and CLS below 0.1 (Google Search Central, 2025).&lt;/p&gt;

&lt;p&gt;Modern native features can help when they replace heavy scripts, reduce layout hacks, and make pages easier to interact with. Faster, more stable pages support SEO because users and crawlers can access content with less friction.&lt;/p&gt;

&lt;p&gt;They also support AEO and GEO.&lt;/p&gt;

&lt;p&gt;Google's guidance for AI features in Search says existing SEO fundamentals remain relevant for AI Overviews and AI Mode. Site owners should allow crawling, make content easy to find through internal links, provide a good page experience, keep important content available in text, support content with useful images and videos, and make sure structured data matches visible text (Google Search Central, n.d.).&lt;/p&gt;

&lt;p&gt;That means an AI-ready website still needs old-fashioned discipline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear HTML content.&lt;/li&gt;
&lt;li&gt;Descriptive headings.&lt;/li&gt;
&lt;li&gt;Useful internal links.&lt;/li&gt;
&lt;li&gt;Fast pages.&lt;/li&gt;
&lt;li&gt;Accurate structured data.&lt;/li&gt;
&lt;li&gt;Real author attribution.&lt;/li&gt;
&lt;li&gt;Original answers to customer questions.&lt;/li&gt;
&lt;li&gt;Images that support the page topic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future of search is not only about prompts. It is also about whether your website gives machines and people clean, trustworthy information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1454165804606-c3d57bc86b40%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1454165804606-c3d57bc86b40%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Business owner planning website improvements with analytics, laptop, and printed documents" width="1200" height="801"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The best website upgrades connect platform changes to measurable outcomes: faster pages, clearer answers, better leads, and fewer browser-specific bugs.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Upgrade Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist before adding new web platform features to a small business website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit the Browser Risk
&lt;/h3&gt;

&lt;p&gt;Check analytics to see the browsers, devices, and operating systems your customers actually use. A feature that works well for a developer's desktop setup may still need testing on Safari for iOS, Chrome for Android, Edge on Windows, and Firefox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prefer Baseline Features
&lt;/h3&gt;

&lt;p&gt;Start with features marked Baseline when possible. If a feature is newly available, test it carefully and provide a fallback. If it has limited availability, avoid using it for essential conversion paths unless there is a strong reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace JavaScript Only When the Native Feature Is Better
&lt;/h3&gt;

&lt;p&gt;Native does not automatically mean better. A native dialog used poorly is still a poor experience. The right test is whether the change improves performance, accessibility, maintainability, or user clarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the Money Pages First
&lt;/h3&gt;

&lt;p&gt;Do not limit compatibility testing to the homepage. Test the pages that create business value:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primary service pages.&lt;/li&gt;
&lt;li&gt;Contact page.&lt;/li&gt;
&lt;li&gt;Quote request forms.&lt;/li&gt;
&lt;li&gt;Booking pages.&lt;/li&gt;
&lt;li&gt;Paid ad landing pages.&lt;/li&gt;
&lt;li&gt;Blog posts that attract search traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the homepage works but the lead form fails, the site still fails.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Content Visible as Text
&lt;/h3&gt;

&lt;p&gt;Do not hide important service details inside images, animations, tabs that never render server-side, or scripts that crawlers may struggle to process. If the information matters to customers, write it as visible text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measure Before and After
&lt;/h3&gt;

&lt;p&gt;Before shipping upgrades, record Core Web Vitals, crawlability, form completion behavior, and conversion rates. After shipping, measure again. A modern implementation that worsens INP or lead flow is not an upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Interop 2026 and Small Business Websites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Interop 2026 mean every browser supports the same features now?
&lt;/h3&gt;

&lt;p&gt;No. Interop 2026 is an active effort to improve selected focus areas during 2026. Use it as a planning signal, then verify current browser support before shipping important features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Baseline the same as Interop?
&lt;/h3&gt;

&lt;p&gt;No. Interop coordinates browser work on high-priority focus areas. Baseline helps developers understand whether a feature is ready to use across the core browser set.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should a small business redesign its website because of Interop 2026?
&lt;/h3&gt;

&lt;p&gt;Not automatically. Interop 2026 is a reason to review outdated patterns and plan safer upgrades. A redesign makes sense when your current site is slow, hard to update, difficult to use on mobile, or unreliable across browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which upgrades are most useful for lead generation?
&lt;/h3&gt;

&lt;p&gt;Focus on reliable mobile navigation, faster pages, accessible dialogs, stable forms, clear service content, and crawlable FAQ sections. Those improvements support both customer experience and search visibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do AI search tools care about modern browser features?
&lt;/h3&gt;

&lt;p&gt;AI search tools care most about accessible, crawlable, helpful content. Modern browser features help when they make content easier to reach, reduce friction, improve page experience, and keep important information available as text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Interop 2026 is a reminder that the web platform keeps improving, and small business websites should not be frozen in old patterns forever.&lt;/p&gt;

&lt;p&gt;The right approach is selective modernization. Use Baseline to choose safer features. Use Interop 2026 to understand where browser reliability is improving. Test the customer journey on real devices. Measure Core Web Vitals. Keep service information visible, structured, and easy to cite.&lt;/p&gt;

&lt;p&gt;That combination supports SEO, AEO, and GEO because it gives search engines, answer engines, AI systems, and customers the same thing: a fast, trustworthy website that clearly explains what the business does and how to take the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Andrew, R. (2026, February 12). &lt;em&gt;Interop 2026: Continuing to improve the web for developers&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/blog/interop-2026" rel="noopener noreferrer"&gt;https://web.dev/blog/interop-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Chrome Developers. (n.d.). &lt;em&gt;Baseline&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/baseline" rel="noopener noreferrer"&gt;https://web.dev/baseline&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.). &lt;em&gt;AI features and your website&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/ai-features&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (2025, December 10). &lt;em&gt;Understanding Core Web Vitals and Google search results&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/appearance/core-web-vitals" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/core-web-vitals&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Web Platform Tests. (2026). &lt;em&gt;Interop 2026&lt;/em&gt;. GitHub. &lt;a href="https://github.com/web-platform-tests/interop/blob/main/2026/README.md" rel="noopener noreferrer"&gt;https://github.com/web-platform-tests/interop/blob/main/2026/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wu, Y., &amp;amp; Simmons, J. (2026, February 12). &lt;em&gt;Announcing Interop 2026&lt;/em&gt;. WebKit. &lt;a href="https://webkit.org/blog/17818/announcing-interop-2026/" rel="noopener noreferrer"&gt;https://webkit.org/blog/17818/announcing-interop-2026/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
      <category>webdesign</category>
    </item>
    <item>
      <title>Core Web Vitals Checklist for Small Business Websites</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:26:18 +0000</pubDate>
      <link>https://dev.to/rverwey/core-web-vitals-checklist-for-small-business-websites-4ef7</link>
      <guid>https://dev.to/rverwey/core-web-vitals-checklist-for-small-business-websites-4ef7</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/core-web-vitals-small-business-checklist-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Core Web Vitals are still one of the clearest ways to tell whether a small business website feels fast, stable, and easy to use. They are not the whole SEO story, but they are a practical signal because they measure what real visitors experience: loading speed, responsiveness, and visual stability.&lt;/p&gt;

&lt;p&gt;As of June 29, 2026, the three Core Web Vitals that matter most are Largest Contentful Paint, Interaction to Next Paint, and Cumulative Layout Shift. Google recommends checking those metrics at the 75th percentile of page loads, segmented across mobile and desktop visits (Google Search Central, n.d.; Walton, 2024).&lt;/p&gt;

&lt;p&gt;For small businesses, this is not just a technical scorecard. A slow homepage can waste ad spend. A sticky navigation menu can frustrate mobile visitors. A jumpy contact form can cost leads. A page that loads poorly can also weaken the clarity signals that search engines, answer engines, and AI crawlers use to understand and cite your site.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Aim for LCP at 2.5 seconds or faster, INP at 200 milliseconds or faster, and CLS at 0.1 or lower. Then test the actual lead path, not only the homepage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Core Web Vitals Measure
&lt;/h2&gt;

&lt;p&gt;Core Web Vitals are a subset of Google's broader Web Vitals program. They focus on three user experience questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How quickly does the main content load?&lt;/li&gt;
&lt;li&gt;How quickly does the page respond after someone interacts?&lt;/li&gt;
&lt;li&gt;Does the layout stay stable while the page loads?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Largest Contentful Paint, or LCP, measures loading performance. A good LCP is 2.5 seconds or faster. Interaction to Next Paint, or INP, measures responsiveness after user input. A good INP is 200 milliseconds or faster. Cumulative Layout Shift, or CLS, measures unexpected visual movement. A good CLS is 0.1 or lower (Walton, 2024).&lt;/p&gt;

&lt;p&gt;Those numbers matter because they turn vague complaints into specific action. "The site feels slow" becomes "the hero image is pushing LCP past 4 seconds on mobile." "The form feels laggy" becomes "the first tap is waiting on heavy JavaScript." "The page jumps" becomes "images and embedded widgets do not reserve space before loading."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1504384308090-c894fdcc538d%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1504384308090-c894fdcc538d%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="People working on laptops in a modern office during a website performance review" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Core Web Vitals are useful because they connect technical decisions to visible customer experience: faster pages, steadier layouts, and smoother interactions.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for SEO, AEO, and GEO
&lt;/h2&gt;

&lt;p&gt;Google's page experience guidance says Core Web Vitals are part of evaluating page experience, alongside factors such as mobile usability, HTTPS, and avoiding intrusive interstitials. Google also makes clear that helpful content remains central, but a good page experience can help content perform better when pages are otherwise similar (Google Search Central, n.d.).&lt;/p&gt;

&lt;p&gt;That is the SEO layer. The answer engine optimization and generative engine optimization layers are just as important.&lt;/p&gt;

&lt;p&gt;Answer engines need clean, readable pages that directly answer questions. Generative AI systems need content that is crawlable, structured, accurate, and easy to parse. Google's guidance for AI features says site owners should continue following search fundamentals, make important content available in text, keep structured data aligned with visible content, and support content with useful images or video where appropriate (Google Search Central, n.d.).&lt;/p&gt;

&lt;p&gt;Core Web Vitals do not guarantee AI citations. They do make your content easier to access and trust. A fast, stable, crawlable page with clear headings, direct answers, and real sources is more citation-friendly than a slow page buried behind layout shifts and heavy scripts.&lt;/p&gt;

&lt;p&gt;For the broader search strategy, pair this checklist with the &lt;a href="https://dev.to/blog/google-search-console-guide"&gt;Google Search Console guide&lt;/a&gt;, the &lt;a href="https://dev.to/blog/answer-engine-optimization-2026"&gt;answer engine optimization guide&lt;/a&gt;, and the &lt;a href="https://dev.to/blog/generative-engine-optimization-guide"&gt;generative engine optimization guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2026 Core Web Vitals Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist when reviewing a small business website, especially before redesigning, buying ads, or publishing a new service page.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Test Real Field Data First
&lt;/h3&gt;

&lt;p&gt;Start with field data, not lab data. Field data reflects real users, devices, networks, and pages. Google's PageSpeed Insights reports field data from the Chrome User Experience Report when enough data is available, plus lab diagnostics from Lighthouse (Google PageSpeed Insights Team, n.d.).&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Homepage.&lt;/li&gt;
&lt;li&gt;Primary service pages.&lt;/li&gt;
&lt;li&gt;Contact page.&lt;/li&gt;
&lt;li&gt;Blog posts that bring organic traffic.&lt;/li&gt;
&lt;li&gt;Landing pages used for ads.&lt;/li&gt;
&lt;li&gt;Product or booking pages if the site has them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The homepage may pass while a money page fails. Do not stop after one URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fix LCP by Prioritizing the Main Content
&lt;/h3&gt;

&lt;p&gt;LCP usually points to the largest visible element in the first viewport. On small business websites, that is often a hero image, heading block, background image, or large service-card section.&lt;/p&gt;

&lt;p&gt;Common LCP fixes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compress and resize hero images.&lt;/li&gt;
&lt;li&gt;Use modern image formats such as WebP or AVIF when possible.&lt;/li&gt;
&lt;li&gt;Avoid loading huge desktop images on mobile.&lt;/li&gt;
&lt;li&gt;Preload the most important above-the-fold image when appropriate.&lt;/li&gt;
&lt;li&gt;Reduce slow server response time.&lt;/li&gt;
&lt;li&gt;Remove render-blocking scripts and styles where practical.&lt;/li&gt;
&lt;li&gt;Keep the first viewport focused, not overloaded with sliders, videos, and popups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many local business sites, the biggest win is simple: use one strong hero image, size it correctly, and avoid making the browser download five decorative assets before the visitor can read the offer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Fix INP by Reducing JavaScript Pressure
&lt;/h3&gt;

&lt;p&gt;INP replaced First Input Delay as a Core Web Vital because it measures responsiveness across the full page visit, not only the first interaction. web.dev explains that INP observes interactions such as clicks, taps, and keyboard input, then reports a high-percentile interaction latency for the page (Wagner &amp;amp; Pollard, 2025).&lt;/p&gt;

&lt;p&gt;Poor INP often comes from too much JavaScript competing for the main thread. That can happen when a site loads heavy tracking tags, chat widgets, animation libraries, booking embeds, cookie banners, or large client-side frameworks on pages that do not need them.&lt;/p&gt;

&lt;p&gt;Improve INP by asking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this script help the visitor complete the task?&lt;/li&gt;
&lt;li&gt;Does it need to load on every page?&lt;/li&gt;
&lt;li&gt;Can it load after the main content?&lt;/li&gt;
&lt;li&gt;Can this interaction be simpler?&lt;/li&gt;
&lt;li&gt;Can server-rendered HTML replace client-side rendering?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This matters for conversions. A visitor who taps "Request a Quote" should not wait because the browser is busy running a carousel script, three trackers, and an unused animation bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Fix CLS by Reserving Space
&lt;/h3&gt;

&lt;p&gt;CLS is about unexpected movement. It usually shows up when images, ads, embeds, fonts, banners, or late-loading content shift the page after the visitor has started reading or tapping.&lt;/p&gt;

&lt;p&gt;Common CLS fixes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set width and height for images and videos.&lt;/li&gt;
&lt;li&gt;Reserve space for review widgets, maps, forms, and embedded calendars.&lt;/li&gt;
&lt;li&gt;Avoid injecting banners above existing content after load.&lt;/li&gt;
&lt;li&gt;Use font loading strategies that prevent dramatic text reflow.&lt;/li&gt;
&lt;li&gt;Keep sticky headers and mobile menus predictable.&lt;/li&gt;
&lt;li&gt;Test the page on real mobile widths, not only a desktop browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CLS is especially important on lead forms. If the submit button moves while someone is trying to tap it, that is not a minor design issue. It is a conversion problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1517245386807-bb43f82c33c4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1517245386807-bb43f82c33c4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Website planning session with a laptop, notebook, and mobile device" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Performance work should include the full customer journey: landing page, service details, contact form, confirmation page, and follow-up tracking.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Audit Third-Party Tools Like Business Costs
&lt;/h3&gt;

&lt;p&gt;Small business sites often collect third-party tools over time: analytics, heatmaps, chat widgets, booking tools, review embeds, social feeds, CRM forms, ad pixels, and cookie consent scripts.&lt;/p&gt;

&lt;p&gt;Some are worth it. Some are silently slowing down the site.&lt;/p&gt;

&lt;p&gt;Review each tool with four questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does it support revenue, measurement, compliance, or customer service?&lt;/li&gt;
&lt;li&gt;Is it still used by the business?&lt;/li&gt;
&lt;li&gt;Does it need to load on every page?&lt;/li&gt;
&lt;li&gt;Is there a lighter way to achieve the same result?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Performance best practice is not "remove every script." It is "make every script justify its place."&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Keep Mobile as the Default Test Case
&lt;/h3&gt;

&lt;p&gt;Most small business searches start in impatient moments: someone needs a contractor, restaurant, consultant, repair service, clinic, or local expert. They are often on a phone, using a cellular connection, and comparing options quickly.&lt;/p&gt;

&lt;p&gt;That means mobile performance deserves priority.&lt;/p&gt;

&lt;p&gt;Check whether:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first viewport explains what the business does.&lt;/li&gt;
&lt;li&gt;The main call to action is easy to tap.&lt;/li&gt;
&lt;li&gt;The phone number or contact path is visible.&lt;/li&gt;
&lt;li&gt;Text is readable without zooming.&lt;/li&gt;
&lt;li&gt;Menus respond quickly.&lt;/li&gt;
&lt;li&gt;Forms are short and stable.&lt;/li&gt;
&lt;li&gt;Images are sharp but not oversized.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good mobile performance supports SEO, but it also supports the basic sales path. People do not wait patiently for a slow site when competitors are one tap away.&lt;/p&gt;

&lt;h2&gt;
  
  
  AEO and GEO Formatting Tips for Performance Pages
&lt;/h2&gt;

&lt;p&gt;Technical performance content can become too vague for AI systems to summarize well. Structure matters.&lt;/p&gt;

&lt;p&gt;For service pages and blog posts, use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Direct answers near the top of the page.&lt;/li&gt;
&lt;li&gt;Clear H2 and H3 headings.&lt;/li&gt;
&lt;li&gt;Short definitions for LCP, INP, and CLS.&lt;/li&gt;
&lt;li&gt;Specific thresholds and dates.&lt;/li&gt;
&lt;li&gt;Step-by-step checklists.&lt;/li&gt;
&lt;li&gt;Internal links to related SEO and web design resources.&lt;/li&gt;
&lt;li&gt;APA-style references for factual claims.&lt;/li&gt;
&lt;li&gt;Descriptive image alt text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That format helps human readers skim, helps search engines classify the page, and helps AI systems extract accurate answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Core Web Vitals for Small Businesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do Core Web Vitals directly affect Google rankings?
&lt;/h3&gt;

&lt;p&gt;Core Web Vitals are part of Google's page experience signals. They are not a substitute for helpful content, relevance, authority, or local trust, but they can matter when users and search systems compare similar pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  What score should a small business website aim for?
&lt;/h3&gt;

&lt;p&gt;Aim for LCP at 2.5 seconds or faster, INP at 200 milliseconds or faster, and CLS at 0.1 or lower at the 75th percentile of page loads. Check both mobile and desktop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is PageSpeed Insights enough?
&lt;/h3&gt;

&lt;p&gt;PageSpeed Insights is a strong starting point, especially when it has field data. For a fuller picture, also check Search Console's Core Web Vitals report, Lighthouse diagnostics, analytics behavior, and real lead-flow testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I redesign my website if Core Web Vitals are poor?
&lt;/h3&gt;

&lt;p&gt;Not always. Some sites need targeted fixes: better images, fewer scripts, cleaner hosting, or reserved layout space. A full redesign makes sense when the site is structurally slow, hard to maintain, or failing the customer journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  How often should Core Web Vitals be checked?
&lt;/h3&gt;

&lt;p&gt;Check monthly, after major content or design changes, and before spending heavily on ads. Also check after adding third-party scripts such as chat, booking, reviews, analytics, or social embeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Core Web Vitals are not vanity metrics. They are a practical way to measure whether your website is fast enough, responsive enough, and stable enough for real customers.&lt;/p&gt;

&lt;p&gt;For small businesses, the best approach is focused: test the pages that make money, fix the biggest blockers first, keep mobile users in mind, and remove scripts or design choices that do not support the customer journey.&lt;/p&gt;

&lt;p&gt;Strong SEO, AEO, and GEO all start with the same foundation: helpful content on a website that people and crawlers can access without friction. If your site is slow, jumpy, or frustrating on mobile, a Core Web Vitals audit is one of the highest-value technical reviews you can run this year.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Google PageSpeed Insights Team. (n.d.). &lt;em&gt;About PageSpeed Insights&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/speed/docs/insights/v5/about" rel="noopener noreferrer"&gt;https://developers.google.com/speed/docs/insights/v5/about&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.). &lt;em&gt;Understanding page experience in Google Search results&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/appearance/page-experience" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/page-experience&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.). &lt;em&gt;AI features and your website&lt;/em&gt;. Google for Developers. &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/ai-features&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wagner, J., &amp;amp; Pollard, B. (2025, September 2). &lt;em&gt;Interaction to Next Paint (INP)&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/articles/inp" rel="noopener noreferrer"&gt;https://web.dev/articles/inp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Walton, P. (2024, September 17). &lt;em&gt;Web Vitals&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/articles/vitals" rel="noopener noreferrer"&gt;https://web.dev/articles/vitals&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>performance</category>
      <category>webdesign</category>
    </item>
    <item>
      <title>Next.js May 2026 Security Release: Small Business Takeaways</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:26:14 +0000</pubDate>
      <link>https://dev.to/rverwey/nextjs-may-2026-security-release-small-business-takeaways-1ge1</link>
      <guid>https://dev.to/rverwey/nextjs-may-2026-security-release-small-business-takeaways-1ge1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/nextjs-may-2026-security-release-small-business" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On May 7, 2026, Vercel published a coordinated Next.js security release covering 13 advisories across middleware and proxy bypass, denial of service, server-side request forgery, cache poisoning, and cross-site scripting. One of the issues came from React Server Components and is tracked as CVE-2026-23870 (Lai, 2026; National Vulnerability Database, 2026).&lt;/p&gt;

&lt;p&gt;For small businesses, the lesson is bigger than one framework. A website is not finished when it launches. If it runs on modern JavaScript, accepts form submissions, protects logged-in areas, uses middleware for access control, or depends on image optimization and server rendering, it needs an active patch process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; If your website runs Next.js 13.x or 14.x, Vercel says all versions are affected by the May 2026 advisory set and should move to Next.js 15.5.18 or 16.2.6. If you are on 15.x or 16.x, upgrade to the patched release in that line immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Happened in the May 2026 Next.js Release?
&lt;/h2&gt;

&lt;p&gt;The May 2026 release was not one bug. It was a cluster of issues across several parts of the framework. Vercel's advisory grouped the impact into five categories: middleware and proxy bypass, denial of service, server-side request forgery, cache poisoning, and cross-site scripting (Lai, 2026).&lt;/p&gt;

&lt;p&gt;That matters because those categories touch business risk in different ways.&lt;/p&gt;

&lt;p&gt;Middleware and proxy bypass issues can matter when a site uses middleware for authorization, routing, localization, or gated content. Denial-of-service issues can make a site unavailable or increase hosting costs. Server-side request forgery can let an attacker abuse server-side network behavior. Cache poisoning can cause users or crawlers to receive incorrect content. Cross-site scripting can expose visitors to attacker-controlled scripts.&lt;/p&gt;

&lt;p&gt;The React Server Components issue, CVE-2026-23870, was classified as a high-severity denial-of-service vulnerability. The React advisory says specially crafted HTTP requests to server function endpoints could lead to out-of-memory exceptions or excessive CPU usage in affected &lt;code&gt;react-server-dom-*&lt;/code&gt; packages (React Team, 2026). NVD lists the CNA score as 7.5 High with a network attack vector, low attack complexity, no privileges required, no user interaction required, and high availability impact (National Vulnerability Database, 2026).&lt;/p&gt;

&lt;p&gt;In plain English: an affected server-rendered React application may be easier to knock offline than a business owner expects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1544197150-b99a580bb7a8%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1544197150-b99a580bb7a8%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Server racks with network cables in a data center" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Framework security is business continuity. A vulnerable website can become unavailable, leak logic, or route traffic incorrectly even when the design looks fine.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Small Business Owners Should Care
&lt;/h2&gt;

&lt;p&gt;Most business owners do not care which framework version their website uses. They care whether the site brings in leads, loads quickly, ranks in search, and stays online.&lt;/p&gt;

&lt;p&gt;That is reasonable, but it creates a blind spot. Modern websites are software systems. The visible page may look like a brochure, but behind that page there may be dependencies, build tools, server functions, image processors, route handlers, middleware, analytics scripts, and hosting adapters. Any of those layers can require security updates.&lt;/p&gt;

&lt;p&gt;This is especially important for small businesses because the same website often handles several jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It explains services.&lt;/li&gt;
&lt;li&gt;It captures leads.&lt;/li&gt;
&lt;li&gt;It validates trust through reviews and proof.&lt;/li&gt;
&lt;li&gt;It supports local SEO.&lt;/li&gt;
&lt;li&gt;It feeds content to Google, AI search tools, and answer engines.&lt;/li&gt;
&lt;li&gt;It may connect to email, booking, CRM, analytics, or payment systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the site goes offline, loads malicious scripts, leaks server behavior, or blocks the wrong users, the business impact is not theoretical. Leads stop. Ads waste money. Search crawlers may see bad responses. Customers may lose trust.&lt;/p&gt;

&lt;p&gt;That is why security patching belongs in the same conversation as SEO, AEO, and GEO. Search visibility depends on a site being available, crawlable, trustworthy, and technically stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Versions Needed Attention?
&lt;/h2&gt;

&lt;p&gt;Vercel's May 2026 advisory lists the affected and patched versions clearly. Next.js 13.x and 14.x are listed as affected across all versions and should upgrade to Next.js 15.5.18 or 16.2.6. Next.js 15.x versions through 15.5.17 should upgrade to 15.5.18. Next.js 16.x versions through 16.2.5 should upgrade to 16.2.6 (Lai, 2026).&lt;/p&gt;

&lt;p&gt;For React Server Components packages, the fixed versions are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;react-server-dom-*&lt;/code&gt; 19.0.6 for the 19.0.x line.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-server-dom-*&lt;/code&gt; 19.1.7 for the 19.1.x line.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-server-dom-*&lt;/code&gt; 19.2.6 for the 19.2.x line.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;React's advisory names &lt;code&gt;react-server-dom-webpack&lt;/code&gt;, &lt;code&gt;react-server-dom-parcel&lt;/code&gt;, and &lt;code&gt;react-server-dom-turbopack&lt;/code&gt; as affected packages and says fixes were backported to 19.0.6, 19.1.7, and 19.2.6 (React Team, 2026).&lt;/p&gt;

&lt;p&gt;If you are a business owner, you do not need to memorize those numbers. You need your developer, agency, or hosting partner to answer three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What version of Next.js is my production website actually running?&lt;/li&gt;
&lt;li&gt;Does the site use App Router, middleware, proxy, Server Functions, React Server Components, Image Optimization API, CSP nonces, WebSocket upgrades, or custom caching?&lt;/li&gt;
&lt;li&gt;Has the patched version been deployed and verified in production?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If nobody can answer those questions, the risk is not only the May 2026 advisory. The risk is that no one owns maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a WAF Is Helpful, but Not Enough
&lt;/h2&gt;

&lt;p&gt;A web application firewall can reduce risk, but it cannot replace patching. Vercel said patching is the only complete mitigation for the May 2026 release and noted that the advisories cannot be reliably blocked at the WAF layer (Lai, 2026).&lt;/p&gt;

&lt;p&gt;Cloudflare published similar guidance. It said some existing WAF rules applied to the new React Server Components denial-of-service vulnerability, but it also warned that several disclosed vulnerabilities are not possible to block in WAF and that applications should not rely only on WAF mitigations (Cloudflare, 2026).&lt;/p&gt;

&lt;p&gt;That distinction matters for small businesses. A WAF is a control. A framework patch is a fix. You usually want both, but they are not interchangeable.&lt;/p&gt;

&lt;p&gt;Think of it this way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Patching removes the vulnerable code path.&lt;/li&gt;
&lt;li&gt;A WAF may block known request patterns.&lt;/li&gt;
&lt;li&gt;Monitoring helps confirm the patch worked and catches unusual traffic.&lt;/li&gt;
&lt;li&gt;Backups and rollback plans help if the update breaks something.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best maintenance plan uses layers. It does not treat any single layer as magic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1515879218367-8466d910aaa4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1515879218367-8466d910aaa4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Developer reviewing code on a screen in a dark editor" width="1200" height="801"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Security updates should be tested like any production change: confirm versions, deploy cleanly, inspect logs, and verify key business workflows.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Patch Checklist
&lt;/h2&gt;

&lt;p&gt;If your business has a Next.js website, use this checklist to guide a focused maintenance review.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Identify the Production Version
&lt;/h3&gt;

&lt;p&gt;Do not rely only on &lt;code&gt;package.json&lt;/code&gt;. Check the lockfile, deployment logs, and production build output. A version range like &lt;code&gt;^14.0.4&lt;/code&gt; can resolve differently over time depending on the lockfile and install process.&lt;/p&gt;

&lt;p&gt;Your developer should confirm the exact installed &lt;code&gt;next&lt;/code&gt; version and the exact deployed build.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Check Which Features the Site Uses
&lt;/h3&gt;

&lt;p&gt;The May 2026 advisory touches multiple framework surfaces. Ask whether the site uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App Router.&lt;/li&gt;
&lt;li&gt;Pages Router with i18n.&lt;/li&gt;
&lt;li&gt;Middleware or proxy rules.&lt;/li&gt;
&lt;li&gt;Server Functions.&lt;/li&gt;
&lt;li&gt;React Server Components.&lt;/li&gt;
&lt;li&gt;Partial Prerendering or Cache Components.&lt;/li&gt;
&lt;li&gt;Image Optimization API.&lt;/li&gt;
&lt;li&gt;WebSocket upgrade handling.&lt;/li&gt;
&lt;li&gt;CSP nonces.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;beforeInteractive&lt;/code&gt; scripts that handle untrusted input.&lt;/li&gt;
&lt;li&gt;Custom caching in front of React Server Component responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feature usage changes priority. A static marketing site and a logged-in customer portal may both run Next.js, but their exposure is not the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Upgrade in a Test Branch First
&lt;/h3&gt;

&lt;p&gt;For many sites, moving from Next.js 14.x to 15.5.18 or 16.2.6 is more than a patch bump. It can include framework behavior changes that need testing.&lt;/p&gt;

&lt;p&gt;Test these before production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Homepage and core service pages.&lt;/li&gt;
&lt;li&gt;Contact forms and quote request forms.&lt;/li&gt;
&lt;li&gt;Blog routes and RSS feed.&lt;/li&gt;
&lt;li&gt;Sitemap and robots.txt.&lt;/li&gt;
&lt;li&gt;Image rendering.&lt;/li&gt;
&lt;li&gt;Redirects.&lt;/li&gt;
&lt;li&gt;Middleware behavior.&lt;/li&gt;
&lt;li&gt;Analytics and conversion tracking.&lt;/li&gt;
&lt;li&gt;Search metadata and canonical URLs.&lt;/li&gt;
&lt;li&gt;Lighthouse or PageSpeed basics after deploy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Security updates should not quietly break the lead path.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Redeploy and Verify
&lt;/h3&gt;

&lt;p&gt;Netlify's advisory for the same release recommends upgrading &lt;code&gt;next&lt;/code&gt; to 15.5.18 or 16.2.6 and redeploying, noting that this brings in the patched React Server Components dependency for Next.js projects (Netlify, 2026).&lt;/p&gt;

&lt;p&gt;After deployment, verify the production site, not only the build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the live version.&lt;/li&gt;
&lt;li&gt;Run smoke tests for forms, navigation, and gated paths.&lt;/li&gt;
&lt;li&gt;Inspect server logs for errors.&lt;/li&gt;
&lt;li&gt;Check uptime monitoring.&lt;/li&gt;
&lt;li&gt;Review Web Vitals or real-user monitoring if available.&lt;/li&gt;
&lt;li&gt;Watch Search Console for crawl errors over the next few days.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Document the Maintenance Decision
&lt;/h3&gt;

&lt;p&gt;Every website should have a short maintenance record. For this advisory, the record should include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Current production version before patching.&lt;/li&gt;
&lt;li&gt;Patched target version.&lt;/li&gt;
&lt;li&gt;Date deployed.&lt;/li&gt;
&lt;li&gt;Who approved the change.&lt;/li&gt;
&lt;li&gt;What tests were run.&lt;/li&gt;
&lt;li&gt;Any known follow-up work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This does not need to be complex. It just needs to exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SEO and AI Search Angle
&lt;/h2&gt;

&lt;p&gt;Security releases may look unrelated to SEO, but they affect the technical foundation search systems depend on.&lt;/p&gt;

&lt;p&gt;Search engines and AI answer engines need stable pages. If a framework issue causes downtime, inconsistent caching, bad redirects, broken image responses, or incorrect content delivery, the problem can spill into crawlability and trust.&lt;/p&gt;

&lt;p&gt;For AEO and GEO, the same logic applies. AI tools are more likely to cite sources that are accessible, clear, stable, and technically sound. A page that is frequently unavailable or inconsistent is a weaker source, even if the copy is strong.&lt;/p&gt;

&lt;p&gt;That is why "maintained website" should be part of your SEO vocabulary. A technically current site is not just safer. It is easier for customers, search engines, and AI systems to use confidently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Ask Your Web Partner This Week
&lt;/h2&gt;

&lt;p&gt;If you work with a developer or agency, send these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What framework and version is our production website running right now?&lt;/li&gt;
&lt;li&gt;Are we affected by the May 2026 Next.js and React security advisories?&lt;/li&gt;
&lt;li&gt;If yes, what version should we upgrade to?&lt;/li&gt;
&lt;li&gt;What business workflows need testing before deploy?&lt;/li&gt;
&lt;li&gt;Do we rely on middleware or proxy logic for authorization?&lt;/li&gt;
&lt;li&gt;Do we have a WAF, and what does it cover?&lt;/li&gt;
&lt;li&gt;Do we have uptime monitoring and error logging?&lt;/li&gt;
&lt;li&gt;How often are dependency updates reviewed?&lt;/li&gt;
&lt;li&gt;Who is responsible for emergency security patches?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good vendors will welcome those questions. Vague answers are a warning sign.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: Next.js Security for Small Business Websites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does every Next.js website need to upgrade because of the May 2026 release?
&lt;/h3&gt;

&lt;p&gt;Every affected site should be reviewed immediately. Vercel lists all Next.js 13.x and 14.x versions as affected and recommends upgrading to 15.5.18 or 16.2.6. For 15.x and 16.x sites, upgrade to the patched release in that line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a static marketing website affected the same way as a web app?
&lt;/h3&gt;

&lt;p&gt;Not always. Feature usage matters. A mostly static site may have less exposure than a portal with middleware, server functions, and custom caching. But version review is still necessary because framework behavior and deployment adapters can affect the risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Cloudflare, Vercel, or another WAF fully protect the site?
&lt;/h3&gt;

&lt;p&gt;No. WAF rules can reduce risk, and Cloudflare said some rules applied to the React denial-of-service issue. But both Vercel and Cloudflare made clear that patching is still required for complete protection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will upgrading Next.js hurt SEO?
&lt;/h3&gt;

&lt;p&gt;It should not if the upgrade is tested properly. The risk comes from untested changes that break metadata, redirects, sitemap generation, image loading, internal links, or page rendering. A disciplined upgrade should preserve or improve technical SEO.&lt;/p&gt;

&lt;h3&gt;
  
  
  How often should a small business review website dependencies?
&lt;/h3&gt;

&lt;p&gt;At minimum, review dependencies monthly and immediately when a high-severity advisory affects your stack. Sites that handle logins, payments, sensitive forms, or high ad spend need faster monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;The May 2026 Next.js security release is a reminder that website maintenance is not optional. A modern site can be fast, beautiful, and well optimized, but still carry business risk if nobody patches the framework underneath it.&lt;/p&gt;

&lt;p&gt;For small businesses, the practical move is simple: identify the production version, understand which framework features are in use, patch to the recommended release, test the customer journey, and document who owns security maintenance going forward.&lt;/p&gt;

&lt;p&gt;Echo Effect builds websites with SEO, AEO, GEO, and maintenance in mind. If your current site is on an older framework, has no clear patch owner, or has not had a technical review this year, schedule a website audit before a security update becomes an emergency.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Cloudflare. (2026, May 7). &lt;em&gt;WAF and framework adapter mitigations for React and Next.js vulnerabilities&lt;/em&gt;. &lt;a href="https://developers.cloudflare.com/changelog/post/2026-05-06-react-nextjs-vulnerabilities/" rel="noopener noreferrer"&gt;https://developers.cloudflare.com/changelog/post/2026-05-06-react-nextjs-vulnerabilities/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lai, J. (2026, May 7). &lt;em&gt;Next.js May 2026 security release&lt;/em&gt;. Vercel. &lt;a href="https://vercel.com/changelog/next-js-may-2026-security-release" rel="noopener noreferrer"&gt;https://vercel.com/changelog/next-js-may-2026-security-release&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;National Vulnerability Database. (2026, May 6). &lt;em&gt;CVE-2026-23870 detail&lt;/em&gt;. National Institute of Standards and Technology. &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-23870" rel="noopener noreferrer"&gt;https://nvd.nist.gov/vuln/detail/CVE-2026-23870&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Netlify. (2026, May 8). &lt;em&gt;Security update: Multiple vulnerabilities in Next.js and React&lt;/em&gt;. &lt;a href="https://www.netlify.com/changelog/2026-05-08-react-nextjs-security-vulnerabilities/" rel="noopener noreferrer"&gt;https://www.netlify.com/changelog/2026-05-08-react-nextjs-security-vulnerabilities/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Team. (2026, May 6). &lt;em&gt;Denial of service vulnerability in React Server Components&lt;/em&gt;. GitHub Security Advisory. &lt;a href="https://github.com/facebook/react/security/advisories/GHSA-rv78-f8rc-xrxh" rel="noopener noreferrer"&gt;https://github.com/facebook/react/security/advisories/GHSA-rv78-f8rc-xrxh&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>security</category>
      <category>javascript</category>
    </item>
    <item>
      <title>AI Agents Are Changing Search: Small Business Prep</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:25:40 +0000</pubDate>
      <link>https://dev.to/rverwey/ai-agents-are-changing-search-small-business-prep-51ij</link>
      <guid>https://dev.to/rverwey/ai-agents-are-changing-search-small-business-prep-51ij</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/ai-agents-search-small-business-websites-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As of June 15, 2026, AI search is no longer only about getting summarized in an answer box. Google is moving AI Mode toward agents that can monitor information, compare options, help with bookings, and even call some businesses on behalf of users in select categories. OpenAI is also expanding ChatGPT from answer generation into richer product discovery, comparison, and decision support (OpenAI, 2026; Reid, 2026).&lt;/p&gt;

&lt;p&gt;For small businesses, this changes the practical question. It is not just "Can Google crawl my website?" It is also "Can an AI assistant understand my business, compare my services, trust my proof, and guide a customer to the right next action?"&lt;/p&gt;

&lt;p&gt;That does not mean you need to rebuild your website around AI hype. The best AI-ready work is still grounded in fundamentals: clear content, strong technical SEO, structured data that matches visible content, accessible interfaces, fast pages, accurate business details, and useful answers. The difference is that these fundamentals now serve three audiences at once: people, search engines, and AI agents.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; AI agents make clarity more valuable. If your website clearly explains who you serve, what you offer, how customers take action, and why they should trust you, you are in a better position for SEO, AEO, and GEO.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Changed in 2026?
&lt;/h2&gt;

&lt;p&gt;Google's May 19, 2026 Search announcement described AI Mode as a larger shift toward "Search agents." Google said AI Mode had surpassed one billion monthly users one year after launch, and it outlined agent features that can monitor information, support local bookings, and help users complete tasks with direct links to providers (Reid, 2026).&lt;/p&gt;

&lt;p&gt;Google Search Central also published guidance for generative AI features in Search. The message is important because it cuts through a lot of bad advice: SEO still matters, AI Overviews and AI Mode are rooted in Google's core Search systems, and there are no special files or magic markup required to appear in those AI features (Google Search Central, n.d.-a, n.d.-b).&lt;/p&gt;

&lt;p&gt;OpenAI is moving in a similar direction from the user side. ChatGPT search can show cited sources, and OpenAI's product discovery updates describe a more visual shopping experience where users can compare products by price, reviews, features, and constraints without jumping between tabs (OpenAI Help Center, n.d.; OpenAI, 2026).&lt;/p&gt;

&lt;p&gt;The pattern is clear: customers are not only searching for pages. They are asking assistants to research, compare, summarize, and act.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1552664730-d307ca884978%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1552664730-d307ca884978%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Marketing team reviewing a digital strategy board in a meeting" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI search rewards websites that make the business easy to understand, compare, and trust.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How AI Agents Read a Website
&lt;/h2&gt;

&lt;p&gt;Traditional search crawlers mostly care whether they can discover, crawl, render, index, and understand your pages. AI agents may do more. They can inspect the page visually, read the HTML, use the accessibility tree, click links, fill forms, compare options, and report back to the user.&lt;/p&gt;

&lt;p&gt;That makes your website interface part of your search strategy.&lt;/p&gt;

&lt;p&gt;The web.dev guidance on agent-friendly websites explains that agents may use screenshots, raw HTML, and the accessibility tree to understand a page. It recommends stable layouts, semantic buttons and links, visible interface changes after actions, labels connected to form inputs, and interactive elements that are large enough to recognize (Kulikowski &amp;amp; More, 2026).&lt;/p&gt;

&lt;p&gt;Those recommendations are not strange new AI tactics. They are good web design and accessibility practices. A real customer also benefits when a form label is clear, a button looks clickable, the layout does not jump, and the next step is obvious.&lt;/p&gt;

&lt;p&gt;For Echo Effect clients, this is the useful framing: build for humans first, but remove the ambiguity that makes machines guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Small Businesses
&lt;/h2&gt;

&lt;p&gt;Small business websites often lose AI visibility for the same reasons they lose human trust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The homepage says "solutions" but never states the actual services.&lt;/li&gt;
&lt;li&gt;The service area is vague or missing.&lt;/li&gt;
&lt;li&gt;Pricing factors are hidden behind a contact form.&lt;/li&gt;
&lt;li&gt;Reviews live on third-party profiles but not on matching service pages.&lt;/li&gt;
&lt;li&gt;Forms have unclear labels, weak error messages, or no visible submission state.&lt;/li&gt;
&lt;li&gt;Service pages are thin, generic, or duplicated across locations.&lt;/li&gt;
&lt;li&gt;Structured data exists, but it does not match what users can see.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These issues were already bad for SEO. AI agents make them more expensive because assistants need clean evidence to summarize a business confidently.&lt;/p&gt;

&lt;p&gt;If an agent is asked, "Find a Florida web designer for a small business that needs SEO and social media help," it needs to connect several facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the business name,&lt;/li&gt;
&lt;li&gt;the service category,&lt;/li&gt;
&lt;li&gt;the service area,&lt;/li&gt;
&lt;li&gt;the customer type,&lt;/li&gt;
&lt;li&gt;the proof of expertise,&lt;/li&gt;
&lt;li&gt;the next action,&lt;/li&gt;
&lt;li&gt;and the source pages that support those claims.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those facts are scattered, vague, or inconsistent, the agent has less reason to include you.&lt;/p&gt;

&lt;h2&gt;
  
  
  SEO, AEO, and GEO Are Now One Workflow
&lt;/h2&gt;

&lt;p&gt;The labels can get messy, but the work overlaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEO&lt;/strong&gt; helps your pages get crawled, indexed, ranked, and clicked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AEO&lt;/strong&gt; helps your content become the direct answer to a customer question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GEO&lt;/strong&gt; helps your business become a source that generative engines can summarize, cite, and recommend.&lt;/p&gt;

&lt;p&gt;AI agents add a fourth layer: &lt;strong&gt;AX&lt;/strong&gt;, or agent experience. That means your website is not only findable and answer-ready. It is also usable by systems that may need to inspect content, navigate the page, and complete a task for the user.&lt;/p&gt;

&lt;p&gt;You do not need four separate strategies. You need one disciplined website foundation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crawlable pages.&lt;/li&gt;
&lt;li&gt;Useful content.&lt;/li&gt;
&lt;li&gt;Specific answers.&lt;/li&gt;
&lt;li&gt;Consistent entity signals.&lt;/li&gt;
&lt;li&gt;Honest structured data.&lt;/li&gt;
&lt;li&gt;Accessible forms and buttons.&lt;/li&gt;
&lt;li&gt;Clear conversion paths.&lt;/li&gt;
&lt;li&gt;Measurable business outcomes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the practical version of AI readiness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Your Business Facts Machine-Clear
&lt;/h2&gt;

&lt;p&gt;Start with the facts an assistant would need to recommend you.&lt;/p&gt;

&lt;p&gt;Your website should clearly state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your business name,&lt;/li&gt;
&lt;li&gt;who owns or leads the business,&lt;/li&gt;
&lt;li&gt;where you are based,&lt;/li&gt;
&lt;li&gt;where you serve customers,&lt;/li&gt;
&lt;li&gt;what services you offer,&lt;/li&gt;
&lt;li&gt;who those services are for,&lt;/li&gt;
&lt;li&gt;what makes your approach credible,&lt;/li&gt;
&lt;li&gt;how customers can contact you,&lt;/li&gt;
&lt;li&gt;and what happens after they reach out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Echo Effect, those facts include "veteran-owned digital marketing agency," "Florida-based," "serving all 50 U.S. states," "web design," "social media consulting," "small businesses," and "Ryan VerWey."&lt;/p&gt;

&lt;p&gt;Do not hide those facts only in a footer or About page. Put them where customers make decisions: homepage, service pages, contact page, author bios, blog content, schema, Google Business Profile, and public social profiles.&lt;/p&gt;

&lt;p&gt;This is not keyword stuffing. It is entity clarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Content Around Real Customer Questions
&lt;/h2&gt;

&lt;p&gt;Google's generative AI search guidance emphasizes useful, non-commodity content written for people, with a unique point of view and clear organization (Google Search Central, n.d.-a). That matters because AI systems do not need another generic article that repeats the same advice as everyone else.&lt;/p&gt;

&lt;p&gt;For small businesses, the best topics usually come from sales conversations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much does a small business website cost?&lt;/li&gt;
&lt;li&gt;What should I fix before running ads?&lt;/li&gt;
&lt;li&gt;Do I need SEO if I already get referrals?&lt;/li&gt;
&lt;li&gt;Why is my Google Business Profile not getting calls?&lt;/li&gt;
&lt;li&gt;Should I use WordPress, Wix, Squarespace, or Next.js?&lt;/li&gt;
&lt;li&gt;What does a social media consultant actually do?&lt;/li&gt;
&lt;li&gt;How long does a website redesign take?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Answer those questions directly. Put the answer early. Then explain the nuance.&lt;/p&gt;

&lt;p&gt;This is where AEO and GEO overlap. A direct answer helps a customer. A well-structured answer helps search engines. A sourced answer helps generative systems decide whether your page is reliable enough to cite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Structured Data as a Label, Not a Trick
&lt;/h2&gt;

&lt;p&gt;Structured data helps Google understand the content and entities on a page. Google recommends JSON-LD where possible, and it warns against adding structured data for information that is not visible to users (Google Search Central, n.d.-c).&lt;/p&gt;

&lt;p&gt;For small businesses, the highest-value schema usually includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organization or LocalBusiness,&lt;/li&gt;
&lt;li&gt;Service,&lt;/li&gt;
&lt;li&gt;FAQPage when the FAQs are visible,&lt;/li&gt;
&lt;li&gt;BlogPosting for articles,&lt;/li&gt;
&lt;li&gt;BreadcrumbList,&lt;/li&gt;
&lt;li&gt;Person for authors or founders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not invent claims for schema. If your structured data says you offer a service, the page should visibly explain that service. If your FAQ schema marks up a question, that question and answer should be on the page. If your author schema says a named person wrote the post, the byline should support that.&lt;/p&gt;

&lt;p&gt;Schema is not a secret AI ranking hack. It is a clarity layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1553877522-43269d4ea984%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1553877522-43269d4ea984%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Team analyzing website data and user behavior on a laptop" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI readiness is mostly practical website hygiene: clear content, clean structure, accessible actions, and proof that supports the page.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Forms and Calls to Action Agent-Friendly
&lt;/h2&gt;

&lt;p&gt;If an AI agent can help a customer complete a task, your forms and calls to action need to be easy to interpret.&lt;/p&gt;

&lt;p&gt;Audit your main conversion paths:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use real &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; elements for actions.&lt;/li&gt;
&lt;li&gt;Use real links for navigation.&lt;/li&gt;
&lt;li&gt;Connect every form label to its input.&lt;/li&gt;
&lt;li&gt;Use plain button text like "Schedule a Call" or "Request a Website Review."&lt;/li&gt;
&lt;li&gt;Show clear success, loading, and error states.&lt;/li&gt;
&lt;li&gt;Keep required fields obvious.&lt;/li&gt;
&lt;li&gt;Avoid hover-only menus for critical paths.&lt;/li&gt;
&lt;li&gt;Make phone numbers, email links, and forms visible in predictable places.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is not only for agents. It also helps mobile users, screen reader users, distracted users, and customers who are ready to contact you but do not want to decode a clever interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep AI-Generated Content Under Human Control
&lt;/h2&gt;

&lt;p&gt;AI tools can help with research, outlines, editing, and content structure. They should not replace expertise.&lt;/p&gt;

&lt;p&gt;Google's guidance on AI-generated content warns that using AI or similar tools to generate many pages without added value may violate spam policies. Google also tells site owners to focus on accuracy, quality, relevance, metadata, structured data, and image alt text (Google Search Central, n.d.-d).&lt;/p&gt;

&lt;p&gt;That is a practical standard for small businesses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AI to speed up drafts, not to publish unchecked advice.&lt;/li&gt;
&lt;li&gt;Verify every statistic, source, quote, and link.&lt;/li&gt;
&lt;li&gt;Add real local knowledge, client experience, examples, and judgment.&lt;/li&gt;
&lt;li&gt;Credit a human author who can stand behind the content.&lt;/li&gt;
&lt;li&gt;Update old posts when platform behavior changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI search rewards useful sources. Generic AI content is rarely useful enough to become one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure More Than Clicks
&lt;/h2&gt;

&lt;p&gt;AI search can influence a customer before they click your website. A person might see your business in an AI answer, ask a follow-up question, search your name later, call from a profile, or compare you against another provider.&lt;/p&gt;

&lt;p&gt;That makes measurement harder, but not impossible.&lt;/p&gt;

&lt;p&gt;Track these signals together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Search Console impressions for question-based queries.&lt;/li&gt;
&lt;li&gt;Branded search growth.&lt;/li&gt;
&lt;li&gt;Referral traffic from AI tools when visible.&lt;/li&gt;
&lt;li&gt;Google Business Profile calls, messages, and website clicks.&lt;/li&gt;
&lt;li&gt;Contact form submissions.&lt;/li&gt;
&lt;li&gt;Phone calls.&lt;/li&gt;
&lt;li&gt;Consultation bookings.&lt;/li&gt;
&lt;li&gt;Assisted conversions after educational blog visits.&lt;/li&gt;
&lt;li&gt;Manual citation checks in Google AI Mode, ChatGPT search, and Perplexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google says sites appearing in AI features are included in the overall Search Console Performance report under the Web search type, so do not expect every AI exposure to appear as a separate clean channel (Google Search Central, n.d.-b). Tie the data back to leads and revenue, not only sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Small Business AI Agent Checklist
&lt;/h2&gt;

&lt;p&gt;If you want to prepare your website for AI-assisted discovery this month, start here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rewrite your homepage intro so it clearly says who you serve, what you do, and where you work.&lt;/li&gt;
&lt;li&gt;Add direct FAQ sections to your top service pages.&lt;/li&gt;
&lt;li&gt;Update your Google Business Profile so services, categories, hours, and website links match your site.&lt;/li&gt;
&lt;li&gt;Add internal links from related blog posts to matching service pages.&lt;/li&gt;
&lt;li&gt;Validate BlogPosting, Organization, BreadcrumbList, and FAQ schema where relevant.&lt;/li&gt;
&lt;li&gt;Audit forms for labels, required states, success messages, and mobile usability.&lt;/li&gt;
&lt;li&gt;Replace vague claims with proof: reviews, examples, credentials, process details, and outcomes.&lt;/li&gt;
&lt;li&gt;Add high-quality, relevant images with descriptive alt text.&lt;/li&gt;
&lt;li&gt;Check that important content appears as text, not only in images, videos, or graphics.&lt;/li&gt;
&lt;li&gt;Review Search Console monthly for indexing, impressions, and question-based queries.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this requires chasing hacks. It requires making your business easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: AI Agents and Small Business Websites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do small businesses need a separate AI agent strategy?
&lt;/h3&gt;

&lt;p&gt;Most do not need a separate strategy. They need a stronger website foundation that supports people, search engines, and AI assistants at the same time: clear services, direct answers, crawlable pages, accessible interactions, structured data, and consistent business information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will AI agents replace SEO?
&lt;/h3&gt;

&lt;p&gt;No. Google says foundational SEO best practices still apply to AI Overviews and AI Mode. AI agents raise the importance of SEO because agents need crawlable, trustworthy, well-structured sources to complete research and comparison tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is llms.txt required for Google AI Mode?
&lt;/h3&gt;

&lt;p&gt;No. Google Search Central says special machine-readable files, AI text files, and special AI markup are not required for generative AI search visibility in Google Search (Google Search Central, n.d.-a).&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the fastest improvement a business can make?
&lt;/h3&gt;

&lt;p&gt;Clarify your top service pages. Add direct answers, specific proof, visible contact paths, internal links, and accurate structured data. That single improvement supports SEO, AEO, GEO, and conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;AI agents are changing search from a page-finding experience into a task-completion experience. Customers can ask longer questions, compare providers, continue the conversation, and lean on assistants to narrow the field before they ever contact a business.&lt;/p&gt;

&lt;p&gt;Small businesses do not need to panic. They need to get clearer.&lt;/p&gt;

&lt;p&gt;The websites that win will not be the ones with the most AI buzzwords. They will be the ones that make the business easy to understand, easy to verify, easy to compare, and easy to contact.&lt;/p&gt;

&lt;p&gt;That is good SEO. It is good AEO. It is good GEO. It is also just a better website.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Echo Effect helps small businesses build websites and content systems that work for customers, search engines, and AI discovery tools. If you want to know whether your site is ready for AI-assisted search, schedule a discovery call and we will identify the highest-impact fixes first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Google Search Central. (n.d.-a). &lt;em&gt;Optimizing your website for generative AI features on Google Search&lt;/em&gt;. Google for Developers. Retrieved June 15, 2026, from &lt;a href="https://developers.google.com/search/docs/fundamentals/ai-optimization-guide" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/fundamentals/ai-optimization-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-b). &lt;em&gt;AI features and your website&lt;/em&gt;. Google for Developers. Retrieved June 15, 2026, from &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/ai-features&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-c). &lt;em&gt;Introduction to structured data markup in Google Search&lt;/em&gt;. Google for Developers. Retrieved June 15, 2026, from &lt;a href="https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Search Central. (n.d.-d). &lt;em&gt;Google Search's guidance on generative AI content on your website&lt;/em&gt;. Google for Developers. Retrieved June 15, 2026, from &lt;a href="https://developers.google.com/search/docs/fundamentals/using-gen-ai-content" rel="noopener noreferrer"&gt;https://developers.google.com/search/docs/fundamentals/using-gen-ai-content&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kulikowski, K., &amp;amp; More, O. (2026, April 1). &lt;em&gt;Build agent-friendly websites&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/articles/ai-agent-site-ux" rel="noopener noreferrer"&gt;https://web.dev/articles/ai-agent-site-ux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI. (2026, March 24). &lt;em&gt;Powering product discovery in ChatGPT&lt;/em&gt;. &lt;a href="https://openai.com/index/powering-product-discovery-in-chatgpt/" rel="noopener noreferrer"&gt;https://openai.com/index/powering-product-discovery-in-chatgpt/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI Help Center. (n.d.). &lt;em&gt;ChatGPT search&lt;/em&gt;. Retrieved June 15, 2026, from &lt;a href="https://help.openai.com/en/articles/9237897-chatgpt-search" rel="noopener noreferrer"&gt;https://help.openai.com/en/articles/9237897-chatgpt-search&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reid, E. (2026, May 19). &lt;em&gt;A new era for AI Search&lt;/em&gt;. Google. &lt;a href="https://blog.google/products-and-platforms/products/search/search-io-2026/" rel="noopener noreferrer"&gt;https://blog.google/products-and-platforms/products/search/search-io-2026/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
      <category>marketing</category>
    </item>
    <item>
      <title>React 19 and Next.js 16: What Small Business Websites Should Actually Upgrade in 2026</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:25:35 +0000</pubDate>
      <link>https://dev.to/rverwey/react-19-and-nextjs-16-what-small-business-websites-should-actually-upgrade-in-2026-2mnk</link>
      <guid>https://dev.to/rverwey/react-19-and-nextjs-16-what-small-business-websites-should-actually-upgrade-in-2026-2mnk</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/react-19-nextjs-16-small-business-websites-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As of June 11, 2026, the current framework conversation is no longer just "Should we use React?" It is "Which parts of the modern React and Next.js stack actually improve a business website, and which parts are just noise?" That distinction matters for small businesses because framework upgrades cost time, money, and testing. If an upgrade does not make your site faster, easier to maintain, or better at turning visitors into leads, it is not a good investment.&lt;/p&gt;

&lt;p&gt;The good news is that the recent release cycle has included real improvements that matter to business websites. React 19 stabilized major form and rendering improvements on December 5, 2024, React 19.2 added additional rendering and debugging features on October 1, 2025, and Next.js 16.2 shipped on March 18, 2026 with performance and debugging gains that are directly relevant to production teams (Next.js Team, 2026; React Team, 2024, 2025).&lt;/p&gt;

&lt;p&gt;The bad news is that the same ecosystem also had serious React Server Components security advisories in December 2025 and January 2026, so "modern" does not automatically mean "safe" unless teams keep patched versions deployed (Next.js Team, 2025; React Team, 2025).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; If your small business site depends on lead forms, SEO, speed, and maintainability, the recent React and Next.js releases matter. If your site is brochure-only and already fast, selective upgrades usually beat a full rewrite.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Changed Recently, in Plain English
&lt;/h2&gt;

&lt;p&gt;React 19 introduced a cleaner way to handle forms, pending states, optimistic UI, and async actions. For most business websites, that matters less for flashy product engineering and more for practical interactions like contact forms, quote requests, newsletter signups, and gated downloads. The React team also added &lt;code&gt;useFormStatus&lt;/code&gt;, &lt;code&gt;useOptimistic&lt;/code&gt;, and a more straightforward pattern for form actions, which reduces the amount of custom client-side plumbing developers used to write by hand (React Team, 2024).&lt;/p&gt;

&lt;p&gt;React 19.2 extended that work with &lt;code&gt;useEffectEvent&lt;/code&gt;, ``, partial pre-rendering support in React DOM, and new React Performance Tracks in Chrome DevTools. Those features help developers isolate side-effect logic, pre-render more intelligently, and debug rendering bottlenecks with better visibility (React Team, 2025).&lt;/p&gt;

&lt;p&gt;On the framework side, Next.js 16 introduced Cache Components, made Turbopack the default bundler, expanded React 19.2 support, and tightened several APIs around async request data. Then Next.js 16.2 improved development startup time, rendering speed, hydration mismatch debugging, and server function logging (Next.js Team, 2025, 2026).&lt;/p&gt;

&lt;p&gt;For a business owner, that long list reduces to three useful questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Will the site feel faster?&lt;/li&gt;
&lt;li&gt;Will forms and customer interactions break less often?&lt;/li&gt;
&lt;li&gt;Will my developer spend less time fighting the framework?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answer is yes to those three, the upgrade is worth serious consideration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1519389950473-47ba0277781c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1519389950473-47ba0277781c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Developers collaborating around computers while reviewing a web project" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recent React and Next.js improvements are most valuable when they reduce friction in real business workflows like leads, forms, and content updates.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why React 19 Is More Relevant to Lead Generation Than Most People Realize
&lt;/h2&gt;

&lt;p&gt;Many small business websites still treat forms like an afterthought. The page looks fine, but the actual interaction is clunky: double submissions, inconsistent pending states, vague error handling, or fragile JavaScript that fails on slower devices. React 19 directly targets that category of problem.&lt;/p&gt;

&lt;p&gt;The React team stabilized Actions in React 19 so developers can handle async form work with less custom state management. It also introduced &lt;code&gt;useFormStatus&lt;/code&gt;, which makes it easier to disable submit buttons and reflect pending states correctly, and &lt;code&gt;useOptimistic&lt;/code&gt;, which helps keep interfaces responsive while the server finishes work (React Team, 2024).&lt;/p&gt;

&lt;p&gt;That matters because a lead form is not just a technical component. It is a conversion point. If a visitor requests a quote, books a call, or asks for pricing, the form experience is part of the sales process. Cleaner form handling improves perceived professionalism and reduces abandonment.&lt;/p&gt;

&lt;p&gt;React 19.2 also added &lt;code&gt;useEffectEvent&lt;/code&gt;, which is especially useful for cleaning up effect logic that tends to create bugs in interactive components. When developers can separate event logic from effect dependencies more cleanly, they reconnect fewer sockets, re-run fewer unnecessary effects, and avoid the sort of brittle behavior that causes "it works on my machine" regressions (React Team, 2025).&lt;/p&gt;

&lt;p&gt;For most small business sites, this does not mean "you need React 19 because it is trendy." It means "if your site has forms, calculators, portals, booking flows, or gated assets, React 19 removes real sources of friction."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Next.js 16.2 Is a Bigger Story Than a Version Number
&lt;/h2&gt;

&lt;p&gt;As of June 11, 2026, the latest major stable line on the official Next.js blog is Next.js 16.2, published on March 18, 2026. According to Vercel's release notes, 16.2 includes faster &lt;code&gt;next dev&lt;/code&gt; startup, roughly 50% faster rendering in the scenarios they profiled, server function logging, hydration diff indicators, and more than 200 Turbopack fixes and improvements (Next.js Team, 2026).&lt;/p&gt;

&lt;p&gt;For agencies and in-house developers, that is a serious quality-of-life release. Faster local startup and better hydration debugging shorten the time between finding a problem and fixing it. Faster rendering helps both local workflows and production behavior.&lt;/p&gt;

&lt;p&gt;Next.js 16 also changed how teams should think about caching. Cache Components make caching more explicit and opt-in, which is healthier than relying on framework magic you do not fully understand. That matters on content-heavy business sites because you want the fast load of static content without losing the ability to show dynamic pieces like availability, seasonal banners, pricing disclaimers, or localized calls to action (Next.js Team, 2025).&lt;/p&gt;

&lt;p&gt;This release line also pushes teams toward more intentional architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server-render what should be crawlable.&lt;/li&gt;
&lt;li&gt;Cache what is stable.&lt;/li&gt;
&lt;li&gt;Keep dynamic logic where it belongs.&lt;/li&gt;
&lt;li&gt;Ship less client JavaScript by default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That philosophy aligns well with SEO, AEO, and GEO because search engines and answer engines still benefit from fast, structured, immediately available HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Still Decides Whether the Upgrade Was Worth It
&lt;/h2&gt;

&lt;p&gt;A framework upgrade only matters if the user experience actually improves. That is where Core Web Vitals still matter.&lt;/p&gt;

&lt;p&gt;According to web.dev, Interaction to Next Paint, or INP, is a stable Core Web Vital that measures responsiveness, and a good INP score is 200 milliseconds or less at the 75th percentile of page loads. Scores above 200 milliseconds need improvement, and scores above 500 milliseconds are poor (Wagner &amp;amp; Pollard, 2025).&lt;/p&gt;

&lt;p&gt;That benchmark is important because many business websites do not fail on design. They fail on responsiveness. The site loads, but menus lag, forms feel sticky, filters stutter, or the page becomes unresponsive after the first interaction. Those are the moments that cost trust and conversions.&lt;/p&gt;

&lt;p&gt;React 19.2 is relevant here because the React team explicitly notes that its SSR batching heuristics are designed to avoid negatively affecting LCP, and its new performance tracks give developers better visibility into what React is doing during rendering (React Team, 2025). Next.js 16.2 is relevant because it improves rendering speed and gives teams better diagnostics when server and client output diverge (Next.js Team, 2026).&lt;/p&gt;

&lt;p&gt;If your website already has strong field data in PageSpeed Insights and Google Search Console, you may not need a major rebuild. If your site has poor INP, bloated client bundles, hydration mismatches, or sluggish forms, the newer stack can help solve a real problem instead of creating a cosmetic one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1551434678-e076c223a692%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1551434678-e076c223a692%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Team reviewing performance metrics and website work in a modern office" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Framework upgrades should be judged by measurable outcomes like responsiveness, rendering speed, and lead-flow reliability, not by version numbers alone.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Security Lesson Small Businesses Should Not Miss
&lt;/h2&gt;

&lt;p&gt;The most important recent web development story was not a shiny feature. It was patch discipline.&lt;/p&gt;

&lt;p&gt;On December 3, 2025, the React team disclosed a critical remote code execution vulnerability in React Server Components, CVE-2025-55182, and recommended immediate upgrades. The affected packages were fixed in React 19.0.1, 19.1.2, and 19.2.1 (React Team, 2025). The Next.js team published a related downstream advisory the same day for App Router applications on affected release lines, and followed with another security update on December 11, 2025 for additional denial-of-service and source-code-exposure issues (Next.js Team, 2025).&lt;/p&gt;

&lt;p&gt;That matters for non-technical business owners because it changes the question from "Is my site on a modern framework?" to "Is my site being maintained like production software?"&lt;/p&gt;

&lt;p&gt;A site running a respected framework but left unpatched is not modern in any meaningful sense.&lt;/p&gt;

&lt;p&gt;If your developer or agency cannot tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what framework version you are on,&lt;/li&gt;
&lt;li&gt;when it was last patched,&lt;/li&gt;
&lt;li&gt;whether your site uses affected App Router features,&lt;/li&gt;
&lt;li&gt;and how security updates are tested before deploy,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then your website is carrying more operational risk than it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should Every Small Business Site Upgrade Right Now?
&lt;/h2&gt;

&lt;p&gt;No. Not every site needs an immediate jump to Next.js 16.2 and React 19.2.&lt;/p&gt;

&lt;p&gt;If your current site is fast, secure, easy to update, and converting well, a forced upgrade can be wasted effort. This is especially true for brochure-style sites with minimal interactivity. A business does not get bonus revenue for owning the newest toolchain if the old one is already performing well.&lt;/p&gt;

&lt;p&gt;But there are clear signs an upgrade should move higher on the priority list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your forms rely on fragile client-side code.&lt;/li&gt;
&lt;li&gt;Your site has hydration mismatch bugs.&lt;/li&gt;
&lt;li&gt;Your Core Web Vitals are weak in field data.&lt;/li&gt;
&lt;li&gt;Content updates require too much developer effort.&lt;/li&gt;
&lt;li&gt;Your current stack makes security patching slow or risky.&lt;/li&gt;
&lt;li&gt;You are planning new interactive features like booking, portals, dashboards, or calculators.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For those cases, the modern React and Next.js stack is not just a developer preference. It is infrastructure for better performance, cleaner maintenance, and more dependable conversion flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Upgrade Checklist for 2026
&lt;/h2&gt;

&lt;p&gt;If you are evaluating whether to modernize your site this year, start here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Measure your real-world performance first, especially INP, LCP, and CLS.&lt;/li&gt;
&lt;li&gt;Audit every lead form, booking flow, and quote request for friction points.&lt;/li&gt;
&lt;li&gt;Confirm your current React and Next.js versions, plus the last patch date.&lt;/li&gt;
&lt;li&gt;Identify which pages truly need client-side interactivity and which should stay server-rendered.&lt;/li&gt;
&lt;li&gt;Reduce unnecessary JavaScript before assuming a full rebuild is required.&lt;/li&gt;
&lt;li&gt;Plan upgrades around business value, not release hype.&lt;/li&gt;
&lt;li&gt;Re-test SEO fundamentals after any upgrade: titles, canonicals, schema, crawlability, and internal links.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For many companies, the best move is not "rebuild everything." It is "upgrade selectively, simplify aggressively, and preserve what is already working."&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ: What Business Owners Usually Ask Next
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does upgrading to React 19 and Next.js 16 automatically improve SEO?
&lt;/h3&gt;

&lt;p&gt;No. The upgrade creates better conditions for SEO, especially through stronger rendering patterns, better performance, and cleaner architecture, but rankings still depend on content quality, internal linking, topical relevance, and technical execution. A fast framework does not rescue weak messaging.&lt;/p&gt;

&lt;h3&gt;
  
  
  If my website is on Next.js 14 and React 18, am I behind?
&lt;/h3&gt;

&lt;p&gt;Not automatically. A site on Next.js 14 and React 18 can still perform well if it is fast, secure, and maintained properly. The bigger issue is whether it is patched, stable, and easy to evolve. Version age matters less than operational discipline.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the biggest business benefit of the recent React changes?
&lt;/h3&gt;

&lt;p&gt;For most service businesses, it is better handling of forms and interactive states. Lead generation often lives or dies in small interface details like pending buttons, clear submission states, and responsive interactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the biggest business benefit of the recent Next.js changes?
&lt;/h3&gt;

&lt;p&gt;More predictable caching, better debugging, and improved rendering performance. Those improvements reduce developer time, lower bug risk, and help teams ship changes more confidently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Recent React and Next.js updates matter in 2026 because they improve the parts of a business website that actually affect revenue: form reliability, rendering performance, debugging speed, and long-term maintainability. They also reinforced a harder truth, modern stacks still require active security patching.&lt;/p&gt;

&lt;p&gt;The right move for most small businesses is not blind upgrade pressure. It is a clear technical audit: measure the site, identify where users feel friction, patch what is vulnerable, and modernize only where the newer stack creates a measurable advantage.&lt;/p&gt;

&lt;p&gt;If you want that kind of audit, Echo Effect can help you evaluate whether your current website needs a patch cycle, a targeted rebuild, or a full platform modernization.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Next.js Team. (2025, October 21). &lt;em&gt;Next.js 16&lt;/em&gt;. Next.js. &lt;a href="https://nextjs.org/blog/next-16" rel="noopener noreferrer"&gt;https://nextjs.org/blog/next-16&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next.js Team. (2025, December 3). &lt;em&gt;Security advisory: CVE-2025-66478&lt;/em&gt;. Next.js. &lt;a href="https://nextjs.org/blog/CVE-2025-66478" rel="noopener noreferrer"&gt;https://nextjs.org/blog/CVE-2025-66478&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next.js Team. (2025, December 11). &lt;em&gt;Next.js security update: December 11, 2025&lt;/em&gt;. Next.js. &lt;a href="https://nextjs.org/blog/security-update-2025-12-11" rel="noopener noreferrer"&gt;https://nextjs.org/blog/security-update-2025-12-11&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next.js Team. (2026, March 18). &lt;em&gt;Next.js 16.2&lt;/em&gt;. Next.js. &lt;a href="https://nextjs.org/blog/next-16-2" rel="noopener noreferrer"&gt;https://nextjs.org/blog/next-16-2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Team. (2024, December 5). &lt;em&gt;React v19&lt;/em&gt;. React. &lt;a href="https://react.dev/blog/2024/12/05/react-19" rel="noopener noreferrer"&gt;https://react.dev/blog/2024/12/05/react-19&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Team. (2025, October 1). &lt;em&gt;React 19.2&lt;/em&gt;. React. &lt;a href="https://react.dev/blog/2025/10/01/react-19-2" rel="noopener noreferrer"&gt;https://react.dev/blog/2025/10/01/react-19-2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Team. (2025, December 3). &lt;em&gt;Critical security vulnerability in React Server Components&lt;/em&gt;. React. &lt;a href="https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components" rel="noopener noreferrer"&gt;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wagner, J., &amp;amp; Pollard, B. (2025, September 2). &lt;em&gt;Interaction to Next Paint (INP)&lt;/em&gt;. web.dev. &lt;a href="https://web.dev/articles/inp" rel="noopener noreferrer"&gt;https://web.dev/articles/inp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Google Ads Negative Keywords: What They Do and Why They Matter</title>
      <dc:creator>Ryan VerWey</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:25:01 +0000</pubDate>
      <link>https://dev.to/rverwey/google-ads-negative-keywords-what-they-do-and-why-they-matter-1jn7</link>
      <guid>https://dev.to/rverwey/google-ads-negative-keywords-what-they-do-and-why-they-matter-1jn7</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.echoeffect.net/blog/google-ads-negative-keywords-2026" rel="noopener noreferrer"&gt;echoeffect.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Google Ads can bring in high-intent leads fast, but it can also spend money on searches that were never going to become customers.&lt;/p&gt;

&lt;p&gt;That is where negative keywords matter.&lt;/p&gt;

&lt;p&gt;A negative keyword tells Google Ads when not to show your ad. If you run a campaign for website design, you may want traffic from searches like "small business website designer" or "custom web design agency." You probably do not want to pay for searches like "free website templates," "web design jobs," or "how to learn web design for beginners."&lt;/p&gt;

&lt;p&gt;Those people may be searching about the same general topic, but they are not looking to hire you. Without negative keywords, your campaign can waste budget on curiosity clicks, job seekers, students, bargain hunters, competitors, and searches that only look relevant at first glance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The short version:&lt;/strong&gt; Keywords tell Google who you want to reach. Negative keywords tell Google who you do not want to pay for.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Negative Keywords Are
&lt;/h2&gt;

&lt;p&gt;A negative keyword is a word or phrase that prevents your ad from showing for certain searches. Google defines it as a keyword type that stops your ad from being triggered by a specific word or phrase. In practice, it is one of the most important controls inside a paid search campaign.&lt;/p&gt;

&lt;p&gt;Positive keywords open the door. Negative keywords close the wrong doors.&lt;/p&gt;

&lt;p&gt;If you sell emergency plumbing services, the keyword "plumber near me" might be valuable. But if your ads also show for "plumber salary," "plumber license class," or "DIY plumber tools," you are paying for people who are not trying to book service. Adding negatives like "salary," "license class," "DIY," and "tools" helps keep the campaign focused on buyers.&lt;/p&gt;

&lt;p&gt;Google's own &lt;a href="https://support.google.com/google-ads/answer/2453972" rel="noopener noreferrer"&gt;negative keyword documentation&lt;/a&gt; puts the goal plainly: exclude search terms from campaigns so your ads focus on the keywords that matter to customers.&lt;/p&gt;

&lt;p&gt;That is the whole point. Negative keywords are not about getting fewer clicks for the sake of it. They are about getting fewer bad clicks so more of the budget can reach people with real intent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1608222351212-18fe0ec7b13b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1608222351212-18fe0ec7b13b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Marketing analytics dashboard on a laptop showing campaign performance data" width="1200" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Negative keywords turn Google Ads from a broad traffic source into a more disciplined lead generation system.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Negative Keywords Matter for Small Businesses
&lt;/h2&gt;

&lt;p&gt;Small businesses usually do not have unlimited ad budgets. A national brand can waste a few thousand dollars while testing a messy campaign and barely notice. A local contractor, law firm, clinic, gym, or service business cannot afford that.&lt;/p&gt;

&lt;p&gt;Every irrelevant click does two kinds of damage.&lt;/p&gt;

&lt;p&gt;First, it spends money directly. If your average cost per click is $7 and twenty irrelevant searches click your ad this week, that is $140 gone with no realistic path to revenue.&lt;/p&gt;

&lt;p&gt;Second, it corrupts the campaign's learning signals. Google Ads optimizes based on the data you feed it. If low-quality traffic clicks, bounces, fails to convert, or triggers weak conversion actions, the campaign gets noisier. The algorithm has a harder time identifying what a valuable customer actually looks like.&lt;/p&gt;

&lt;p&gt;Negative keywords help protect the campaign from that noise.&lt;/p&gt;

&lt;p&gt;They can improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Budget efficiency:&lt;/strong&gt; Less spend goes to searches that cannot convert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead quality:&lt;/strong&gt; More clicks come from people closer to buying.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTR:&lt;/strong&gt; Ads stop showing for searches where they are a poor fit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversion rate:&lt;/strong&gt; The remaining traffic is more aligned with the offer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reporting clarity:&lt;/strong&gt; Search term reports become easier to interpret.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to block everything uncertain. The goal is to remove patterns that are clearly wrong for the business.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Negative Keywords Actually Do
&lt;/h2&gt;

&lt;p&gt;Negative keywords affect eligibility. When a search includes a blocked term or phrase, your ad becomes ineligible for that auction.&lt;/p&gt;

&lt;p&gt;That sounds simple, but it matters because Google Ads matching has become broader over time. Modern match types, automation, and smart bidding can all expand reach beyond the exact phrases you originally typed into the account. That can be useful when the system finds profitable variations. It can also be expensive when the system wanders into irrelevant territory.&lt;/p&gt;

&lt;p&gt;Negative keywords give you a steering mechanism.&lt;/p&gt;

&lt;p&gt;For example, a campaign targeting "social media marketing agency" might accidentally show for searches like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;social media marketing jobs&lt;/li&gt;
&lt;li&gt;social media marketing degree&lt;/li&gt;
&lt;li&gt;social media marketing examples for school&lt;/li&gt;
&lt;li&gt;free social media marketing course&lt;/li&gt;
&lt;li&gt;social media marketing salary&lt;/li&gt;
&lt;li&gt;social media marketing software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those searches contain similar words, but the intent is different. A business selling consulting or campaign management should not treat them all the same.&lt;/p&gt;

&lt;p&gt;Negatives like "jobs," "degree," "school," "free course," "salary," and "software" help separate buyer intent from research intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Negative Match Types
&lt;/h2&gt;

&lt;p&gt;Negative keywords can use broad match, phrase match, or exact match in Search campaigns. The names sound familiar, but Google notes that negative match types work differently from positive keyword match types.&lt;/p&gt;

&lt;p&gt;That difference is important. Negative keywords are literal controls, not magic intent readers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Negative Broad Match
&lt;/h2&gt;

&lt;p&gt;Negative broad match blocks a search when all the negative keyword terms appear in the search, even if they appear in a different order.&lt;/p&gt;

&lt;p&gt;If your negative broad keyword is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;free website&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your ad may be blocked for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;free website builder&lt;/li&gt;
&lt;li&gt;website free trial&lt;/li&gt;
&lt;li&gt;best free website templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it may still show for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;free hosting&lt;/li&gt;
&lt;li&gt;website design pricing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why? Because both words from the negative keyword are not present.&lt;/p&gt;

&lt;p&gt;Negative broad match is useful for general patterns, but it can miss related searches that do not use the exact same words. If you want to block several variations, you may need several negatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Negative Phrase Match
&lt;/h2&gt;

&lt;p&gt;Negative phrase match blocks searches that include the phrase in the same order, even if other words come before or after it.&lt;/p&gt;

&lt;p&gt;If your negative phrase keyword is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"web design jobs"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your ad may be blocked for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remote web design jobs&lt;/li&gt;
&lt;li&gt;web design jobs near me&lt;/li&gt;
&lt;li&gt;entry level web design jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it may still show for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jobs in website design&lt;/li&gt;
&lt;li&gt;web designer hiring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Negative phrase match is helpful when a specific phrase is consistently wrong, but you do not want to block every search containing one of the individual words.&lt;/p&gt;

&lt;h2&gt;
  
  
  Negative Exact Match
&lt;/h2&gt;

&lt;p&gt;Negative exact match blocks only searches that match the exact negative keyword meaningfully as entered, without extra words.&lt;/p&gt;

&lt;p&gt;If your negative exact keyword is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[website design]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your ad may be blocked for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;website design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it may still show for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;website design company&lt;/li&gt;
&lt;li&gt;small business website design&lt;/li&gt;
&lt;li&gt;website design services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Negative exact match is precise. Use it when one specific search term is bad, but longer versions may still be valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake Most Businesses Make
&lt;/h2&gt;

&lt;p&gt;Most small businesses treat negative keywords as a one-time setup task. They add a few obvious terms like "free," "cheap," "jobs," and "DIY," then ignore the account for months.&lt;/p&gt;

&lt;p&gt;That is not enough.&lt;/p&gt;

&lt;p&gt;Negative keyword management is ongoing because real search behavior changes. New competitors enter the market. New services launch. Google expands matching. Customers phrase problems in ways you did not predict. A campaign that looked clean in week one can quietly drift by week six.&lt;/p&gt;

&lt;p&gt;The best source of negative keyword ideas is the search terms report. Google's &lt;a href="https://support.google.com/google-ads/answer/2684537" rel="noopener noreferrer"&gt;search terms report definition&lt;/a&gt; explains that it shows the actual terms people searched when your ad was shown, and that less relevant searches can be added as negative keywords.&lt;/p&gt;

&lt;p&gt;That report should be reviewed regularly, especially during the first month of a new campaign.&lt;/p&gt;

&lt;p&gt;Look for terms that reveal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job seekers&lt;/li&gt;
&lt;li&gt;Students&lt;/li&gt;
&lt;li&gt;Freebie hunters&lt;/li&gt;
&lt;li&gt;DIY intent&lt;/li&gt;
&lt;li&gt;Support requests&lt;/li&gt;
&lt;li&gt;Competitor research&lt;/li&gt;
&lt;li&gt;Wrong locations&lt;/li&gt;
&lt;li&gt;Wrong service categories&lt;/li&gt;
&lt;li&gt;Low-budget searches that do not match your offer&lt;/li&gt;
&lt;li&gt;Informational searches with no buying intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more expensive the campaign, the more often you should review it. For a small budget, weekly may be enough. For a campaign spending aggressively, search terms deserve attention multiple times per week.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1526628953301-3e589a6a8b74%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1526628953301-3e589a6a8b74%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="Close-up campaign analytics dashboard showing CTR and quality score metrics" width="1200" height="864"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Search term reviews show where your budget is actually going. That is where the best negative keyword decisions come from.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Account-Level Lists vs Campaign-Level Negatives
&lt;/h2&gt;

&lt;p&gt;Not every negative keyword belongs in the same place.&lt;/p&gt;

&lt;p&gt;Some negatives are account-wide. If your business never offers free services, "free" may belong at the account level. If you never hire through lead generation campaigns, job-related negatives may belong across most campaigns.&lt;/p&gt;

&lt;p&gt;Other negatives are campaign-specific. A web design campaign should probably block "social media templates" if it is not relevant. But a social media consulting campaign may want that traffic. A residential service campaign may block commercial searches, while a commercial campaign may block residential searches.&lt;/p&gt;

&lt;p&gt;Google supports &lt;a href="https://support.google.com/google-ads/answer/2453983" rel="noopener noreferrer"&gt;negative keyword lists&lt;/a&gt;, which make it easier to manage shared exclusions across multiple campaigns. This is cleaner than copying the same negatives into every campaign by hand.&lt;/p&gt;

&lt;p&gt;A practical account structure might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Global exclusions:&lt;/strong&gt; free, jobs, salary, training, course, definition, template, PDF&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitor exclusions:&lt;/strong&gt; competitor names you intentionally do not want to target&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location exclusions:&lt;/strong&gt; cities, states, or countries you do not serve&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service exclusions:&lt;/strong&gt; services you do not offer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Campaign-specific exclusions:&lt;/strong&gt; terms that are wrong for one campaign but useful for another&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be careful with global lists. A negative keyword added at the wrong level can block good traffic everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Negative Keywords Are Not a Strategy by Themselves
&lt;/h2&gt;

&lt;p&gt;Negative keywords are powerful, but they cannot fix a bad campaign alone.&lt;/p&gt;

&lt;p&gt;If your offer is unclear, your landing page is weak, your conversion tracking is broken, or your targeting is too broad, negatives will only reduce the damage. They will not turn a poor strategy into a profitable one.&lt;/p&gt;

&lt;p&gt;Think of negative keywords as a filter.&lt;/p&gt;

&lt;p&gt;They do not create demand. They do not write better ads. They do not improve your landing page. They do not make an uncompetitive offer compelling. They simply stop certain bad-fit searches from spending budget.&lt;/p&gt;

&lt;p&gt;That filter works best when the rest of the campaign is sound:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The campaign has a clear conversion goal.&lt;/li&gt;
&lt;li&gt;Keywords match real buying intent.&lt;/li&gt;
&lt;li&gt;Ad copy reflects the searcher's problem.&lt;/li&gt;
&lt;li&gt;The landing page answers the question immediately.&lt;/li&gt;
&lt;li&gt;Conversion tracking is installed and tested.&lt;/li&gt;
&lt;li&gt;Calls, forms, bookings, and sales are measured correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those pieces are missing, negative keywords still help, but they are not enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Negative Keyword Mistakes
&lt;/h2&gt;

&lt;p&gt;The first mistake is being too timid. Some advertisers are afraid to block anything because they do not want to lose reach. But reach is not the goal. Revenue is the goal. If a search pattern clearly does not produce qualified leads, keeping it active just makes the reporting look busier.&lt;/p&gt;

&lt;p&gt;The second mistake is being too aggressive. Blocking broad terms without thinking through buyer intent can kill useful traffic. For example, adding "cheap" as a negative may make sense for a premium agency. But for a repair service where people search "cheap emergency plumber" and still convert, blocking it could remove profitable leads.&lt;/p&gt;

&lt;p&gt;The third mistake is ignoring close variants. Google says negative keywords do not match to close variants or other expansions in the same way positive keywords can. If you want to block multiple versions of a bad search, you may need to add those versions directly.&lt;/p&gt;

&lt;p&gt;The fourth mistake is using only exact match negatives. Exact match is clean, but it can be too narrow. If a theme is consistently irrelevant, phrase or broad negatives may control waste faster.&lt;/p&gt;

&lt;p&gt;The fifth mistake is never auditing old negatives. A negative keyword that made sense last year may be wrong after a service expansion, location change, pricing change, or new campaign strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Negative Keyword Workflow
&lt;/h2&gt;

&lt;p&gt;Here is the process we recommend for most small business Google Ads accounts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with obvious exclusions before launch.&lt;/strong&gt; Add known bad-fit categories like jobs, free, DIY, training, tutorials, templates, and unrelated services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the search terms report after the first few days.&lt;/strong&gt; Look for spend on terms that clearly do not match the offer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate bad searches from weak searches.&lt;/strong&gt; A bad search should be blocked. A weak search may need better ad copy, a different landing page, or more data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose the right match type.&lt;/strong&gt; Use exact for one bad term, phrase for a recurring phrase, and broad for a recurring theme that consistently wastes money.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use lists for repeated patterns.&lt;/strong&gt; Shared lists make account management easier and reduce missed exclusions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit before major campaign changes.&lt;/strong&gt; Before scaling budget, expanding match types, or launching Performance Max and broader campaign types, review negatives again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow is not complicated. It just has to be consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for Your Ad Budget
&lt;/h2&gt;

&lt;p&gt;Google Ads is not expensive because clicks cost money. It is expensive because bad clicks cost money without creating opportunity.&lt;/p&gt;

&lt;p&gt;Negative keywords protect the budget from searches that were never likely to convert. They help Google Ads focus on the people who are closer to taking action. They make reporting cleaner. They reduce waste. They give small businesses a better chance of turning paid search into qualified leads instead of random traffic.&lt;/p&gt;

&lt;p&gt;If you are running Google Ads and have not reviewed your search terms recently, that is the first place to look. The account is already telling you where the waste is. Negative keywords are how you act on it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want a quick audit?&lt;/strong&gt; Echo Effect can review your Google Ads search terms, identify wasted spend patterns, and build a negative keyword structure that protects your budget before you scale.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>seo</category>
      <category>marketing</category>
      <category>google</category>
      <category>ads</category>
    </item>
  </channel>
</rss>
