<?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: Sourci</title>
    <description>The latest articles on DEV Community by Sourci (@getsourci).</description>
    <link>https://dev.to/getsourci</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%2F4236076%2Fbe82cb1b-e0a3-4814-8f91-4ec58c88130c.png</url>
      <title>DEV Community: Sourci</title>
      <link>https://dev.to/getsourci</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/getsourci"/>
    <language>en</language>
    <item>
      <title>JSON-LD for Contractor Websites: Schema Markup That Makes Service Pages Machine-Readable</title>
      <dc:creator>Sourci</dc:creator>
      <pubDate>Wed, 11 Nov 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/getsourci/json-ld-for-contractor-websites-schema-markup-that-makes-service-pages-machine-readable-4dch</link>
      <guid>https://dev.to/getsourci/json-ld-for-contractor-websites-schema-markup-that-makes-service-pages-machine-readable-4dch</guid>
      <description>&lt;p&gt;If you build or maintain websites for trades businesses, such as painters, roofers or flooring installers, you'll get asked to "do the SEO stuff," and these days to "make us show up in ChatGPT." Structured data is one of the few parts of that request that's concrete, testable and fully under your control.&lt;/p&gt;

&lt;p&gt;This post is a practical reference: which schema.org types fit contractors, a working JSON-LD pattern for a company with several service pages, what to do when the business doesn't publish a street address, and what structured data will and won't do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bother? What do AI engines actually read on contractor sites?
&lt;/h2&gt;

&lt;p&gt;On November 8, 2026, the Sourci team asked ChatGPT and Gemini to shortlist commercial painting, commercial roofing and epoxy floor contractors in 50 US metros, 300 answers in all. Contractor websites were the largest single category of cited sources for both engines: 58% of ChatGPT's 2,914 citations and 76% of Gemini's 638. ChatGPT cited the recommended contractor's own site in 89% of its recommendations, usually a service page for the exact trade asked about (&lt;a href="https://getsourci.com/research/ai-contractor-recommendations" rel="noopener noreferrer"&gt;full method and data&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;That study measured citations, not markup. It doesn't show that JSON-LD causes recommendations, and we won't claim it does. What it does show is that the service page itself is the evidence. Structured data is the cheapest way to make that page's key facts unambiguous to any parser: who the business is, what it does, and where.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which schema.org type should a contractor use?
&lt;/h2&gt;

&lt;p&gt;Schema.org has a &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt; type, a &lt;code&gt;LocalBusiness&lt;/code&gt; described as one "that provides services around homes and buildings." Its subtypes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RoofingContractor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HousePainter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GeneralContractor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Electrician&lt;/code&gt;, &lt;code&gt;Plumber&lt;/code&gt;, &lt;code&gt;HVACBusiness&lt;/code&gt;, &lt;code&gt;Locksmith&lt;/code&gt;, &lt;code&gt;MovingCompany&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's no dedicated flooring or coatings contractor type. For an epoxy or resinous flooring company, use &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt; and describe the specialty with &lt;code&gt;Service&lt;/code&gt; entries and &lt;code&gt;knowsAbout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Google's local business documentation says to "use the most specific LocalBusiness sub-type possible," and if a business has several types, to list them as an array because &lt;code&gt;additionalType&lt;/code&gt; isn't supported. A company that paints and roofs would use:&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"HousePainter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"RoofingContractor"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HousePainter&lt;/code&gt; is schema.org's name for painting businesses generally. It still fits a company that only does commercial work. Your page copy carries the "commercial" signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you mark up a contractor with multiple service pages?
&lt;/h2&gt;

&lt;p&gt;Define the business once, with a stable &lt;code&gt;@id&lt;/code&gt;, and reference it from each service page. Don't repeat a full &lt;code&gt;LocalBusiness&lt;/code&gt; block on every page. Use an &lt;code&gt;@graph&lt;/code&gt; on the homepage or about page:&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="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&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="nl"&gt;"@graph"&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"RoofingContractor"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://example-roofing.com/#business"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Example Roofing Co."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://example-roofing.com/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"logo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://example-roofing.com/logo.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"telephone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"+1-512-555-0100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"areaServed"&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"City"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Austin, TX"&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"City"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Round Rock, TX"&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="nl"&gt;"knowsAbout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"TPO roofing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"modified bitumen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"commercial roof inspections"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;"sameAs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"https://www.bbb.org/us/tx/austin/profile/roofing-contractors/example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"https://www.facebook.com/exampleroofing"&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;Then on &lt;code&gt;/commercial-roof-inspections&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="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://example-roofing.com/commercial-roof-inspections#service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Commercial roof inspections"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"serviceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Roof inspection"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://example-roofing.com/#business"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"areaServed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"City"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Austin, TX"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"audience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"BusinessAudience"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;"audienceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Property managers and facility managers"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Twice-yearly and post-storm inspections for low-slope commercial roofs, with photo documentation and a written repair list."&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few notes from real implementations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sameAs&lt;/code&gt; is where directory profiles go.&lt;/strong&gt; In the study, ChatGPT cited directory or review sites in 85% of answers. BBB and Angi were in both engines' top-four third-party sources. Linking the company's real BBB, Angi or manufacturer-directory profile with &lt;code&gt;sameAs&lt;/code&gt; ties them to one entity. Only list profiles the business actually controls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;areaServed&lt;/code&gt; takes names, not just a radius.&lt;/strong&gt; &lt;code&gt;GeoCircle&lt;/code&gt; is valid, but a list of real cities matches how buyers phrase questions ("roofers in Round Rock").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep &lt;code&gt;name&lt;/code&gt; identical everywhere.&lt;/strong&gt; It should match the business name on Google Business Profile and directories character for character. Entity matching breaks on "Example Roofing" vs "Example Roofing &amp;amp; Restoration LLC."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What if the business doesn't publish a street address?
&lt;/h2&gt;

