I've implemented schema markup on dozens of law firm websites over the past few years, and the pattern is always the same: the firm's developer (or worse, their "SEO guy") has either done nothing, or slapped on some auto-generated Yoast schema that barely scratches the surface. Meanwhile, the competing firm down the street is pulling FAQ rich results, knowledge panel data, and getting cited by AI search tools -- all because they took the time to write proper JSON-LD.

This guide is the one I wish existed when I started. We'll cover every schema type that matters for law firms -- LegalService, Attorney, FAQPage, Organization, and how they all connect -- with real, production-ready JSON-LD you can adapt and deploy today.

Table of Contents

Schema Markup for Law Firms: Complete JSON-LD Guide (2026)

Why Schema Markup Matters for Law Firms in 2026

Let's be direct: schema markup won't magically rank your site. It's not a ranking factor in the traditional sense. But it does three things that compound over time:

  1. Rich results in SERPs. FAQ dropdowns, star ratings, business details -- these take up more screen real estate and boost click-through rates. Data from a 2025 Milestone Research study showed pages with structured data earned 40-50% higher CTR than those without.

  2. AI search citations. Google's AI Overviews, Bing Copilot, Perplexity, and ChatGPT search all parse structured data to understand entities. If you want your firm cited when someone asks "best personal injury lawyer in Austin," schema helps these systems understand who you are, what you do, and where you're located.

  3. Knowledge panel eligibility. Google's Knowledge Graph pulls heavily from structured data. A properly marked-up law firm with consistent sameAs links has a much better shot at triggering a branded knowledge panel.

For law firms specifically, the stakes are high. Legal keywords are some of the most expensive in paid search ($50-150+ per click for competitive practice areas). Anything you can do to improve organic visibility is worth the engineering time.

JSON-LD vs Microdata: Pick the Right Format

Short answer: use JSON-LD. Always.

Google explicitly recommends JSON-LD. It's easier to maintain, doesn't pollute your HTML markup, and can be injected dynamically via <script> tags. Microdata requires you to add attributes directly to your HTML elements, which gets messy fast -- especially if you're working with a headless CMS like Sanity, Contentful, or Storyblok where content and presentation are decoupled.

Feature JSON-LD Microdata RDFa
Google recommended ✅ Yes ⚠️ Supported ⚠️ Supported
Separate from HTML ✅ Yes ❌ No ❌ No
Easy to maintain ✅ Yes ❌ Messy ❌ Messy
Works with headless CMS ✅ Perfect fit ⚠️ Possible ⚠️ Possible
AI search compatibility ✅ Excellent ✅ Good ✅ Good
Dynamic injection ✅ Trivial ❌ Requires DOM changes ❌ Requires DOM changes

If you're building with Next.js or Astro (which we do a lot at Social Animal -- see our Next.js development and Astro development capabilities), JSON-LD is especially clean. You generate it as a JavaScript object and drop it into a <script type="application/ld+json"> tag in the <head>.

LegalService Schema: The Foundation

LegalService is the schema.org type specifically designed for law firms and legal practices. It's a subtype of LocalBusiness, which means it inherits all the local business properties -- address, phone, hours -- plus you can specify legal-specific details.

Here's a production-ready example:

{
  "@context": "https://schema.org",
  "@type": "LegalService",
  "@id": "https://www.smithlawfirm.com/#organization",
  "name": "Smith & Associates Law Firm",
  "alternateName": "Smith Law",
  "url": "https://www.smithlawfirm.com",
  "logo": {
    "@type": "ImageObject",
    "url": "https://www.smithlawfirm.com/images/logo.png",
    "width": 600,
    "height": 200
  },
  "image": "https://www.smithlawfirm.com/images/office-exterior.jpg",
  "description": "Smith & Associates provides personal injury, family law, and estate planning legal services in Austin, Texas.",
  "telephone": "+1-512-555-0199",
  "email": "contact@smithlawfirm.com",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "456 Congress Avenue, Suite 300",
    "addressLocality": "Austin",
    "addressRegion": "TX",
    "postalCode": "78701",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 30.2672,
    "longitude": -97.7431
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "18:00"
    }
  ],
  "priceRange": "$$",
  "areaServed": {
    "@type": "City",
    "name": "Austin",
    "sameAs": "https://en.wikipedia.org/wiki/Austin,_Texas"
  },
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Legal Services",
    "itemListElement": [
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Personal Injury Representation",
          "description": "Legal representation for car accidents, slip and fall, and workplace injuries."
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Family Law",
          "description": "Divorce, child custody, and prenuptial agreement services."
        }
      }
    ]
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "reviewCount": "127",
    "bestRating": "5"
  },
  "sameAs": [
    "https://www.facebook.com/SmithLawAustin",
    "https://www.linkedin.com/company/smith-law-austin",
    "https://www.avvo.com/attorneys/smith-associates.html"
  ]
}

