leobard / kirby-linkeddata
Kirby LinkedData for SEO
Requires
None
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Do you want to give search engines and AIs the data they need with minimal effort?
Kirby LinkedData for SEO is a plugin that maps fields from your pages (blueprints) to schema.org or any other RDF-based markup.
- It prints the data as JSON-LD block in a snippet.
- Search engines, AIs, and human readers can pick it up from there and use it.
- Fields are mapped to equivalent RDF properties, blueprints to their RDF class. (🆑 not yet, see issue#1: Support RDF namespaces)
- Use the AI skill "schemaorg-that-blueprint" to get AI support when annotating blueprints.
- Complex mappings can be done in PHP code. (👾 not yet, see issue#2: Map structures in blueprints and sub-resources in LinkedData)
Caution
This plugin is in an alpha state. It has not been used productively. It misses some useful features, see issues.
Example
Here is the JSON-LD rendered by the starterkit example for Mægazine Inc.
{ "@context": "https://schema.org", "@type": "Organization", "@id": "https://www.example.com/about", "address": "Mægazine Inc. Sesamestreet 1 Gotham City USA", "email": "mail@maegazine.com", "telephone": "+49 1234 5678" }
Getting started
1. Install the plugin
composer require leobard/kirby-linkeddata
2. Annotate your blueprints
Add these annotations to your blueprint:
rdftypeto state that pages created with the blueprint are also instances of a RDF class.rdfpropertyto state that the value of a field is also the object of a RDF statement with this property.
For the starterkit about.yml blueprint, it works like this:
# about.yml # on top-level: the blueprint of about.yml is intended for organizations like "Mægazine Inc." . # The corresponding RDF type is https://schema.org/Organization rdftype: schema:Organization # The fields of the blueprint are mapped to RDF properties. ... fields: address: label: Address type: writer inline: true rdfproperty: schema:address email: label: Email type: email rdfproperty: schema:email phone: label: Phone type: tel rdfproperty: schema:telephone
Hint: Use the AI skill "schemaorg-that-blueprint" to get AI support when annotating blueprints.
3. Call the snippet from your page template
Open your page template and call snippet('linkeddata/forpage');.
For the starterkit about.php template, it works like this:
</div> </aside> <?php snippet('linkeddata/forpage') ?> <?php snippet('footer') ?>
4. Validate it
- If it is schema.org, validate it using validator.schema.org.
- If it is RDF, see if the easyrdf.org/converter parses it.
Questions and Answers
Will using this increase my ranking in results generated by AIs and Search engines? SEO/GEO...
Yes.
This plugin generates JSON-LD which is a serialization of RDF.
The W3C, where all major search engines are agreeing on standards, calls these standards "Linked Data".
All major search engines read linked data and use it in their search results. Most contemporary LLM based AI systems also use it.
This plugin creates data that is good for Search Engine Optimization (SEO) and AI Optimization.
When should I use "Kirby-SEO" and when "Kirby LinkedData"?
Kirby SEO by Tobias Möritz is an all-in-one toolkit for implementing SEO & Meta best practices in your Kirby site. Use it to get a customizable, turnkey SEO solution in seconds.
- use it for production sites
- use it when you don't have blueprints
- use it for sitemap
Kirby LinkedData for SEO to maps fields from your pages (blueprints) to schema.org or any other RDF-based markup. As the mappings are part of the definitions in the blueprints, they add semantic meaning to your fields for interoperability with other systems. Like the help property of a field suggested by Kirby for documentation, the rdfproperty points to a documentation of the field based on W3C Standards. This plugin adds a mapping. Once defined, this mapping can be reused for importing data, instructing AI systems to write code for importing from external sources and do all kinds of useful things we can think of. It opens the door to hacking more features on top.
- use it when you want to experiment with the idea of linked data
- use it when you want to map fields and classes declaratively in your blueprints
- use it when you want minimal code and dependencies
- use it when you are ok with an early alpha version
Tip
You can use both plugins in parallel. Just know what you are doing: the OpenGraph data, Title-Data, sitemap are great from "Kirby SEO". The JSON-LD for schema.org may be nicer for you with "Kirby LinkedData for SEO".
Why is this called "LinkedData" and "SEO"?
"LinkedData" is a term that in itself describes what this is about: there is data published on websites, it links to more data on this or other websites. It is used by many as a more human readable synonym for what first had been published as the Resource Description Framework (RDF) and grown large by the Semantic Web initiative and community.
"SEO" is in the description because webmasters currently know the term "SEO" more and want to do it. They usually don't know that they need to publish "Linked Data" to achieve it.
Do I need blueprints?
Yes, to use this plugin, you need to define blueprints for your pages in site/blueprints/pages.
The concept of this plugin is to express mappings declaratively in the YAML text.
If you use pages without blueprints, this plugin is not for you, see this discussion on discord on 2026-09-27.
What is "RDF" and why do I need to for SEO with Schema.org and artificial intelligence (AI)?
The Resource Description Framework is the W3C standard to publish data on the web so that both humans and machines can read it and use it. It is open to be used by anyone ... and golly, both humans and machines love it.
You need RDF for SEO.
You are already using RDF in so many ways.
But there is more.
- RDF led to RDF Site Summary (RSS) which enabled the blogging / microblogging / social media thing where you follow streams of stuff.
- RDF is the data model used by Schema.org.
- RDF is the data model used by W3C ActivityPub Protocol. It is the data format of the Fediverse. Social Media software like Wordpress support its. Social Network Software like Mastodon or Friendica use it.
- RDF can be written in many serialization formats such as JSON-LD, turtle, RDF/XML, microdata, RDF-A. You can implement content negotiation - when a client asks for this serialization format, return not HTML but this.
- RDF is read by search engines and AI companies crawling the web to gather data to include in their answers.
- RDF can be indexed as-is in graph databases and queried using the W3C standard SPARQL.
- RDF can be read by you to build your own applications.
- RDF + SPARQL can be the REST APIs of your page. RDF stated in 1998: "call the URI to get the data, just use content negotiation to tell the web server which serialization to return". Can you guess, where REST got inspired? You can build import/export modules for Kirby based on the
rdftypeandrdfpropertymappings. - RDF and ontologies is one of the tech stacks that enterprise knowledge management experts use when they integrate a multitude of enterprise applications into modern data mesh.
If you are working in any of above fields and are interested to get all these great things running in your Kirby site, get in touch with the RDF/ LinkedData/ SemanticWeb community. Leobard is having fun there since 2003 and may be able to connect you to others.
What is the URI / ID used in the RDF statements? By what do we identify the real world thing in comparison to the web page?
kirby-linkeddata uses by default the $page->url() for identifying the resource. This is simple and in practice it "just works (tm)".
The RDF resource id from the starterkit example is https://www.example.com/about.
Formally this is "not cool".
Yeah, "not cool" or "uncool" are W3C terms used by multiple people there (TimBl started the tradition). Who would have thought. The author of this plugin, Leobard, was the initiator and one of the authors of the W3C Interest Group Note "Cool URIs for the Semantic Web".
The URLs of this plugin are currently in a state defined as uncool according to W3C. The URI for the web document and the URI identifying the resource should be different.
In the starterkit example, the example.org/about page describing Mægazine Inc in HTML should have a different URL that the identifier used in the RDF Resource representation, in the @id of the JSON-LD. Then it would qualify as cool based on the IG note I have published in 2008. But I don't know yet how I should mint the resource URIs yet. Add a suffix? Add a parameter like activitypub does? I need to think this through. Then I would need to implement a redirect pointing from the resource-URI to the document-URI. This probably needs some feedback from others.
If you want to help this plugin to reach the level of coolness I defined as W3C, you are highly welcome. Demand coolness and start a ticket. Suggest a cool URL scheme. Together, we can make this cool.
See issue#4: Make the URLs cool, implement content-negotiation
Development
Representation of RDF in PHP: JSON-LD as array
This plugin intentionally currently uses a minimalistic RDF representation: the RDF graph is represented using a PHP array object that is later converted to JSON-LD using json_encode().
It does currently intentionally does not use external libraries such as EasyRdf to keep the required dependencies minimal.
Authors and License
Developed by Leo "Leobard" Sauermann.