<?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: freewebsite247</title>
    <description>The latest articles on DEV Community by freewebsite247 (@freewebsite247).</description>
    <link>https://dev.to/freewebsite247</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%2F4215691%2Ffeb79048-0b86-45b4-a7db-e61cb557fdac.png</url>
      <title>DEV Community: freewebsite247</title>
      <link>https://dev.to/freewebsite247</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freewebsite247"/>
    <language>en</language>
    <item>
      <title>How to make an AI-built website show up on Google (a fixed version of the viral Claude Code prompt)</title>
      <dc:creator>freewebsite247</dc:creator>
      <pubDate>Mon, 02 Nov 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/freewebsite247/how-to-make-an-ai-built-website-show-up-on-google-a-fixed-version-of-the-viral-claude-code-prompt-1b18</link>
      <guid>https://dev.to/freewebsite247/how-to-make-an-ai-built-website-show-up-on-google-a-fixed-version-of-the-viral-claude-code-prompt-1b18</guid>
      <description>&lt;p&gt;A joke prompt went around X in October: twenty one-line SEO orders for a vibe-coded site, ending with "Rank #1 by Friday." The punchline is that the list really is most of the technical checklist. Paste it into Claude Code and the agent will do something with every line.&lt;/p&gt;

&lt;p&gt;But a few lines are out of date, some can't be done by a coding agent, and the order matters. Below is the checklist in the order that works, with commands to verify each step and a rewritten prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Check what a crawler gets without JavaScript
&lt;/h2&gt;

&lt;p&gt;Run this against the live site, not the dev server:&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;-i&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the browser shows a heading and curl shows nothing, your content is built in the browser. Googlebot &lt;a href="https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics" rel="noopener noreferrer"&gt;does run JavaScript&lt;/a&gt;, so server-side rendering isn't strictly required. But rendering is queued, and not all bots run JavaScript. Static HTML is the safer default, and you don't need a server for it: Astro prerenders every page at build time unless you opt out. For a client-side React or Vue app, add a prerender step or move the marketing pages to a framework that outputs HTML.&lt;/p&gt;

&lt;p&gt;Links must be &lt;code&gt;&amp;lt;a href="..."&amp;gt;&lt;/code&gt;, because Google doesn't follow &lt;code&gt;onClick&lt;/code&gt; handlers. And a made-up URL must return a real 404:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;A single-page app with a catch-all route often returns 200 here, which Search Console reports as a soft 404.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Remove everything that blocks indexing
&lt;/h2&gt;

&lt;p&gt;There are three places a block can hide:&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/robots.txt
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; x-robots-tag
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rni&lt;/span&gt; &lt;span class="s2"&gt;"noindex"&lt;/span&gt; src/ public/ astro.config.&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove &lt;code&gt;Disallow: /&lt;/code&gt; and any &lt;code&gt;noindex&lt;/code&gt; meta tag or &lt;code&gt;X-Robots-Tag&lt;/code&gt; header from production pages, including ones set in your host's headers config.&lt;/p&gt;

&lt;p&gt;Pages that should stay out of Google (thank-you pages, a client login) get &lt;code&gt;noindex&lt;/code&gt; and stay crawlable. A page &lt;a href="https://developers.google.com/search/docs/crawling-indexing/block-indexing" rel="noopener noreferrer"&gt;blocked in robots.txt&lt;/a&gt; can't have its noindex read, so it can still show up in results. And set noindex in the HTML the server sends. Google may skip rendering when it sees one, so removing it with JavaScript may never register.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Generate a sitemap and point robots.txt at it
&lt;/h2&gt;

&lt;p&gt;In Astro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx astro add sitemap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// astro.config.mjs&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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;astro/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sitemap&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;@astrojs/sitemap&lt;/span&gt;&lt;span class="dl"&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;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;site&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://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// required, or no sitemap is built&lt;/span&gt;
  &lt;span class="na"&gt;integrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;sitemap&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;The build writes &lt;code&gt;dist/sitemap-index.xml&lt;/code&gt; and &lt;code&gt;dist/sitemap-0.xml&lt;/code&gt;. One catch: &lt;a href="https://docs.astro.build/en/guides/integrations-guide/sitemap/" rel="noopener noreferrer"&gt;the integration can't list dynamic routes rendered on demand&lt;/a&gt;, only prerendered ones.&lt;/p&gt;