Key Properties You Shouldn't Skip

  • @id: This is crucial for connecting schemas together. Think of it as a unique identifier that other schema blocks can reference.
  • geo: Google uses this for local pack results. Don't skip it.
  • areaServed: If you serve multiple cities or counties, list them all. Use GeoCircle for radius-based service areas.
  • hasOfferCatalog: This is how you enumerate your practice areas as services. Each practice area page should ideally have its own Service schema too.
  • sameAs: Include your Avvo, Justia, FindLaw, LinkedIn, Facebook -- any authoritative profile. This helps Google connect the dots for your knowledge panel.
  • aggregateRating: Only include this if you're pulling from legitimate first-party reviews. Google's guidelines are strict here -- don't fabricate ratings.

Schema Markup for Law Firms: Complete JSON-LD Guide (2026) - architecture

Attorney Schema with Person Markup

Each attorney at your firm should have a Person schema on their bio page. This is where E-E-A-T really kicks in -- you're explicitly telling search engines about credentials, bar admissions, education, and expertise.

{
  "@context": "https://schema.org",
  "@type": "Person",
  "@id": "https://www.smithlawfirm.com/attorneys/jane-smith/#person",
  "name": "Jane Smith",
  "jobTitle": "Managing Partner",
  "url": "https://www.smithlawfirm.com/attorneys/jane-smith",
  "image": "https://www.smithlawfirm.com/images/attorneys/jane-smith.jpg",
  "description": "Jane Smith is a personal injury attorney in Austin, TX with over 15 years of experience and a track record of $50M+ in settlements.",
  "telephone": "+1-512-555-0200",
  "email": "jane@smithlawfirm.com",
  "worksFor": {
    "@id": "https://www.smithlawfirm.com/#organization"
  },
  "alumniOf": [
    {
      "@type": "CollegeOrUniversity",
      "name": "University of Texas School of Law",
      "sameAs": "https://law.utexas.edu"
    }
  ],
  "hasCredential": [
    {
      "@type": "EducationalOccupationalCredential",
      "credentialCategory": "Bar Admission",
      "recognizedBy": {
        "@type": "Organization",
        "name": "State Bar of Texas"
      }
    }
  ],
  "knowsAbout": [
    "Personal Injury Law",
    "Car Accident Claims",
    "Wrongful Death",
    "Premises Liability"
  ],
  "sameAs": [
    "https://www.linkedin.com/in/janesmith-attorney",
    "https://www.avvo.com/attorneys/jane-smith.html",
    "https://www.martindale.com/jane-smith"
  ]
}

Why `worksFor` References Matter

See that worksFor property? It uses the @id from the LegalService schema. That's how you build a connected graph -- Google understands that Jane Smith works at Smith & Associates, which is a legal service provider in Austin. These connections strengthen both entities.

The hasCredential property is relatively new but increasingly important. Bar admissions, board certifications, Super Lawyers designations -- mark them all up. AI search systems love this kind of verifiable credential data.

FAQPage Schema for Practice Areas

FAQ schema has had a turbulent history. Google reduced FAQ rich results visibility in August 2023, limiting them primarily to authoritative government and health sites. But here's the thing -- FAQPage schema still matters in 2026 for two reasons:

  1. AI search parsing. LLMs actively consume FAQ structured data when generating answers. Perplexity and Google AI Overviews both cite FAQ content.
  2. Bing and other engines. Bing still shows FAQ rich results more liberally than Google.

For each practice area page, you should have a relevant FAQ section with matching schema:

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How much does a personal injury lawyer cost in Austin?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Most personal injury attorneys in Austin work on a contingency fee basis, meaning you pay nothing upfront. The standard contingency fee ranges from 33% to 40% of the settlement or verdict amount. If you don't win, you don't pay attorney fees."
      }
    },
    {
      "@type": "Question",
      "name": "What is the statute of limitations for personal injury in Texas?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "In Texas, you generally have two years from the date of the injury to file a personal injury lawsuit. There are exceptions for minors, government entities, and cases where the injury wasn't immediately discovered. Consulting an attorney promptly is critical to preserve your rights."
      }
    },
    {
      "@type": "Question",
      "name": "How long does a personal injury case take to settle?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Most personal injury cases in Texas settle within 6 to 18 months. Simpler cases like fender-benders with clear liability may resolve in a few months. Complex cases involving catastrophic injuries or disputed fault can take 2-3 years or longer if they go to trial."
      }
    }
  ]
}

