Structured data is one of the few technical SEO tasks that suits Laravel perfectly: it is data-driven, it belongs in the template layer, and it should be generated from the same models that render the page. Done properly, you build it once as components and every new template inherits correct markup.
A reusable JSON-LD component
Create a small Blade component that takes an array and encodes it into a single application/ld+json script block, then build the graph in a dedicated PHP class rather than in views so the shapes stay testable:
// app/Support/Schema.php
public static function organization(): array
{
return [
'@context' => 'https://schema.org',
'@type' => 'Organization',
'@id' => url('/#organization'),
'name' => config('app.name'),
'url' => url('/'),
'logo' => url('/images/logo.png'),
'sameAs' => array_values(array_filter(config('seo.profiles', []))),
];
}
@id and connect the nodes. A page whose Article references the same @id as the sitewide Organization gives search engines an entity graph rather than isolated fragments. This is also what helps AI systems attribute content correctly.
Article markup for content pages
public static function article(Post $post): array
{
return [
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'headline' => Str::limit($post->title, 110, ''),
'description' => $post->excerpt,
'datePublished' => $post->published_at->toAtomString(),
'dateModified' => ($post->content_updated_at ?? $post->published_at)->toAtomString(),
'author' => [
'@type' => 'Person',
'name' => $post->author->name,
'url' => route('authors.show', $post->author),
],
'publisher' => ['@id' => url('/#organization')],
'mainEntityOfPage' => ['@type' => 'WebPage', '@id' => route('posts.show', $post)],
'image' => $post->featured_image_url,
];
}
Points that are routinely wrong: headline over 110 characters, dateModified earlier than datePublished, a publisher name that does not match the site, and dates without timezone offsets.
Product markup
Product schema is the most heavily validated type because it drives shopping surfaces. Generate the Offer node from the model — URL, formatted price, currency, and an availability value derived from real stock state — never from hard-coded strings. Price and availability must match what the page displays at the moment of crawl. Cached schema that lags the actual stock state produces mismatch warnings and lost eligibility.
Breadcrumbs
Breadcrumb markup should mirror the visible trail exactly, in the same order. Build the itemListElement array from the same trail array the view renders, so a navigation change cannot desynchronise the two:
'itemListElement' => collect($trail)->values()->map(fn ($item, $i) => [
'@type' => 'ListItem',
'position' => $i + 1,
'name' => $item['label'],
'item' => $item['url'],
])->all(),
FAQ markup
Only add FAQPage where the questions and answers are visible on the page. Generate it from the same array that renders the accordion so the two cannot drift apart — a hardcoded FAQ graph beside an unrelated visible accordion is one of the most common causes of manual action on structured data.
Organization, search engines see conflicting definitions. Audit the rendered page, not the code, to confirm what actually ships.
Validation and monitoring
- Validate representative templates with the Rich Results Test and the Schema.org validator — they catch different classes of problem.
- Add a feature test asserting the JSON-LD block parses and contains required keys, so a model change cannot silently break markup.
- Watch the Search Console enhancement reports for new errors after each deployment.
- Re-check after any template refactor; structured data is the first thing lost in a redesign.
Where structured data actually pays off
Beyond rich results, well-formed entity markup helps AI answer engines identify who published something and what it is about. If you want your Laravel application cited rather than paraphrased, consistent Organization, Person and Article nodes with stable @id values and accurate sameAs profiles are the practical starting point. The broader Laravel implementation context is in the Laravel SEO best practices guide.