&lt;p&gt;Then &lt;code&gt;public/robots.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="n"&gt;Sitemap&lt;/span&gt;: &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;example&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;/&lt;span class="n"&gt;sitemap&lt;/span&gt;-&lt;span class="n"&gt;index&lt;/span&gt;.&lt;span class="n"&gt;xml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google &lt;a href="https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap" rel="noopener noreferrer"&gt;ignores &lt;code&gt;priority&lt;/code&gt; and &lt;code&gt;changefreq&lt;/code&gt;&lt;/a&gt; and only trusts &lt;code&gt;lastmod&lt;/code&gt; when it's accurate, so don't let the agent fake dates.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Give every page exactly one URL
&lt;/h2&gt;

&lt;p&gt;Pick https, either www or non-www, and one trailing-slash style (&lt;code&gt;trailingSlash&lt;/code&gt; in the Astro config). Every other variant should reach the final URL in one 301:&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;-sIL&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{num_redirects} hops -&amp;gt; %{url_effective}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; http://www.example.com/services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google follows up to 10 hops, so a chain won't break indexing, but aim for one. Internal links should point at the final URL and not redirect at all.&lt;/p&gt;

&lt;p&gt;For canonicals, add one absolute, self-referencing tag in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of your layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
const canonical = new URL(Astro.url.pathname, Astro.site);
---
&amp;lt;link rel="canonical" href={canonical} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google treats a canonical as a strong signal, not an order, so it only works when your redirects, internal links and sitemap all agree with it.&lt;/p&gt;

&lt;p&gt;A 404 on a page that's really gone is correct, and Google simply drops it. Fix the internal links pointing at it, and 301 old URLs that have a clear replacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Do the on-page basics, minus the myths
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unique &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; and meta description on every page. Google often writes its own snippet from page content, so the description is a suggestion.&lt;/li&gt;
&lt;li&gt;One H1 per page helps screen readers, but Google's starter guide says heading order doesn't matter for Search. Don't expect a ranking change.&lt;/li&gt;
&lt;li&gt;Alt text that describes the image. Decorative images get &lt;code&gt;alt=""&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No orphans. Every sitemap URL needs at least one internal &lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt; pointing to it, because Google finds most new pages through links.&lt;/li&gt;
&lt;li&gt;Breadcrumbs plus &lt;code&gt;BreadcrumbList&lt;/code&gt; JSON-LD. Since January 2025 mobile results show only the domain, but desktop still shows the trail, and the links help crawling either way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skip the FAQ schema. Since August 2023 Google &lt;a href="https://developers.google.com/search/blog/2023/08/howto-faq-changes" rel="noopener noreferrer"&gt;shows FAQ rich results only for well-known government and health sites&lt;/a&gt;. Keep the questions and answers on the page as plain content.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Hit the Core Web Vitals numbers
&lt;/h2&gt;

&lt;p&gt;"Under 2 seconds" isn't a metric Google uses. The &lt;a href="https://web.dev/articles/vitals" rel="noopener noreferrer"&gt;Core Web Vitals&lt;/a&gt; targets are LCP 2.5 s or less, INP 200 ms or less, and CLS 0.1 or less, measured at the 75th percentile of real visits.&lt;/p&gt;

&lt;p&gt;A new site has no real-visit data, so PageSpeed Insights shows lab results only, with Total Blocking Time standing in for INP.&lt;/p&gt;

&lt;p&gt;In Astro, most of the image work is one component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import { Image } from 'astro:assets';
import hero from '../assets/hero.jpg';
---
&amp;lt;Image src={hero} alt="Technician fitting a tankless water heater" priority /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;Image /&amp;gt;&lt;/code&gt; outputs WebP by default and sets &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt;, so images don't shift the layout. Keep the file in &lt;code&gt;src/&lt;/code&gt;, because &lt;code&gt;public/&lt;/code&gt; is copied as-is. &lt;code&gt;priority&lt;/code&gt; (Astro 5.10+) turns off lazy loading for the hero, which is usually your LCP element.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Submit the site in Search Console yourself
&lt;/h2&gt;