Critical FAQPage Rules

  • The content must appear on the page. Google's guidelines are explicit: your FAQ markup must match visible content on the page. Don't add FAQ schema for questions that only exist in the JSON-LD.
  • Keep answers concise. Two to three sentences per answer performs best. If you need to explain something complex, link to a dedicated page.
  • Use real questions. Pull from Google Search Console query data, "People Also Ask" boxes, and actual client intake conversations. Don't make up questions nobody asks.
  • Limit to 5-10 per page. More than that and you're diluting relevance.

Organization Schema: Tying It All Together

If your firm has multiple offices, you'll want an Organization schema on your homepage that acts as the parent entity, with individual LegalService schemas for each location.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://www.smithlawfirm.com/#organization",
  "name": "Smith & Associates Law Firm",
  "url": "https://www.smithlawfirm.com",
  "logo": "https://www.smithlawfirm.com/images/logo.png",
  "foundingDate": "2008",
  "founder": {
    "@id": "https://www.smithlawfirm.com/attorneys/jane-smith/#person"
  },
  "numberOfEmployees": {
    "@type": "QuantitativeValue",
    "value": 25
  },
  "subOrganization": [
    {
      "@type": "LegalService",
      "name": "Smith & Associates - Austin Office",
      "url": "https://www.smithlawfirm.com/locations/austin"
    },
    {
      "@type": "LegalService",
      "name": "Smith & Associates - San Antonio Office",
      "url": "https://www.smithlawfirm.com/locations/san-antonio"
    }
  ],
  "sameAs": [
    "https://www.facebook.com/SmithLawAustin",
    "https://www.linkedin.com/company/smith-law-austin",
    "https://twitter.com/SmithLawATX"
  ]
}

Building a Connected Schema Graph

This is where most law firm websites fail. They have disconnected blobs of schema -- a bit of LocalBusiness here, a Person there -- but nothing links together. Google's documentation talks about "entity reconciliation," which is basically how it figures out that all these pieces of data refer to the same real-world entities.

The @id property is your tool for this. Here's how the graph should connect:

Page Schema Type References
Homepage Organization + WebSite @id for the org
Location pages LegalService parentOrganization → org @id
Attorney bios Person worksFor → org @id
Practice area pages Service + FAQPage provider → org @id
Blog posts Article author → person @id, publisher → org @id
Contact page ContactPoint Nested in org or LegalService

Here's a quick example of how a practice area page ties back:

{
  "@context": "https://schema.org",
  "@type": "Service",
  "name": "Personal Injury Representation",
  "serviceType": "Personal Injury Law",
  "provider": {
    "@id": "https://www.smithlawfirm.com/#organization"
  },
  "areaServed": {
    "@type": "State",
    "name": "Texas"
  },
  "description": "Legal representation for car accidents, truck accidents, workplace injuries, and wrongful death claims throughout Texas.",
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Personal Injury Services",
    "itemListElement": [
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Car Accident Claims"
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Truck Accident Claims"
        }
      }
    ]
  }
}

Where to Place JSON-LD in Your Templates

JSON-LD goes in a <script type="application/ld+json"> tag. You can place it in the <head> or just before the closing </body> tag -- Google doesn't care about placement, but I prefer <head> for organizational sanity.

If you're working with a headless CMS and a framework like Next.js or Astro, you'll want to generate the schema dynamically from your CMS data. Here's a simplified Next.js example:

// components/LegalServiceSchema.tsx
export function LegalServiceSchema({ firm }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "LegalService",
    "@id": `${firm.url}/#organization`,
    "name": firm.name,
    "url": firm.url,
    "telephone": firm.phone,
    "address": {
      "@type": "PostalAddress",
      "streetAddress": firm.address.street,
      "addressLocality": firm.address.city,
      "addressRegion": firm.address.state,
      "postalCode": firm.address.zip,
      "addressCountry": "US"
    }
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
    />
  );
}

This pattern works beautifully when your content lives in a headless CMS. The schema stays in sync with your data automatically -- no manual updates when the phone number changes. If you're interested in this approach, we build these kinds of systems regularly with our headless CMS development work.

Validation and Testing

Before you push anything live, test it. Every time. Here are the tools I actually use:

Tool URL What It Does
Google Rich Results Test search.google.com/test/rich-results Shows which rich results your page is eligible for
Schema Markup Validator validator.schema.org Validates against full schema.org spec (stricter than Google)
Google Search Console search.google.com/search-console Shows errors and warnings after deployment
Merkle Schema Markup Generator technicalseo.com/tools/schema-markup-generator Good for generating initial markup

