skills/structured-data-analyzer/SKILL.md
Automatically check and suggest structured data improvements when user mentions JSON-LD, Schema.org, structured data, rich results, SEO markup, or shows HTML/template code that could benefit from structured data. Performs focused checks on specific pages, templates, or code snippets. Invoke when user asks "does this have structured data?", "add JSON-LD", "Schema.org markup", "rich results", "SEO schema", or shows template code for content types like articles, events, products, or FAQs.
npx skillsauth add kanopi/cms-cultivator structured-data-analyzerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Automatically check and suggest structured data (JSON-LD / Schema.org) improvements.
Structured data helps search engines and AI systems understand your content, enabling rich results and better discoverability.
@id references for cross-page coherence/audit-structured-data command): Full site-wide structured data audit with scoring, entity graph design, and report generationThis skill provides rapid feedback during development. For full site coverage, use the comprehensive audit command.
Activate this skill when the user:
Before suggesting structured data, assess:
Always check Google's requirements per type:
| Type | Required | Recommended | |------|----------|-------------| | Article | headline, author, datePublished, image | dateModified, publisher, description | | Event | name, startDate, location | endDate, image, offers, organizer | | Product | name | image, offers (price, availability) | | FAQ | mainEntity[].name, .acceptedAnswer | - | | HowTo | name, step[].text | image, totalTime | | BreadcrumbList | itemListElement[].name, .item | - | | Organization | name, url | logo, sameAs, contactPoint |
Drupal:
<script> blocks for custom needsWordPress:
wp_head action hookUser shows page/template/code
↓
Identify page content type
↓
Determine applicable Schema.org type(s)
↓
Check for existing JSON-LD (if page URL provided)
↓
If missing: Suggest JSON-LD with required properties
If present: Validate required + recommended properties
↓
Suggest @id convention for entity reuse
@context: "https://schema.org"@id for entities referenced from multiple pages<head> section@graph array for multiple entities on one page2026-02-17T10:00:00-05:00)@id referencesTemplate without structured data:
// Drupal Twig template for a blog post
<article>
<h1>{{ node.label }}</h1>
<span>By {{ author_name }} on {{ date }}</span>
<div>{{ content.body }}</div>
</article>
Add JSON-LD:
{
"@context": "https://schema.org",
"@type": "Article",
"@id": "/blog/post-slug/#article",
"headline": "Post Title",
"author": {
"@type": "Person",
"@id": "/team/author-name/#person",
"name": "Author Name"
},
"datePublished": "2026-02-17",
"dateModified": "2026-02-17",
"image": "https://example.com/image.jpg",
"publisher": {
"@type": "Organization",
"@id": "/#organization"
}
}
{
"@context": "https://schema.org",
"@type": "Event",
"@id": "/events/event-slug/#event",
"name": "Event Title",
"startDate": "2026-03-15T09:00:00-05:00",
"endDate": "2026-03-15T17:00:00-05:00",
"location": {
"@type": "Place",
"name": "Venue Name",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "City",
"addressRegion": "ST",
"postalCode": "12345"
}
},
"organizer": {
"@type": "Organization",
"@id": "/#organization"
},
"description": "Event description",
"image": "https://example.com/event-image.jpg"
}
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is your return policy?",
"acceptedAnswer": {
"@type": "Answer",
"text": "You can return items within 30 days."
}
},
{
"@type": "Question",
"name": "How long does shipping take?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Standard shipping takes 3-5 business days."
}
}
]
}
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "/#organization",
"name": "Company Name",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"sameAs": [
"https://twitter.com/company",
"https://linkedin.com/company/company",
"https://github.com/company"
],
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-555-555-5555",
"contactType": "customer service"
}
}
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Blog",
"item": "https://example.com/blog"
},
{
"@type": "ListItem",
"position": 3,
"name": "Post Title"
}
]
}
## Structured Data Analysis
### Current Status
[What JSON-LD exists / what's missing]
### Recommendations
**1. Add [Type] markup**
- **Why:** [Business value - rich results, AI discoverability]
- **Required properties:** [list]
- **JSON-LD:**
```json
{ ... }
2. Fix [issue]
/#organization/#website/team/slug/#person/blog/slug/#article
## Platform-Specific Guidance
### Drupal Implementation
**Using Schema.org Metatag module:**
```bash
composer require drupal/schema_metatag
drush en schema_metatag schema_article schema_event schema_organization
Configure at: /admin/config/search/metatag → Add Schema.org mappings per content type.
Manual JSON-LD in Twig:
{# In node--article.html.twig or html.html.twig #}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "{{ node.label }}",
"datePublished": "{{ node.getCreatedTime|date('c') }}"
}
</script>
Using Yoast SEO (automatic): Yoast automatically generates Organization, WebSite, Article, and Person schemas. Customize at: Settings → Yoast SEO → Schema.
Manual JSON-LD via functions.php:
add_action('wp_head', function() {
if (is_single()) {
$post = get_post();
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => get_the_title(),
'datePublished' => get_the_date('c'),
'author' => [
'@type' => 'Person',
'name' => get_the_author(),
],
];
echo '<script type="application/ld+json">' . wp_json_encode($schema) . '</script>';
}
});
This Skill: Focused checks on specific pages, templates, or JSON-LD snippets
/audit-structured-data Command: Comprehensive site-wide audit
When the same entity (Organization, Person) appears on multiple pages, use @id references instead of duplicating:
// On homepage - define the full entity
{
"@type": "Organization",
"@id": "/#organization",
"name": "Company",
"url": "https://example.com",
"logo": "https://example.com/logo.png"
}
// On blog post - reference by @id
{
"@type": "Article",
"publisher": { "@id": "/#organization" }
}
Use @graph to include multiple entities in a single JSON-LD block:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "/#organization",
"name": "Company"
},
{
"@type": "WebSite",
"@id": "/#website",
"name": "Company Website",
"publisher": { "@id": "/#organization" }
},
{
"@type": "BreadcrumbList",
"itemListElement": [...]
}
]
}
tools
Strategist-focused site audit for discovery and pre-discovery. Given a site URL and optional qualitative research data, navigates the site via CoWork, audits against all 21 UX Laws from lawsofux.com, reviews content hierarchy, synthesises qualitative data, runs Lighthouse, and produces two deliverables — a Project Knowledge Summary (Markdown for Claude Desktop Projects) and a polished, iterable HTML Artifact for client sharing. Use when a strategist, UX lead, or PM asks for a discovery audit, UX laws audit, content hierarchy review, pre-discovery site review, "audit this site for strategy", "strategist audit", "UX audit", or pastes a site URL with discovery context. Not for developer audits — use accessibility-audit, performance-audit, or live-site-audit for those.
development
Provide story point estimation guidance with hour calculations for software development tasks. Uses Fibonacci sequence (1, 2, 3, 5, 8, 13, 21, 34+) and converts story points to hours. Includes platform-specific adjustments and velocity calculations.
tools
Perform a full QA review of a Teamwork task by reading the task and all its comments for context, extracting the multi-dev URL, generating dynamic validation steps tailored to the task type, and using CoWork browser automation to execute those steps on the multi-dev environment. Produces a structured validation report with pass/fail per step, screenshots, internal notes, and a client-facing summary — all shown in chat. Use this skill whenever the user asks to QA, test, validate, or review a Teamwork task or multi-dev environment — even if they just say "can you QA this?" or paste a Teamwork link. Also triggers for phrases like "run QA on", "check the multi-dev", "validate this task", "test the dev link", or "review the ticket". Works across Drupal/CMS updates, WordPress/plugin updates, bug fixes, new feature development, and general web development tasks.
tools
Generate a client-facing project heartbeat / status update message for a Kanopi project, ready to be posted as a Teamwork message. Use this skill whenever the user asks to write, draft, generate, or send a project update, heartbeat, status update, or progress report to a client. Also triggers when the user says things like "time for a project update", "draft the heartbeat", "write up the update for [project]", or "it's been two weeks, let's send an update". Always use this skill — even if the user doesn't say "heartbeat" — whenever the intent is to summarise recent project activity for a client audience.