Schema Markup
Structured data tells Google exactly what a page is about. It powers rich results (star ratings, FAQ accordions, breadcrumbs).
Global schema (every page)
Section titled “Global schema (every page)”LocalBusiness + ProfessionalService in Layout.astro. See Global Layout & SEO for the full template.
Key types to set correctly:
"@type": ["LocalBusiness", "ProfessionalService"]// or for a restaurant:"@type": ["LocalBusiness", "Restaurant"]// or for a travel agency:"@type": ["LocalBusiness", "TravelAgency"]Full type list - pick the most specific subtype available.
FAQPage (homepage)
Section titled “FAQPage (homepage)”Enables Google’s FAQ accordion in search results. Requires 5+ questions.
const faqSchema = { "@context": "https://schema.org", "@type": "FAQPage", mainEntity: [ { "@type": "Question", name: "How long does a website take?", acceptedAnswer: { "@type": "Answer", text: "Most projects go live within 10-14 days of receiving all content.", }, }, // ... 4+ more ],};Pass via the head slot:
<script slot="head" is:inline type="application/ld+json" set:html={JSON.stringify(faqSchema)} />AggregateRating
Section titled “AggregateRating”Already in the global LocalBusiness schema. Must use real numbers:
aggregateRating: { "@type": "AggregateRating", ratingValue: "4.9", // actual average reviewCount: "38", // actual count bestRating: "5", worstRating: "1",}Blog posts - FAQPage schema via frontmatter
Section titled “Blog posts - FAQPage schema via frontmatter”Add a faqs array to a post’s frontmatter and the [slug].astro template injects FAQPage JSON-LD automatically. This enables Google FAQ accordion rich results on individual blog posts.
Frontmatter:
faqs: - q: How long does a website take to build? a: Most projects go live within 10-14 days of receiving all content. - q: What does it cost? a: Starting from ₹15,000 for a basic business website.In [slug].astro:
const faqs = post.data.faqs ?? [];const faqSchema = faqs.length ? { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faqs.map((f: { q: string; a: string }) => ({ '@type': 'Question', name: f.q, acceptedAnswer: { '@type': 'Answer', text: f.a }, })),} : null;{faqSchema && <script slot="head" is:inline type="application/ld+json" set:html={JSON.stringify(faqSchema)} />}Aim for 4-6 questions per post. Validate at Google’s Rich Results Test.
Blog posts - Article schema
Section titled “Blog posts - Article schema”Add to individual blog post pages:
const articleSchema = { "@context": "https://schema.org", "@type": "Article", headline: post.data.title, description: post.data.description, datePublished: post.data.pubDate.toISOString(), author: { "@type": "Organization", name: "Juju Alpha", url: "https://jujualpha.in", },};Validate schema
Section titled “Validate schema”Use Google’s Rich Results Test after deploying to confirm the schema is valid and eligible for rich results.
Common validation errors:
aggregateRating.reviewCountmust be a number (not a string in some validators - test both)telephonemust include country code:+91XXXXXXXXXXurlmust be the full production URL withhttps://