My workflow:

  1. Write the JSON-LD manually or generate it from CMS data
  2. Validate with schema.org validator first (catches structural issues)
  3. Test with Google Rich Results Test (confirms Google will parse it)
  4. Deploy and monitor Search Console's "Enhancements" report for 2-4 weeks
  5. Check if rich results actually appear in SERPs using site:yourdomain.com searches

Common Mistakes That Kill Your Rich Results

I've debugged enough law firm schemas to have a greatest-hits list of mistakes:

Invisible markup. You add FAQ schema but the questions and answers aren't visible on the page. Google explicitly says the structured data must reflect visible page content. Violate this and you risk a manual action.

Fake or self-published reviews. Adding AggregateRating with reviews that only exist on your own website -- not pulled from Google Business Profile, Avvo, or another third party -- violates Google's review snippet guidelines. They cracked down hard on this in 2024 and it hasn't loosened.

Duplicate schemas from plugins. You install Yoast or Rank Math, which generates Organization schema automatically. Then you (or your developer) also adds custom JSON-LD. Now Google sees two conflicting Organization blocks. Pick one source of truth.

Missing @id references. Without @id properties, your schema blocks are islands. Google can't connect your attorneys to your firm, your services to your locations. Always use @id and reference it with {"@id": "..."} in related schemas.

Stale data. Your office moved six months ago but the schema still has the old address. Or an attorney left the firm but their Person schema is still live. Treat schema like code -- it needs maintenance.

Using Attorney as a schema type. This is a common confusion. Schema.org doesn't have an Attorney type. There's no @type: "Attorney". Use Person with a jobTitle of "Attorney" and connect them to your LegalService via worksFor. Some plugins get this wrong.

FAQ

What schema types should every law firm website have?

At minimum, you need LegalService (or Organization with LegalService subtypes) on your homepage, Person on each attorney bio page, and FAQPage on practice area pages. If you publish blog content, add Article schema with proper author references. For multi-location firms, each office needs its own LegalService block with location-specific details.

Does FAQPage schema still work for rich results in 2026?

Google significantly reduced FAQ rich results visibility in August 2023, primarily showing them for government and health authority sites. However, FAQ schema remains valuable for AI search systems like Google AI Overviews, Bing Copilot, and Perplexity, which actively parse structured FAQ data when generating answers. It's still worth implementing.

Is there a schema type specifically for attorneys?

No. Schema.org doesn't define an Attorney type. The correct approach is to use Person with properties like jobTitle set to "Attorney" or "Partner," hasCredential for bar admissions, and worksFor referencing your firm's LegalService or Organization schema. Some SEO plugins incorrectly use Attorney -- avoid them or override the output.

How do I handle multiple practice areas in schema markup?

Each practice area page should have its own Service schema with a provider reference back to your firm's @id. On your homepage or main services page, use a hasOfferCatalog with an OfferCatalog listing each service. This creates both individual page-level signals and a firm-level overview.

Can schema markup help my law firm appear in Google's AI Overviews?

Yes. Google's AI Overviews and other AI search tools use structured data as a signal when selecting sources for generated answers. A well-connected schema graph -- with LegalService, Person, FAQPage, and proper sameAs links -- helps AI systems understand your firm's authority, location, and specializations. It's not the only factor, but it's an increasingly important one.

Should I use a schema plugin or write JSON-LD manually?

It depends on your platform and technical comfort. For WordPress, plugins like Rank Math or Schema Pro can handle the basics. But for law firms, the defaults are rarely sufficient -- you'll need to customize the output for LegalService, attorney credentials, and practice area services. If you're on a headless CMS with Next.js or Astro, generating JSON-LD programmatically from your CMS data is the cleanest approach. We help firms set this up through our headless CMS development services.

How long does it take for schema markup to show results?

After deploying valid structured data, Google typically processes it within 2-4 weeks, though it can take longer. You'll see schema detected in Search Console's Enhancements report first. Rich results (if eligible) may take another few weeks to appear. AI search citation improvements are harder to measure and may take 1-3 months to become noticeable.

What's the relationship between schema markup and E-E-A-T?

Schema markup is one of the most direct ways to signal E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness) to search engines. Person schemas with hasCredential demonstrate expertise. AggregateRating and Review schemas signal trustworthiness. sameAs links to authoritative legal directories reinforce authority. Google's quality rater guidelines don't mention schema explicitly, but the data you encode maps directly to what quality raters evaluate.