&lt;p&gt;Many trades companies are service-area businesses that run from a home office or yard and don't want an address public. That collides with one of Google's rules. In Google's local business structured data documentation, &lt;code&gt;address&lt;/code&gt; is a &lt;em&gt;required&lt;/em&gt; property for Local Business rich results.&lt;/p&gt;

&lt;p&gt;Your options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;PostalAddress&lt;/code&gt; with only locality, region and country&lt;/strong&gt; (&lt;code&gt;addressLocality&lt;/code&gt;, &lt;code&gt;addressRegion&lt;/code&gt;, &lt;code&gt;addressCountry&lt;/code&gt;). It's valid schema.org, but it may not qualify for rich results. Treat it as descriptive markup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;Organization&lt;/code&gt; plus &lt;code&gt;Service&lt;/code&gt; markup&lt;/strong&gt; with &lt;code&gt;areaServed&lt;/code&gt;, and leave the location details to Google Business Profile, where service-area businesses can hide their address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don't invent an address, and don't use a virtual office you don't operate from. Google's structured data guidelines warn that markup that misrepresents content can lead to a manual action, which means the markup gets ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should contractor sites still use FAQPage markup?
&lt;/h2&gt;

&lt;p&gt;Not for Google rich results. In August 2023, Google limited FAQ rich results to well-known, authoritative government and health sites. Its Search Central changelog then says the FAQ rich result stopped appearing in Google Search on May 7, 2026, and the documentation was removed in June 2026. The FAQ &lt;em&gt;content&lt;/em&gt; is still worth having. Direct question-and-answer blocks ("Do you work on occupied buildings?" "What roof systems do you install?") are easy for any engine to quote. Keep the markup if it's already there, since it's valid schema. Just don't sell it to a client as a ranking feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you test it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rich Results Test&lt;/strong&gt; (Google): checks eligibility for Google features and flags errors in supported types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema Markup Validator&lt;/strong&gt; (validator.schema.org): checks general schema.org validity, including types Google doesn't use for rich results, such as &lt;code&gt;Service&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL Inspection in Search Console&lt;/strong&gt;: confirms Google can crawl the rendered page. This matters if JSON-LD is injected client-side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you generate JSON-LD in JavaScript, render it server-side or at build time where you can. Google can process JavaScript-injected structured data, but not every crawler that feeds an AI answer renders JavaScript, and a static &lt;code&gt;&amp;lt;script type="application/ld+json"&amp;gt;&lt;/code&gt; removes the question.&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist for contractor schema
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Most specific type (&lt;code&gt;RoofingContractor&lt;/code&gt;, &lt;code&gt;HousePainter&lt;/code&gt;, or &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt; for flooring)&lt;/li&gt;
&lt;li&gt;[ ] One business entity with a stable &lt;code&gt;@id&lt;/code&gt;, referenced from service pages&lt;/li&gt;
&lt;li&gt;[ ] A &lt;code&gt;Service&lt;/code&gt; block on each service page, with &lt;code&gt;provider&lt;/code&gt;, &lt;code&gt;areaServed&lt;/code&gt; and a plain-language &lt;code&gt;description&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;sameAs&lt;/code&gt; limited to real, controlled profiles&lt;/li&gt;
&lt;li&gt;[ ] Name, phone and service area identical to Google Business Profile&lt;/li&gt;
&lt;li&gt;[ ] No invented addresses or self-serving review markup&lt;/li&gt;
&lt;li&gt;[ ] Validated in both the Rich Results Test and the Schema Markup Validator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Markup only helps if there's a real page underneath it. If your client sells &lt;a href="https://getsourci.com/commercial-roofing" rel="noopener noreferrer"&gt;commercial roofing&lt;/a&gt; but their site has one generic "Services" page, the first job is writing the page, then marking it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is there a schema.org type for epoxy flooring contractors?&lt;/strong&gt;&lt;br&gt;
No. Use &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt; with &lt;code&gt;Service&lt;/code&gt; entries describing the flooring systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does structured data make ChatGPT recommend a business?&lt;/strong&gt;&lt;br&gt;
There's no published evidence that it does on its own. What the 50-metro study shows is that the contractor's own service page is the most-cited source. Structured data makes that page's facts unambiguous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I list several trades in one @type?&lt;/strong&gt;&lt;br&gt;
Yes. Google's documentation says to use an array, for example &lt;code&gt;["HousePainter", "RoofingContractor"]&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by The Sourci team. Sourci builds websites, SEO and AI-search visibility for commercial painting, roofing and coatings contractors.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sources: Google Search Central, Local business structured data documentation; Google Search Central Blog, "Changes to HowTo and FAQ rich results" (Aug 8, 2023); Google Search Central documentation changelog (May and June 2026 entries); schema.org HomeAndConstructionBusiness; Sourci 50-metro AI contractor recommendations study, November 2026.&lt;/em&gt;&lt;/p&gt;

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