<?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: Jonathan Comparelli</title>
    <description>The latest articles on DEV Community by Jonathan Comparelli (@jonathancomparelli).</description>
    <link>https://dev.to/jonathancomparelli</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%2F4065513%2Fba89b289-6bf7-47a2-a60c-731967cfa745.png</url>
      <title>DEV Community: Jonathan Comparelli</title>
      <link>https://dev.to/jonathancomparelli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonathancomparelli"/>
    <language>en</language>
    <item>
      <title>How AI answer engines decide which local business to recommend: a schema markup field guide</title>
      <dc:creator>Jonathan Comparelli</dc:creator>
      <pubDate>Fri, 07 Aug 2026 03:25:18 +0000</pubDate>
      <link>https://dev.to/jonathancomparelli/how-ai-answer-engines-decide-which-local-business-to-recommend-a-schema-markup-field-guide-4f8g</link>
      <guid>https://dev.to/jonathancomparelli/how-ai-answer-engines-decide-which-local-business-to-recommend-a-schema-markup-field-guide-4f8g</guid>
      <description>&lt;h2&gt;
  
  
  The question that started this
&lt;/h2&gt;

&lt;p&gt;A homeowner asks ChatGPT: "Who is the best plumber near me?" The answer comes back as a shortlist of three businesses, with confident one-line descriptions of each.&lt;/p&gt;

&lt;p&gt;Where did that shortlist come from? Not from the businesses with the best websites. Not even from the ones with the best Google rankings. In audit after audit, I keep finding the same pattern: the businesses that get recommended are the ones AI can &lt;em&gt;describe with confidence&lt;/em&gt;, and the single biggest lever for that is structured data.&lt;/p&gt;

&lt;p&gt;This guide is the schema layer of that work, written for developers who would rather implement it themselves than hire anyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What answer engines actually read
&lt;/h2&gt;

&lt;p&gt;When an answer engine assembles a local recommendation, it triangulates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Your website&lt;/strong&gt;, and specifically its structured data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your Google Business Profile&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Citations&lt;/strong&gt; across directories (name, address, phone consistency)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reviews and third-party mentions&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You cannot control all of it from code. But the first one is entirely yours, and it is the one most sites get wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The schema that actually moves the needle
&lt;/h2&gt;

&lt;p&gt;Forget generic &lt;code&gt;Organization&lt;/code&gt; markup for a local business. Use the most specific &lt;code&gt;LocalBusiness&lt;/code&gt; subtype you can: &lt;code&gt;Dentist&lt;/code&gt;, &lt;code&gt;LegalService&lt;/code&gt;, &lt;code&gt;MedicalBusiness&lt;/code&gt;, &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt;. Schema.org has subtypes for most local verticals.&lt;/p&gt;

&lt;p&gt;A minimal but complete example:&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;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dentist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Dental Studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Family dentist in Leslieville offering cleanings, implants, and emergency appointments. Accepting new patients."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"telephone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+1-416-555-0142"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"priceRange"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"address"&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;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostalAddress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"streetAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123 Queen St E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressLocality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Toronto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressRegion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ON"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postalCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"M5A 1S2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressCountry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CA"&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;"geo"&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;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GeoCoordinates"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"latitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;43.6629&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"longitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;-79.3287&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;"areaServed"&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="s2"&gt;"Toronto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Leslieville"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Riverdale"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"East York"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openingHoursSpecification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OpeningHoursSpecification"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dayOfWeek"&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="s2"&gt;"Monday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tuesday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wednesday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Thursday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Friday"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"opens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"08:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"closes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18:00"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sameAs"&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="s2"&gt;"https://www.google.com/maps/place/example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://www.facebook.com/example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/company/example"&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;The properties I see skipped most often, ranked by how much they seem to matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;description&lt;/strong&gt;: write it the way you want AI to describe you. One or two sentences, plain language, no slogans. Answer engines paraphrase this field constantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sameAs&lt;/strong&gt;: this is your entity-resolution layer. It tells AI that your website, your GBP, and your directory profiles are the same business. Without it, you are three fuzzy entities instead of one confident one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;areaServed&lt;/strong&gt;: be specific. Neighborhoods and towns, not just the metro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;openingHoursSpecification&lt;/strong&gt;: "open now" logic feeds real recommendation decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The three mistakes that kill you
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Schema that contradicts the visible page.&lt;/strong&gt; If your JSON-LD says "24/7 emergency service" and your homepage does not, you have trained AI to distrust everything else you publish. Markup must match visible content exactly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. NAP drift across citations.&lt;/strong&gt; Name, address, phone. If your site says "Suite 200" and three directories say "Ste. 2" and one has an old number, the entity graph fragments. Pick one canonical format and propagate it everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Organization markup on a local business.&lt;/strong&gt; A &lt;code&gt;Dentist&lt;/code&gt; that only declares &lt;code&gt;Organization&lt;/code&gt; is leaving its most important properties (geo, hours, areaServed) unclaimed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond schema: answer-ready content
&lt;/h2&gt;

&lt;p&gt;Structured data tells AI &lt;em&gt;what&lt;/em&gt; you are. Your content tells it &lt;em&gt;when to recommend you&lt;/em&gt;. The pattern that works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write pages that mirror the questions customers actually ask: "How much does emergency plumbing cost in Toronto?"&lt;/li&gt;
&lt;li&gt;Answer in the first sentence, plainly, then expand. AI extracts answer-first paragraphs.&lt;/li&gt;
&lt;li&gt;Keep facts consistent with your schema. Always.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to test any of this
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;validator.schema.org&lt;/strong&gt; for syntax&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Rich Results Test&lt;/strong&gt; for eligibility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The manual test nobody skips twice&lt;/strong&gt;: once a month, ask ChatGPT, Gemini, and Perplexity "best [your category] in [your city]" from a clean session. Log whether you appear, how you are described, and who appears instead. The descriptions AI uses will tell you exactly which of your signals it is reading.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A confession and an offer
&lt;/h2&gt;

&lt;p&gt;I got into this because I watched excellent local businesses, five-star reputations and all, stay completely invisible in AI answers while weaker competitors got named. Most of the fix is unglamorous structured-data and citation work like the above.&lt;/p&gt;

&lt;p&gt;I run &lt;a href="https://futurebloom.ai" rel="noopener noreferrer"&gt;Futurebloom&lt;/a&gt;, where we do these audits and implementations for local service businesses full time. Everything in this post is stuff you can do yourself, and I am happy to answer implementation questions in the comments, whether or not you ever become a client.&lt;/p&gt;

&lt;p&gt;What are you seeing in your own tests? Curious which industries people here are watching AI eat first.&lt;/p&gt;

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