&lt;p&gt;Claude Code can't do this part. Add a Domain property in Search Console, verify it with the DNS TXT record, then submit &lt;code&gt;https://example.com/sitemap-index.xml&lt;/code&gt; under Sitemaps.&lt;/p&gt;

&lt;p&gt;Use URL Inspection on the homepage and main service pages: "Test live URL", check the rendered HTML, then "Request indexing". There's a quota, and crawling &lt;a href="https://developers.google.com/search/docs/crawling-indexing/ask-google-to-recrawl" rel="noopener noreferrer"&gt;can take a few days to a few weeks&lt;/a&gt;. Friday is optimistic.&lt;/p&gt;

&lt;p&gt;Add the site to Bing Webmaster Tools too. It can import your Search Console properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Do the parts an agent shouldn't
&lt;/h2&gt;

&lt;p&gt;Google doesn't penalize text because an AI wrote it. Its &lt;a href="https://developers.google.com/search/docs/fundamentals/using-gen-ai-content" rel="noopener noreferrer"&gt;guidance&lt;/a&gt; targets pages mass-produced without value for users. The fix for AI-sounding copy is specifics only the business knows: prices, service areas, how a job goes.&lt;/p&gt;

&lt;p&gt;The author bio has to be a real person. Google calls fabricated creator profiles deception, so never let the agent invent one. Backlinks come from real relationships: suppliers, local organizations, trade associations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt
&lt;/h2&gt;

&lt;p&gt;Paste this into Claude Code from the repo root and fill in the brackets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You're working on [site name], a [framework and version] site deployed to [host] at [production URL]. Google isn't indexing it. Audit first, then fix. Don't change prices, business details, reviews or author info.

Preferred URLs: [https + www or non-www], trailing slash [always/never].
Pages that must stay out of Google: [list or "none"].

1. Rendering: build the site and confirm each page's main text, H1 and nav links are in the built HTML without JavaScript, with links as &amp;lt;a href&amp;gt;. List any page that needs JS to show content and propose a prerendered fix.
2. Blocking: find noindex meta tags, X-Robots-Tag headers and robots.txt Disallow rules in the code, build output and host config. Remove them from production pages. Excluded pages get noindex in the server HTML and stay crawlable.
3. Sitemap: generate one containing only canonical, indexable URLs that return 200. Add a Sitemap: line to robots.txt. No fake lastmod dates.
4. URLs: one absolute, self-referencing canonical in &amp;lt;head&amp;gt; on every page, matching my preferred format. Every other variant redirects to the final URL in a single 301. Update internal links that hit redirects or 404s. Unknown URLs must return a real 404 status.
5. On-page: unique title and meta description per page, drafted from that page's content and marked for my review. One H1 per page. Descriptive alt text, alt="" on decorative images. Visible breadcrumbs with BreadcrumbList JSON-LD. List sitemap URLs with no internal links pointing to them and suggest where to link from. No FAQPage schema.
6. Performance: images in WebP or AVIF with width and height set, largest above-the-fold image not lazy-loaded, no layout shifts. Targets on mobile: LCP 2.5s or less, INP 200ms or less, CLS 0.1 or less.
7. Never invent author bios, credentials, reviews or statistics. Leave a TODO where they're missing.

Finish with a table (check, finding, change, file paths), the curl commands I can run on the live site to confirm each fix, and the steps I have to do myself in Search Console.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the output, deploy and run the agent's curl commands against the production URL, because the dev server doesn't show you your host's headers or redirects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;Run the curl checks from steps 1 and 2 on the live site today. If the HTML is empty or a noindex is there, nothing else on the list matters until that's fixed. After that, sitemap and Search Console, then work down in order.&lt;/p&gt;

&lt;p&gt;Based on a post by Suraj Sharma (&lt;a class="mentioned-user" href="https://dev.to/suraj_sharma14"&gt;@suraj_sharma14&lt;/a&gt;) on X: &lt;a href="https://x.com/suraj_sharma14/status/2106240327569035424" rel="noopener noreferrer"&gt;https://x.com/suraj_sharma14/status/2106240327569035424&lt;/a&gt;, with corrections and extra steps.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>ai</category>
      <category>astro</category>
    </item>
    <item>
      <title>How to build a topic cluster for a local business website (with a copy-paste AI prompt)</title>
      <dc:creator>freewebsite247</dc:creator>
      <pubDate>Sat, 31 Oct 2026 13:15:12 +0000</pubDate>
      <link>https://dev.to/freewebsite247/how-to-build-a-topic-cluster-for-a-local-business-website-with-a-copy-paste-ai-prompt-3fmi</link>
      <guid>https://dev.to/freewebsite247/how-to-build-a-topic-cluster-for-a-local-business-website-with-a-copy-paste-ai-prompt-3fmi</guid>
      <description>&lt;p&gt;Most local business websites have one page called "Services". A plumber lists twelve jobs on it, each with one line of text, and that's the whole site.&lt;/p&gt;

