cd /news/structured-data/structured-data-in-2025-schema-marku… · home › topics › structured-data › article
[ARTICLE · art-141375] src=dev.to ↗ pub= topic=structured-data verified=true sentiment=· neutral

Structured Data in 2025: Schema Markup That Actually Wins Rich Results (With Real Laravel Examples)

A developer has published a guide arguing that valid JSON-LD is no longer sufficient for rich results in 2025, since Google's crawlers and AI-driven search summaries weigh recommended schema properties and on-page content matching more heavily than basic validation. The writeup covers BlogPosting, FAQPage, and Product/Offer/AggregateRating markup, and demonstrates generating structured data programmatically in Laravel via a dedicated SchemaBuilder service class.

by read5 min views1 publishedSep 29, 2026

Structured data is one of those topics that developers treat as an afterthought — slap some JSON-LD on the page, validate it in Rich Results Test, and call it done. That approach worked fine in 2019. In 2025, Google's crawlers are more selective, AI-driven search summaries are pulling from schema directly, and the gap between "valid" markup and "ranking" markup has never been wider.

This article is about closing that gap. We'll look at which schema types actually drive measurable SERP features, common implementation mistakes that silently kill eligibility, and how to generate and validate structured data programmatically in a Laravel application.

The common failure mode isn't invalid JSON-LD — validators catch that. The real problem is incomplete or contextually weak schema. Google's documentation is explicit: required properties get you eligibility; recommended properties get you prominence. Most developers stop at required.

Take Article schema. The minimum spec asks for headline, image, and datePublished. But if you want your article appearing in Top Stories or Google Discover, you also need author with a valid Person entity, publisher with a logo that meets dimension specs, and dateModified to signal freshness. Omitting those doesn't break validation — it just quietly removes you from contention.

Another silent killer: schema that doesn't match the visible page content. Google cross-references your markup against what users actually see. A Product schema with a price that doesn't appear in the rendered HTML — or a Review aggregate that differs from the on-page star display — will get ignored or, worse, flagged as manipulative.

Article / BlogPosting Essential for content-heavy sites. Use BlogPosting (a subtype of Article) for blog content; it signals intent to crawlers. Key recommended properties you shouldn't skip:

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Your Post Title Here",
  "image": [
    "https://example.com/photos/1x1/photo.jpg",
    "https://example.com/photos/4x3/photo.jpg",
    "https://example.com/photos/16x9/photo.jpg"
  ],
  "datePublished": "2025-01-15T08:00:00+04:00",
  "dateModified": "2025-06-10T09:20:00+04:00",
  "author": {
    "@type": "Person",
    "name": "Your Name",
    "url": "https://example.com/authors/your-name"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Your Brand",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png",
      "width": 600,
      "height": 60
    }
  },
  "description": "A concise summary that matches your meta description."
}

Note the three image aspect ratios. Google recommends providing all three (1:1, 4:3, 16:9) so the crawler can select the most appropriate one per context.

FAQPage FAQ schema still earns expandable rich results in desktop SERPs and is increasingly used by AI Overviews to surface direct answers. The catch: questions and answers must be verbatim visible on the page. Don't generate FAQ schema from a database if the content isn't rendered in HTML.

Product with Offer and AggregateRating For e-commerce, completeness here is commercially significant. An Offer without availability or priceCurrency gets deprioritised for Shopping graph features. AggregateRating requires both ratingValue and reviewCount — and both must reflect actual visible content.

Hard-coding JSON-LD in Blade templates is fine for static pages but doesn't scale. Here's a clean approach using a dedicated service class.

<?php

namespace App\Services\Seo;

class SchemaBuilder
{
    public function blogPosting(array $data): string
    {
        $schema = [
            '@context' => 'https://schema.org',
            '@type'    => 'BlogPosting',
            'headline' => $data['title'],
            'image'    => $data['images'] ?? [],
            'datePublished' => $data['published_at']->toIso8601String(),
            'dateModified'  => $data['updated_at']->toIso8601String(),
            'author' => [
                '@type' => 'Person',
                'name'  => $data['author_name'],
                'url'   => $data['author_url'],
            ],
            'publisher' => [
                '@type' => 'Organization',
                'name'  => config('app.name'),
                'logo'  => [
                    '@type'  => 'ImageObject',
                    'url'    => asset('images/logo-schema.png'),
                    'width'  => 600,
                    'height' => 60,
                ],
            ],
            'description' => $data['excerpt'],
        ];

        return json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
    }

    public function faqPage(array $questions): string
    {
        $schema = [
            '@context'   => 'https://schema.org',
            '@type'      => 'FAQPage',
            'mainEntity' => array_map(fn($q) => [
                '@type'          => 'Question',
                'name'           => $q['question'],
                'acceptedAnswer' => [
                    '@type' => 'Answer',
                    'text'  => $q['answer'],
                ],
            ], $questions),
        ];

        return json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
    }
}

In your Blade layout:

@stack('schema')

And in specific page views:

@push('schema')
<script type="application/ld+json">
{!! $schemaBuilder->blogPosting($post->toSchemaArray()) !!}
</script>
@endpush

This keeps schema generation testable, reusable, and away from your view layer logic. You can write unit tests against SchemaBuilder methods and assert that required keys are always present before anything hits production.

The Rich Results Test tells you if your schema is valid. It doesn't tell you if you're eligible. Use it, but don't stop there.

Search Console's Rich Results report is the ground truth. It shows actual impressions and clicks from rich results, and — critically — it surfaces warnings that the Rich Results Test misses, like schema detected on pages with thin content or low crawl priority.

Schema Markup Validator (validator.schema.org) runs a stricter conformance check than Google's tool and often catches type mismatches.

Screaming Frog's structured data extraction lets you audit schema across your entire site at once — invaluable when you have hundreds of product or blog pages and need to verify consistency programmatically.

For teams building content-heavy applications, automated schema auditing should be part of your CI/CD pipeline, not a quarterly manual task. Parsing rendered HTML with something like symfony/dom-crawler and asserting schema presence on key page types is straightforward to implement.

One underappreciated dimension: schema isn't just about individual pages. Google builds an entity graph, and your markup contributes to it. Consistent use of sameAs properties — pointing author entities to verified profiles like LinkedIn or Wikipedia, and organisation entities to Wikidata or Crunchbase — strengthens entity disambiguation and can improve how your content is attributed in AI-generated summaries.

This is an area that the team at HanzWeb writes about in depth — particularly how entity signals interact with local SEO for businesses operating in competitive markets like the UAE.

Structured data done right is an investment in discoverability infrastructure — not just a checkbox. The implementation effort is low; the discipline to keep it accurate, complete, and content-matched is where most projects fall short. Start with a schema service class, write tests for required property completeness, monitor Search Console's rich results report weekly, and treat schema updates as a first-class concern whenever content models change. The SERP real estate you gain is genuinely free — but only if the crawler trusts what you've marked up.

── more in #structured-data 4 stories · sorted by recency
── more on @google 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/structured-data-in-2…] indexed:0 read:5min 2026-09-29 · —