Naar de inhoud

Schemagraaf (JSON-LD)

Zoekmachines kunnen JSON-LD het best lezen wanneer de knooppunten naar elkaar verwijzen: Organization publiceert WebSite, WebSite bevat WebPage en WebPage gaat over Article. SchemaGraph maakt precies dat: knooppunten die via stabiele @id-waarden met elkaar verbonden zijn, zodat elke pagina een consistente graaf uitvoert.

De paginagraaf

php
use Rankbeam\Seo\Facades\SEO;
use Rankbeam\Seo\Services\Schema\SchemaCollection;
use Rankbeam\Seo\Services\Schema\SchemaGraph;

$seo = SEO::resolve($post);

$graph = new SchemaGraph();

$schemas = SchemaCollection::make()
    ->add($graph->organization())   // @id: {app_url}#organization
    ->add($graph->webSite())        // @id: {app_url}#website, publisher → #organization
    ->add($graph->webPage($seo));   // @id: {page_url}#webpage, isPartOf → #website

Render deze in Blade (in de head of body):

blade
{!! $schemas->toScript() !!}

De gegevens voor Organization en WebSite komen uit config/seo.php (schema.organization, schema.website); het WebPage-knooppunt wordt gevuld vanuit de uiteindelijke SEOData.

Het WebPage-knooppunt krijgt inLanguage vanuit de uiteindelijke locale van de pagina, in BCP 47-notatie (it_ITit-IT). ArticleSchema::fromModel() haalt deze uit de opgeslagen locale in seo_meta. Het WebSite-knooppunt vermeldt de talen van de site vanuit schema.website.inLanguage (één code of een lijst). Stel schema.in_language in op false om nergens inLanguage uit te voeren. Zie Meertalige content.

Getypeerde builders

Er zijn builders voor veelgebruikte typen uitgebreide zoekresultaten:

BuilderOpmerkingen
ArticleSchema::fromModel($post)datums, auteur en uitgever uit het model en de configuratie
ProductSchemaaanbiedingen, prijs en beschikbaarheid
BreadcrumbSchema::fromArray([...])geordende naam/URL-paren
BreadcrumbSchema::fromModelAncestors($page)doorloopt een parent-keten (met bescherming tegen lussen)
FAQSchemavraag/antwoord-paren
LocalBusinessSchemaadres, geografische gegevens en openingstijden
OrganizationSchemazelfstandig organisatieknooppunt

Een volledige artikelpagina:

php
$article = ArticleSchema::fromModel($post)
    ->setPublisherOrganization(config('seo.schema.publisher.name'));

$schemas = SchemaCollection::make()
    ->add($graph->organization())
    ->add($graph->webSite())
    ->add($graph->webPage($seo))
    ->add($article->toArray())
    ->add(BreadcrumbSchema::fromArray([
        ['name' => 'Home', 'url' => '/'],
        ['name' => 'Blog', 'url' => '/blog'],
        ['name' => $post->title, 'url' => "/blog/{$post->slug}"],
    ])->toArray());

Opgeslagen schema en @seoSchema

Schema dat in de uiteindelijke SEOData is opgeslagen (bijvoorbeeld samen met expliciete metadata), wordt gerenderd via de @seoSchema-directive of het script-gedeelte van SEO::toArray():

blade
@seoSchema($post)

Redacteuren kunnen seo_meta.schema_jsonld zonder code invullen via het optionele onderdeel Gestructureerde data van het pakket met Filament-velden. Dit biedt een schakelaar voor automatische breadcrumbs en FAQ- en Product-blokken, die vóór het opslaan door SchemaValidator worden gevalideerd.

Escaping

Alle JSON-LD-uitvoer — SchemaCollection::toScript(), toJson() en de uitvoer van de renderers — wordt gecodeerd met JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP. Een </script>-reeks in titels of content kan daardoor het scriptelement niet afsluiten. Omzeil dit niet door schema-arrays zelf met json_encode te coderen.

rankbeam/laravel-seo is uitgebracht onder de MIT-licentie.