&lt;p&gt;That page can't answer "how much is a tankless water heater install in Henderson?" And that's the kind of question people now type into ChatGPT, Perplexity and Google's AI Mode. Those tools quote passages that answer the question. If no page on the site has that passage, they quote a competitor.&lt;/p&gt;

&lt;p&gt;A topic cluster fixes this. Every service and every town gets its own page, and the pages link to each other so people and crawlers can follow the structure. Below is the process, the folder structure in Astro, the schema for each page, and a prompt that plans the whole thing for you in about five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Collect questions, not keywords
&lt;/h2&gt;

&lt;p&gt;Keyword tools give you "plumber henderson nv". Customers ask "can you come today?" and "do you charge a call-out fee?". Get the real questions from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call notes and customer emails&lt;/li&gt;
&lt;li&gt;Google reviews (people often say what they hired the business for)&lt;/li&gt;
&lt;li&gt;Google autocomplete and People Also Ask&lt;/li&gt;
&lt;li&gt;the search terms list in the Google Business Profile performance report&lt;/li&gt;
&lt;li&gt;Search Console queries, if the site already exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ten to thirty questions is enough to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Group them by meaning
&lt;/h2&gt;

&lt;p&gt;"Who fixes leaking pipes?" and "emergency plumber near me" are the same job, so they go on the same page. One group of questions becomes one page.&lt;/p&gt;

&lt;p&gt;If two groups need the same answer, merge them. Two thin pages competing for one question do worse than one good page.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Hubs, spokes and town pages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One hub page per core service: &lt;code&gt;/water-heaters/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One spoke page per sub-service: &lt;code&gt;/water-heaters/tankless-installation/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One page per town the business actually serves: &lt;code&gt;/henderson/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Town pages need real local detail: neighborhoods, typical jobs there, response times. A page that only swaps the city name gets ignored by Google and by readers.&lt;/p&gt;

&lt;p&gt;In Astro, the simple version is plain folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/pages/
  index.astro
  water-heaters/
    index.astro                  # hub
    tankless-installation.astro  # spoke
    repair.astro                 # spoke
  drain-cleaning/
    index.astro
    hydro-jetting.astro
  henderson.astro
  summerlin.astro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you pass a dozen or so services, move them into a &lt;a href="https://docs.astro.build/en/guides/content-collections/" rel="noopener noreferrer"&gt;content collection&lt;/a&gt; and build the routes with &lt;code&gt;getStaticPaths()&lt;/code&gt;. Then every service page shares one layout, one schema component and one internal-link block, and adding a service is one new Markdown file.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Follow-up questions become H2s
&lt;/h2&gt;

&lt;p&gt;Google's AI Overviews and AI Mode &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;may use a "query fan-out" technique&lt;/a&gt;, running several related searches behind one question. For a service page those follow-ups are predictable: cost, how long it takes, licensing, financing, same-day or emergency availability, what's included.&lt;/p&gt;

&lt;p&gt;Give each one an H2, phrased the way a customer would ask it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## How much does tankless water heater installation cost in Henderson?&lt;/span&gt;
&lt;span class="gu"&gt;## How long does a tankless install take?&lt;/span&gt;
&lt;span class="gu"&gt;## Do you need a permit for a tankless water heater in Henderson?&lt;/span&gt;
&lt;span class="gu"&gt;## Can I finance a new water heater?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Answer first
&lt;/h2&gt;

&lt;p&gt;Under every H2, the first 40 to 60 words answer the question, name the service and the city, and still make sense if someone quotes only that paragraph. Details, exceptions and photos come after.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tankless water heater installation in Henderson costs $[low] to $[high] for a whole-home gas unit, including removal of the old tank, new venting and the city permit. Most installs take one day. Electric units cost less up front but may need a panel upgrade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fill in real numbers from the business. If they won't publish prices, give a range and say what moves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Link the cluster both ways
&lt;/h2&gt;

