<?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: Andrei SEO</title>
    <description>The latest articles on DEV Community by Andrei SEO (@andrei-seo).</description>
    <link>https://dev.to/andrei-seo</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%2F4183857%2Fdad85ddf-6304-445c-8eff-d4e052abe3f3.jpg</url>
      <title>DEV Community: Andrei SEO</title>
      <link>https://dev.to/andrei-seo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrei-seo"/>
    <language>en</language>
    <item>
      <title>12 SEO Mistakes Developers Ship to Production (and How to Catch Them)</title>
      <dc:creator>Andrei SEO</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:48:33 +0000</pubDate>
      <link>https://dev.to/andrei-seo/12-seo-mistakes-developers-ship-to-production-and-how-to-catch-them-125o</link>
      <guid>https://dev.to/andrei-seo/12-seo-mistakes-developers-ship-to-production-and-how-to-catch-them-125o</guid>
      <description>&lt;p&gt;Most SEO problems I find in audits aren't content or keyword problems. They're bugs. The site looks perfect in the browser, Lighthouse is green, the client is happy, and Google quietly refuses to index half of it.&lt;/p&gt;

&lt;p&gt;The tricky part is that these bugs don't throw errors. Nothing breaks for the user. So here are the 12 I see most often, with a quick way to catch each one.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Shipping the staging noindex to production
&lt;/h2&gt;

&lt;p&gt;The classic. Staging was set to "discourage search engines", the site went live, and nobody unchecked it.&lt;/p&gt;

&lt;p&gt;In WordPress, check it from the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp option get blog_public
&lt;span class="c"&gt;# 0 = search engines discouraged, 1 = indexable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For any stack, check both the HTML and the response headers, since &lt;code&gt;X-Robots-Tag&lt;/code&gt; is easy to forget in a server config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;meta name="robots"'&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://example.com/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'x-robots-tag'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this to your launch checklist. Better yet, make it a deploy check.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. robots.txt blocking what Google needs to render the page
&lt;/h2&gt;

&lt;p&gt;Blocking &lt;code&gt;/wp-content/&lt;/code&gt; or &lt;code&gt;/assets/&lt;/code&gt; "for security" means Googlebot can't load your CSS and JS, so it can't render the page the way users see it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Don't do this
User-agent: *
Disallow: /wp-content/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reverse is just as common: low-value URLs (internal search, filter combinations, admin-ish paths) left fully crawlable. robots.txt controls crawling, not indexing, so for pages that must stay out of the index, use &lt;code&gt;noindex&lt;/code&gt; and let Google crawl them.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Content that only exists after JavaScript runs
&lt;/h2&gt;

&lt;p&gt;With client-side rendering, the initial HTML can be an empty shell. Google does render JavaScript, but it's slower, less reliable, and any error means content (or links) simply don't exist for Googlebot.&lt;/p&gt;

&lt;p&gt;Quick test: compare the raw HTML with what you see in the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com/services/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'Your main heading text'&lt;/span&gt;
&lt;span class="c"&gt;# 0 means the content isn't in the initial HTML&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check the rendered HTML in Search Console's URL Inspection tool. If your main content, menu, or product links only appear after hydration, consider SSR or static generation for those routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Infinite scroll and "load more" without real URLs
&lt;/h2&gt;

&lt;p&gt;Googlebot doesn't scroll or click buttons like a user. Content loaded on scroll events or behind a "Load more" button may never be seen.&lt;/p&gt;

&lt;p&gt;Keep the nice UX, but back it with crawlable pagination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Crawlable fallback the JS can progressively enhance --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/blog/page/2/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Next page&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each page of results should have its own URL that works without JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Canonical and noindex misconfigurations
&lt;/h2&gt;

&lt;p&gt;A few variations I keep finding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every page canonicalized to the homepage (a template bug)&lt;/li&gt;
&lt;li&gt;Canonical pointing to a URL that redirects or returns 404&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;noindex&lt;/code&gt; and &lt;code&gt;canonical&lt;/code&gt; to another URL on the same page (conflicting signals)&lt;/li&gt;
&lt;li&gt;Canonical tags added only by JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check what's actually in the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com/some-page/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'rel="canonical"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then crawl the site (Screaming Frog or similar) and filter for canonicals that don't point to themselves. Every non-self canonical should be intentional.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The CMS generating thousands of empty pages
&lt;/h2&gt;

&lt;p&gt;In a recent audit, a local contractor's site had about 2,600 URLs. Only 58 were service pages. Around 1,650 were &lt;strong&gt;image attachment pages&lt;/strong&gt; and about 700 were &lt;strong&gt;tag archives&lt;/strong&gt;, most with a single post.&lt;/p&gt;

&lt;p&gt;WordPress creates an attachment page for every upload. Since WordPress 6.4, new installs have them disabled, but older sites keep them on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp option get wp_attachment_pages_enabled
wp option update wp_attachment_pages_enabled 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For tag archives, if your SEO plugin doesn't handle it, the core &lt;code&gt;wp_robots&lt;/code&gt; filter does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_robots'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$robots&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="nf"&gt;is_tag&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="nv"&gt;$robots&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'noindex'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$robots&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'follow'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$robots&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;Also check your sitemap index. If you see &lt;code&gt;attachment-sitemap.xml&lt;/code&gt; or a huge &lt;code&gt;post_tag-sitemap.xml&lt;/code&gt;, you have this problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Building URLs with string concatenation
&lt;/h2&gt;

&lt;p&gt;This one I found on my own site yesterday. In the page source:&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;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.comwp-content/uploads/2024/12/image.webp"&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;The missing slash came from an old search-replace (&lt;code&gt;https://old-domain/&lt;/code&gt; → &lt;code&gt;https://example.com&lt;/code&gt;). Users never noticed, because the Elementor lightbox opened the image from a separate, correctly generated URL. Crawlers, on the other hand, saw a broken link on every affected page.&lt;/p&gt;

