A 4,500-word, copy-paste-ready guide to schema markup for Canadian businesses in 2026. Production JSON-LD blocks for the 8 schema types that actually matter, validation workflow, and the specific Canadian gotchas (province codes, bilingual content, NAP consistency).
Schema.org defines hundreds of types. In 2026, fewer than a dozen consistently produce measurable SEO impact for Canadian businesses. This guide focuses on those.
**The eight schema types worth implementing:**
1. **LocalBusiness** (and subtypes) — for any business with a physical location or service area 2. **Organization** — for the publishing entity behind the website 3. **Service** — for service-based businesses, per service offering 4. **Product** — for physical or digital products with pricing 5. **Article** — for blog posts, guides, and editorial content 6. **FAQPage** — for genuine FAQ content (visible on the page) 7. **BreadcrumbList** — for navigation hierarchy 8. **Person/Author** — for E-E-A-T signal on authored content
**Schema types that no longer move the needle in 2026:**
- **HowTo schema** — Google removed rich snippet treatment in late 2023; still parses but minimal benefit - **Recipe schema** — only relevant for food/cooking sites - **Event schema** — only relevant if you actually host events with dates - **JobPosting schema** — only relevant for ATS-integrated career pages - **Generic Thing or WebPage** — no signal value; use specific types
**The Canadian-specific gotchas:**
- **Province codes:** use the two-letter Canadian province codes (ON, QC, BC, AB, etc.) in addressRegion. Don't use full province names ("Ontario") or US state codes. - **Postal codes:** include them with the standard A1A 1A1 format (with the space). - **Country code:** "CA" in addressCountry. - **Currency:** "CAD" for any priceCurrency property. - **Bilingual content:** if you serve French and English markets, build separate schema blocks per language version of the page (don't try to mix languages in one schema).
LocalBusiness schema (and its subtypes) is the most-impactful schema for service businesses, retailers, restaurants, and any business with a physical location or defined service area.
**The recommended structure for a single-location Canadian business:**
{ "@context": "https://schema.org", "@type": "LocalBusiness", "@id": "https://yoursite.ca/#business", "name": "Your Business Name", "image": [ "https://yoursite.ca/images/storefront-1x1.jpg", "https://yoursite.ca/images/storefront-4x3.jpg", "https://yoursite.ca/images/storefront-16x9.jpg" ], "logo": "https://yoursite.ca/logo.png", "url": "https://yoursite.ca", "telephone": "+1-613-555-0123", "email": "hello@yoursite.ca", "address": { "@type": "PostalAddress", "streetAddress": "123 Bank Street", "addressLocality": "Ottawa", "addressRegion": "ON", "postalCode": "K1P 5N7", "addressCountry": "CA" }, "geo": { "@type": "GeoCoordinates", "latitude": 45.4215, "longitude": -75.6972 }, "openingHoursSpecification": [ { "@type": "OpeningHoursSpecification", "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], "opens": "09:00", "closes": "17:00" }, { "@type": "OpeningHoursSpecification", "dayOfWeek": "Saturday", "opens": "10:00", "closes": "14:00" } ], "priceRange": "$$", "sameAs": [ "https://www.facebook.com/yourbusiness", "https://www.linkedin.com/company/yourbusiness", "https://www.instagram.com/yourbusiness", "https://g.page/yourbusiness" ], "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.8", "reviewCount": "127" } }
**Notes on critical properties:**
- **`@id`** — globally unique URI for this entity. Use the URL with a fragment identifier (e.g., `#business`). Lets you reference this same entity from other schema blocks across your site. - **`name`** — exactly matching your Google Business Profile name and Canadian business registration. NAP consistency starts here. - **`address`** — every property required. Province as 2-letter code. Postal code with space. - **`geo`** — latitude and longitude help Google place you on Maps. Get coordinates from Google Maps (right-click your address → coordinates appear). - **`telephone`** — E.164 format: +1-613-555-0123. The +1 country code is required. - **`sameAs`** — only profiles you actually own and that link back to your domain. - **`aggregateRating`** — only if reviews are visible on the page (see Service schema section for review rules).
**LocalBusiness subtypes — use the most specific type:**
Schema.org has dozens of LocalBusiness subtypes. Use the most specific one that matches your business:
- **Dentist, Physician, MedicalBusiness** for healthcare - **AttorneyOffice, LegalService** for legal - **Plumber, HVACBusiness, Electrician, RoofingContractor** for trades - **Restaurant, FastFoodRestaurant, CafeOrCoffeeShop** for food service - **AutoRepair, AutoBodyShop** for automotive - **AccountingService, FinancialService** for accounting/finance - **RealEstateAgent** for realtors - **HomeAndConstructionBusiness** for general contractors
Full list: schema.org/LocalBusiness > More specific Types.
Using a more specific type provides stronger semantic signal than the generic LocalBusiness.
**Multi-location businesses:**
For businesses with 3+ locations, build separate LocalBusiness schema blocks per location, each with its own `@id`. List all locations on a /locations/ page with internal links to per-location pages, each having that location's specific LocalBusiness schema.
**Service-area businesses without storefront:**
Use `areaServed` instead of (or in addition to) a fixed address:
"areaServed": [ {"@type": "City", "name": "Ottawa"}, {"@type": "City", "name": "Kanata"}, {"@type": "City", "name": "Nepean"}, {"@type": "City", "name": "Orléans"} ]
For SAB on GBP, also include `hasMap` linking to your GBP listing.
Service schema is the right type for individual service offerings. It's distinct from Product schema (designed for physical/digital goods) and works alongside LocalBusiness schema (which describes the business as a whole).
**Per-service-page Service schema:**
{ "@context": "https://schema.org", "@type": "Service", "@id": "https://yoursite.ca/services/drain-cleaning/#service", "name": "Drain Cleaning", "description": "Professional drain cleaning services in Ottawa and surrounding areas. Same-day service for clogged sinks, tubs, toilets, and main drains.", "serviceType": "Plumbing services", "provider": { "@id": "https://yoursite.ca/#business" }, "areaServed": [ {"@type": "City", "name": "Ottawa", "containedInPlace": {"@type": "AdministrativeArea", "name": "Ontario"}}, {"@type": "City", "name": "Kanata"}, {"@type": "City", "name": "Nepean"}, {"@type": "City", "name": "Orléans"} ], "offers": { "@type": "Offer", "priceSpecification": { "@type": "PriceSpecification", "price": "150-400", "priceCurrency": "CAD", "valueAddedTaxIncluded": false } }, "hasOfferCatalog": { "@type": "OfferCatalog", "name": "Drain Cleaning Services", "itemListElement": [ { "@type": "Offer", "itemOffered": {"@type": "Service", "name": "Standard drain cleaning"}, "price": "150", "priceCurrency": "CAD" }, { "@type": "Offer", "itemOffered": {"@type": "Service", "name": "Main drain hydro-jetting"}, "price": "350", "priceCurrency": "CAD" }, { "@type": "Offer", "itemOffered": {"@type": "Service", "name": "Camera inspection"}, "price": "200", "priceCurrency": "CAD" } ] } }
**Notes:**
- **`provider`** uses `@id` referencing the LocalBusiness schema on your homepage. This creates a graph: "this Service is provided by that LocalBusiness." Stronger signal than redefining business properties on every service page. - **`offers` vs. `hasOfferCatalog`:** use `offers` (single Offer) for one-price services. Use `hasOfferCatalog` (multiple Offers) for tiered or packaged services. - **Pricing:** include real prices, ranges, or "starting at" prices. Don't fabricate. If pricing varies wildly by job, use a price range in `priceSpecification` (e.g., "150-400") and skip individual Offers. - **`valueAddedTaxIncluded`** — for Canadian pricing, almost always `false` (prices typically shown pre-tax for B2B and trades; pre-GST/HST for consumer services).
**Common mistakes to avoid:**
- **Using Product schema for services.** Schema.org tolerates this but doesn't reward it. Use Service. - **Defining the full business in every service page schema.** Use `@id` references instead. - **Listing every city in your province as `areaServed`.** Read as spam. List the cities you genuinely serve. - **Inflating Offer count by listing every micro-variation as a separate Offer.** Group similar offerings.
Article schema is required for any editorial content if you want a fair shot at AI Overview citations and rich result eligibility.
**Standard Article schema for blog posts and guides:**
{ "@context": "https://schema.org", "@type": "Article", "headline": "The Article Title (Under 110 Characters)", "description": "A 150-200 character meta description summarizing the article.", "image": [ "https://yoursite.ca/articles/featured-1x1.jpg", "https://yoursite.ca/articles/featured-4x3.jpg", "https://yoursite.ca/articles/featured-16x9.jpg" ], "datePublished": "2026-04-22T08:00:00-04:00", "dateModified": "2026-04-22T08:00:00-04:00", "author": { "@type": "Person", "name": "Martin Vassilev", "url": "https://yoursite.ca/about/", "jobTitle": "Founder & Lead Strategist", "worksFor": {"@type": "Organization", "name": "Ottawa SEO Inc."}, "sameAs": [ "https://www.linkedin.com/in/martinvassilev/", "https://twitter.com/martinvassilev" ] }, "publisher": { "@type": "Organization", "name": "Ottawa SEO Inc.", "logo": { "@type": "ImageObject", "url": "https://yoursite.ca/logo.png", "width": 600, "height": 60 } }, "mainEntityOfPage": { "@type": "WebPage", "@id": "https://yoursite.ca/blog/article-slug/" } }
**Required vs. optional properties:**
Required for rich result eligibility: - `headline`, `image`, `datePublished`, `author`, `publisher`
Strongly recommended: - `dateModified`, `description`, `mainEntityOfPage`
Optional but valuable: - `articleSection`, `articleBody`, `wordCount`, `keywords`
- **`headline` under 110 characters.** Longer titles get truncated. - **`image` should provide multiple aspect ratios** — 1:1, 4:3, 16:9 — each at minimum 1200px wide. Helps Google select appropriate image for different SERP layouts. - **`datePublished` and `dateModified` in ISO 8601** with timezone (e.g., `-04:00` for Ottawa/Toronto, `-05:00` for Winnipeg, `-07:00` for Vancouver, accounting for daylight saving). - **`author` as Person** (not Organization) for E-E-A-T benefit. - **`publisher` logo at minimum 600px wide** and rectangular (Google's spec).
**When to use NewsArticle vs. BlogPosting vs. Article:**
- **Article** — universal default, always works - **NewsArticle** — only if you're a recognized news publisher with Google News eligibility - **BlogPosting** — fine for blog content; no functional difference from Article
Use Article for nearly everything. Don't use NewsArticle hoping to "get into Top Stories" — Top Stories requires Google News Publisher Center approval.
Google removed FAQ rich snippet treatment from most sites in August 2023. The schema still parses and provides AI Overview citation lift, but the visual rich snippet rarely triggers anymore for non-government / non-health sites.
**Implement FAQ schema only when:**
1. The FAQs are genuinely useful (not invented to capture related search queries) 2. They're visible to users on the page (not hidden in JavaScript-only collapse states) 3. You have 3–8 questions per page (not 20) 4. Each answer is under 200 words
**Standard FAQ schema:**
{ "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "How long does SEO take to work?", "acceptedAnswer": { "@type": "Answer", "text": "SEO typically produces first leads from organic search within 4-10 weeks for new sites with low-competition keywords. Stable top-3 rankings for competitive head terms take 6-18 months depending on domain age, content velocity, and competition density." } }, { "@type": "Question", "name": "How much does SEO cost in Canada?", "acceptedAnswer": { "@type": "Answer", "text": "Most Canadian small businesses pay $1,500-$4,500 CAD/month for retainer SEO services. Mid-market businesses pay $4,500-$12,000/month. Enterprise / competitive verticals pay $12,000-$60,000+/month." } } ] }
**Common mistakes:**
- Marking up FAQs with answers stuffed full of keywords for the sake of capturing related search queries - Hiding FAQ content behind JavaScript that doesn't render server-side - Including 20+ questions on one page (read as spam) - Marking up the same FAQs on every page across the site (duplicate signal noise)
**Where FAQ schema delivers measurable value in 2026:**
- AI Overview citations — pages with FAQ schema cited ~25-35% more often than equivalent pages without - People Also Ask box inclusions - Voice search results (Google Assistant) - Bing rich snippets (still display more liberally than Google)
Schema markup is fragile — broken JSON, malformed properties, or contradictions between schema blocks all silently kill the benefit. Build a validation workflow into every schema deployment.
**Step 1: validate during development**
Before deploying any schema change:
- **Schema.org Validator** (validator.schema.org) — checks pure schema correctness against the spec - **Google Rich Results Test** (search.google.com/test/rich-results) — checks if Google can parse and what rich result eligibility you have - **JSON-LD Playground** (json-ld.org/playground) — useful for debugging complex graph relationships with @id references
Fix any errors before deployment. Warnings are usually safe to ignore but worth understanding.
**Step 2: validate after deployment**
Within 24 hours of deploying schema changes:
- **Re-test the live URL** in Rich Results Test - **Check Search Console > Enhancements** — Google reports schema parsing issues here within 24-72 hours - **Spot-check competing schema parsers** by inspecting the rendered page source for unexpected duplicates
**Step 3: monitor over time**
Monthly:
- Search Console > Enhancements > [each rich result type] — check for parse error increases - Test 3-5 key page templates per month with Rich Results Test (templates can break after CMS or theme updates) - Review which pages are showing in rich snippets via Search Console > Performance (filter by Search Appearance)
**Step 4: build schema generation into your CMS, not as static JSON**
The most-common cause of stale or wrong schema is hand-coded JSON that doesn't update when content updates:
- Product price changes in CMS but schema still shows old price - Article `dateModified` never gets bumped - LocalBusiness hours change but schema still shows old hours
Generate schema dynamically from your CMS data, not from hand-coded JSON. WordPress sites: Yoast or RankMath handle most cases. Headless CMS / custom builds: build schema generation into your templating layer with the same data source as visible content.
**Step 5: don't over-implement**
More schema isn't better. The minimum effective schema set for most Canadian businesses:
- Homepage: Organization OR LocalBusiness - Service pages: Service (with @id reference back to LocalBusiness) - Blog posts: Article + Author - Pages with FAQs: FAQPage - Site-wide: BreadcrumbList
Adding Product schema to service pages, HowTo schema to non-procedural content, or Recipe schema to non-food pages adds parser complexity without benefit. Stick to the schema types that match your content.
If you've worked through this guide and implemented the appropriate schemas, you're ahead of 80% of Canadian small business websites. Common next-step questions:
**"Do I need to do this myself or hire someone?"**
For most CMS-based sites (WordPress, Shopify, Webflow), an SEO plugin (Yoast, RankMath, Schema Pro) implements 80% of what you need. The remaining 20% (custom Service schemas, multi-location LocalBusiness, advanced @id graph relationships) usually requires a developer or specialist familiar with structured data.
**"How do I check what schema my competitors are using?"**
View source on a competitor page and search for `application/ld+json`. Or use Schema App's free Schema Markup Detector browser extension.
**"Should I use multiple schemas on one page?"**
Yes — most pages legitimately have multiple schemas (BreadcrumbList + Article + Author, or LocalBusiness + Service + AggregateRating). Just make sure they don't contradict each other and use `@id` references rather than duplicating entity definitions.
**Other resources:**
- How long does SEO take in Canada? — answer to a common follow-up question - Schema markup Q&A collection — focused answers on common schema implementation questions - The Canadian SEO Pricing Guide 2026 — what implementing this kind of work actually costs - Contact us — if you'd like a schema audit or implementation help
LocalBusiness (or its specific subtype like Dentist, Restaurant, Plumber) on the homepage and contact page, plus Service schema on each service page. These two together establish your business entity and what you offer.
Schema isn't a direct ranking factor. It enables rich snippets, helps with AI Overview citation eligibility, and provides clear semantic signal that helps Google understand your content. The downstream effect on rankings is positive but indirect.
JSON-LD. Google has explicitly preferred JSON-LD since 2017. Microdata still parses but adds maintenance burden without benefit.
Yes, but expect the rich snippet treatment to rarely trigger for non-authoritative sites (Google restricted it in August 2023). FAQ schema still helps with AI Overview citations and People Also Ask inclusions, so it remains worth implementing on pages with genuine FAQs.
Use Google's Rich Results Test (search.google.com/test/rich-results) immediately after deployment, then check Search Console > Enhancements over the following weeks for any errors Google detects in production.
Use a plugin or CMS feature for the standard schemas (Yoast, RankMath, Schema Pro on WordPress; Shopify's built-in schema; Webflow's CMS bindings). Hand-code only for advanced use cases like multi-location LocalBusiness graphs or custom Service hierarchies.