&lt;p&gt;The hub links to every spoke. Every spoke links back to its hub and to one or two related spokes. Town pages link to the services offered there.&lt;/p&gt;

&lt;p&gt;Use anchor text that describes the target page ("tankless water heater installation"), not "click here" or "learn more".&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Add proof
&lt;/h2&gt;

&lt;p&gt;Job photos with real captions, price ranges, reviews that mention the specific service, license numbers. An AI assistant needs something specific to quote, and the person reading needs a reason to call. Same material does both jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Schema and Google Business Profile
&lt;/h2&gt;

&lt;p&gt;Add every spoke as a service on the Google Business Profile, using the same name as the page. On the site, put &lt;code&gt;LocalBusiness&lt;/code&gt; once (sitewide, with the same name, address and phone as the profile), plus &lt;code&gt;Service&lt;/code&gt; and &lt;code&gt;BreadcrumbList&lt;/code&gt; on each service page.&lt;/p&gt;

&lt;p&gt;A small Astro component keeps it consistent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
// src/components/ServiceSchema.astro
const { name, description, url, cities } = Astro.props;

const schema = {
  "@context": "https://schema.org",
  "@type": "Service",
  name,
  description,
  url,
  areaServed: cities.map((city) =&amp;gt; ({ "@type": "City", name: city })),
  provider: { "@id": "https://example.com/#business" },
};
---
&amp;lt;script type="application/ld+json" set:html={JSON.stringify(schema)} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;provider&lt;/code&gt; points at the &lt;code&gt;@id&lt;/code&gt; of your sitewide &lt;code&gt;LocalBusiness&lt;/code&gt; block, so every service is tied to one business entity.&lt;/p&gt;

&lt;p&gt;A note on FAQs: since August 2023, Google only shows FAQ rich results for &lt;a href="https://developers.google.com/search/blog/2023/08/howto-faq-changes" rel="noopener noreferrer"&gt;well-known, authoritative government and health websites&lt;/a&gt;. &lt;code&gt;FAQPage&lt;/code&gt; markup won't get a plumber a rich result. Keep the questions and answers on the page anyway, because those are the passages that get quoted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt
&lt;/h2&gt;

&lt;p&gt;Paste this into ChatGPT, Claude or Gemini and fill in the brackets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Act as a local SEO strategist and build a topic cluster plan for my business.

Business: [name] | Main service: [service] | City + service areas: [towns] | Top services: [5-10] | Customers: [who] | Why us: [same day, financing, years in business]

Customer questions (calls, emails, reviews, autocomplete, People Also Ask, Google Business Profile searches): [paste 10-30]

1. Cluster the questions by meaning, not wording. One cluster = one page.
2. Organize pages as hubs (one per core service), spokes (one per sub-service) and one page per town.
3. Per page: title, URL slug, main question, and 6-10 H2s written as real customer questions, including the follow-ups an AI assistant would ask (cost, timing, licensing, financing, emergencies).
4. Under each H2: a 40-60 word answer first, naming the service and city, that works if quoted alone.
5. Add a table or numbered process where useful, plus 5 FAQs.
6. Map internal links: hub to spokes, spokes to hub, related spokes to each other.
7. List the schema per page (LocalBusiness, Service, BreadcrumbList) and the proof to add (job photos, price ranges, reviews, licenses).
8. Match each page to a Google Business Profile service.

Start with a summary table, then each page outline.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a table of every page and an outline for each one. Check it before you build anything. The model will happily add towns the business doesn't serve and services it doesn't offer, so cut whatever isn't real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;Build the hub for the service that brings in the most money, plus two or three spokes under it, and add the matching services to the Google Business Profile the same day. Town pages come next, one at a time, each with something you can only say about that town.&lt;/p&gt;

&lt;p&gt;Based on Search Engine Land's guide &lt;a href="https://searchengineland.com/guide/topic-clusters-for-ai-search" rel="noopener noreferrer"&gt;How to build topic clusters that AI will cite&lt;/a&gt;, adapted for local service businesses.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>astro</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