&lt;p&gt;In your own code, let the framework join paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fragile&lt;/span&gt;
&lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'wp-content/uploads/image.webp'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Safe&lt;/span&gt;
&lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'/wp-content/uploads/image.webp'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;trailingslashit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'wp-content/uploads/image.webp'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when you need a search-replace, always do a dry run first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp search-replace &lt;span class="s1"&gt;'https://old-domain.com'&lt;/span&gt; &lt;span class="s1"&gt;'https://example.com'&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that page builders often store data as JSON with escaped slashes (&lt;code&gt;https:\/\/example.com&lt;/code&gt;), so a plain string replace can miss some occurrences and catch others.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Migrations without redirects
&lt;/h2&gt;

&lt;p&gt;New site, new URL structure, and the old URLs return 404. Every backlink pointing to them is now wasted, and Google has to figure out the new site from scratch.&lt;/p&gt;

&lt;p&gt;Before launch:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Export all old URLs (crawl + sitemap + Search Console pages report)&lt;/li&gt;
&lt;li&gt;Export URLs with backlinks (Ahrefs, Semrush, or Search Console's links report)&lt;/li&gt;
&lt;li&gt;Map each one to its closest new equivalent with a 301&lt;/li&gt;
&lt;li&gt;After launch, crawl the old URL list and confirm each one returns a single 301 to a 200, with no chains&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  9. Hreflang errors on multilingual sites
&lt;/h2&gt;

&lt;p&gt;The most common ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing return links (page A references B, but B doesn't reference A)&lt;/li&gt;
&lt;li&gt;Wrong codes (&lt;code&gt;en-UK&lt;/code&gt; instead of &lt;code&gt;en-GB&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Hreflang injected by JavaScript&lt;/li&gt;
&lt;li&gt;Pointing to non-canonical or redirected URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every language version must list all versions, including 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;"alternate"&lt;/span&gt; &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/en/page/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"ro"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/ro/pagina/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&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;"alternate"&lt;/span&gt; &lt;span class="na"&gt;hreflang=&lt;/span&gt;&lt;span class="s"&gt;"x-default"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/en/page/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Links Google can't follow
&lt;/h2&gt;

&lt;p&gt;Google follows &lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt; links. It doesn't reliably follow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Not a link for Google --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"location.href='/pricing/'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pricing&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"router.push('/pricing/')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pricing&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- A link --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/pricing/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pricing&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combined with a page that's only reachable from the sitemap, you get &lt;strong&gt;orphan pages&lt;/strong&gt;. Compare the URLs in your sitemap with the URLs found by a crawl starting from the homepage. Anything in the sitemap but not in the crawl has no internal links, and Google will treat it as unimportant.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Optimizing the wrong performance metric
&lt;/h2&gt;

&lt;p&gt;I'll probably get some disagreement here, but: the PageSpeed Insights score is a lab score, not a ranking factor. I regularly see pages with a score under 10 ranking first in competitive local searches, and pages scoring 97 losing to pages scoring 60.&lt;/p&gt;

&lt;p&gt;Core Web Vitals do matter, but Google uses &lt;strong&gt;field data&lt;/strong&gt; from real users (the CrUX section at the top of the report), not the lab score. If your field data passes, spending a week moving the lab score from 70 to 95 rarely moves rankings. That week is usually better spent on any of the other 11 items in this list.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Not checking a domain's history
&lt;/h2&gt;

&lt;p&gt;A client bought a domain that looked brand new and perfect for their market. Three months and 30+ pages later, almost nothing was indexed. The domain had been used as a redirect around 2004 and was still distrusted by Google almost 20 years later.&lt;/p&gt;

&lt;p&gt;Check before buying. The Wayback Machine's CDX API shows the earliest captures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://web.archive.org/cdx/search/cdx?url=example.com&amp;amp;limit=10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there's history, open a few snapshots and look for spam, redirects, or unrelated content.&lt;/p&gt;

&lt;h2&gt;
  
  
  A launch checklist you can steal
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;noindex&lt;/code&gt; removed (HTML meta and &lt;code&gt;X-Robots-Tag&lt;/code&gt; header)&lt;/li&gt;
&lt;li&gt;[ ] robots.txt doesn't block CSS, JS or important sections&lt;/li&gt;
&lt;li&gt;[ ] Main content and links present in the raw HTML&lt;/li&gt;
&lt;li&gt;[ ] Pagination has real &lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt; URLs&lt;/li&gt;
&lt;li&gt;[ ] Canonicals self-reference unless intentional&lt;/li&gt;
&lt;li&gt;[ ] No attachment, empty tag or test pages in the sitemap&lt;/li&gt;
&lt;li&gt;[ ] No malformed URLs in a full crawl&lt;/li&gt;
&lt;li&gt;[ ] Old URLs 301 to new ones, no chains&lt;/li&gt;
&lt;li&gt;[ ] Hreflang reciprocal (if multilingual)&lt;/li&gt;
&lt;li&gt;[ ] Sitemap URLs all found in a crawl from the homepage&lt;/li&gt;
&lt;li&gt;[ ] Domain history checked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these require an SEO specialist, just a few minutes of checking before the client finds out from their traffic.&lt;/p&gt;




&lt;p&gt;I wrote a broader version of this for business owners, covering the strategy side too (audits, keyword research, content quality): &lt;a href="https://andreiturca.com/blog/common-seo-mistakes-and-fixes/" rel="noopener noreferrer"&gt;12 Common SEO Mistakes (And How to Avoid Them)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What's the strangest SEO bug you've found in production?&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>wordpress</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
