Umbraco.Community.SchemeWeaver
1.0.0
See the version list below for details.
dotnet add package Umbraco.Community.SchemeWeaver --version 1.0.0
NuGet\Install-Package Umbraco.Community.SchemeWeaver -Version 1.0.0
<PackageReference Include="Umbraco.Community.SchemeWeaver" Version="1.0.0" />
<PackageVersion Include="Umbraco.Community.SchemeWeaver" Version="1.0.0" />
<PackageReference Include="Umbraco.Community.SchemeWeaver" />
paket add Umbraco.Community.SchemeWeaver --version 1.0.0
#r "nuget: Umbraco.Community.SchemeWeaver, 1.0.0"
#:package Umbraco.Community.SchemeWeaver@1.0.0
#addin nuget:?package=Umbraco.Community.SchemeWeaver&version=1.0.0
#tool nuget:?package=Umbraco.Community.SchemeWeaver&version=1.0.0
<p align="center"> <img src="icon.png" alt="SchemeWeaver" width="128" /> </p>
<h1 align="center">Umbraco.Community.SchemeWeaver</h1>
<p align="center"> Map Umbraco Content Types to <a href="https://schema.org">Schema.org</a> types and automatically generate <a href="https://json-ld.org/">JSON-LD</a> structured data for your pages. </p>
<p align="center"> <a href="https://www.nuget.org/packages/Umbraco.Community.SchemeWeaver"><img src="https://img.shields.io/nuget/vpre/Umbraco.Community.SchemeWeaver" alt="NuGet" /></a> <a href="https://github.com/EnjoyDigital/Umbraco.Community.Schemeweaver/blob/main/LICENSE"><img src="https://img.shields.io/github/license/EnjoyDigital/Umbraco.Community.Schemeweaver" alt="License" /></a> </p>
SchemeWeaver provides a document type editor UI for configuring mappings, an auto-mapper that suggests property assignments, and runtime JSON-LD generation that works with both server-rendered templates and the headless Delivery API.
Why structured data?
Search engines use JSON-LD to understand page content. A blog post tagged as BlogPosting with a headline, author, and datePublished can appear as a rich result in Google, Bing, and other search engines. Manually maintaining JSON-LD scripts is tedious and error-prone -- SchemeWeaver automates it from your existing content.
Features
- 780 Schema.org types -- discovers every type in the Schema.NET.Pending library at startup, including pending types like
RealEstateListing - Auto-mapping with confidence scores -- suggests property mappings using exact matching, synonym dictionaries, and substring matching
- Smart property UI -- shows mapped properties first, with an "Add property" combobox to add more schema properties
- Seven source types -- pull values from the current node, a static value, the parent, an ancestor, a sibling, block content, or nested complex types
- Transforms -- strip HTML, convert to absolute URL, or format dates before output
- Content Type generation -- scaffold a new Umbraco document type from any Schema.org type
- Language variants -- culture-aware JSON-LD generation for multi-language sites. When content varies by culture, SchemeWeaver pulls the correct localised values and auto-populates
inLanguagewith the BCP 47 culture code. Works across server-rendered templates, the Delivery API, and the backoffice preview - Delivery API integration -- JSON-LD is automatically indexed per culture and available via the
schemaOrgfield - Tag helper -- drop
<scheme-weaver content="@Model" />into any Razor template; the tag helper reads the current culture from Umbraco'sIVariationContextAccessorautomatically - Inherited schemas -- mark a mapping as inherited and it outputs on all descendant pages
- BreadcrumbList -- automatically generated from the content's ancestor hierarchy
- AI-powered mapping (experimental) -- install the companion
Umbraco.Community.SchemeWeaver.AIpackage for AI schema type suggestions, bulk analysis across all content types, and Umbraco Copilot integration. Not yet smoke-tested end-to-end — feedback welcome, but don't rely on it in production
Requirements
- Umbraco 17+
- .NET 10
Installation
dotnet add package Umbraco.Community.SchemeWeaver
No additional configuration needed. The package registers all services, creates its database tables on first run, and adds the backoffice UI automatically.
Optional: AI-Powered Mapping (experimental)
⚠️ Experimental. The AI companion hasn't been smoke-tested end-to-end against the current main-package contracts yet. It is shipped for early feedback only — expect rough edges and don't rely on it in production.
For AI-assisted schema type suggestions and property mapping, install the companion package:
dotnet add package Umbraco.Community.SchemeWeaver.AI --prerelease
Requires Umbraco.AI.Core 1.7.0 or later and a configured chat provider (e.g. Azure OpenAI, Anthropic). See AI Integration for details.
Optional: uSync Integration
To sync schema mappings between environments via uSync:
dotnet add package Umbraco.Community.SchemeWeaver.uSync --prerelease
See uSync Integration for details.
Quick Start
1. Add the tag helper
In your master layout (e.g. _Layout.cshtml):
@addTagHelper *, Umbraco.Community.SchemeWeaver
<head>
...
<scheme-weaver content="@Model" />
</head>
2. Map your content types
- Open any document type in Settings > Document Types
- Click the Schema.org tab
- Click Map to Schema.org and select a type (e.g. Product, Article, Event)
- Review the auto-suggested property mappings in the modal and click Save
- Publish content -- JSON-LD appears in the page source
3. Headless / Delivery API
JSON-LD is automatically indexed when content is published:
const response = await fetch('/umbraco/delivery/api/v2/content/item/my-blog-post');
const data = await response.json();
const jsonLd = data.properties.schemaOrg;
4. Language variants
No extra configuration needed. If your content type varies by culture, SchemeWeaver automatically:
- Pulls property values in the requested culture (tag helper reads the current
VariationContext; the Delivery API handler is called once per culture) - Populates
inLanguagewith the BCP 47 culture code (e.g."de-DE") unless you've explicitly mappedinLanguageyourself - Generates culture-correct URLs for
@idand breadcrumb links
Mappings stay invariant -- the same mapping applies to all cultures. You don't need per-language mappings; SchemeWeaver resolves the right value at generation time.
The backoffice JSON-LD preview tab automatically follows the workspace variant selector, so switching to German in the editor shows the German JSON-LD output.
Documentation
- Getting Started -- installation, tag helper, first mapping
- Mapping Content Types -- full mapping workflow
- Property Mappings -- source types, transforms, confidence tiers
- Block Content -- BlockList/BlockGrid mapping, nested types, wrapInType
- Content Type Generation -- scaffold document types from Schema.org
- Delivery API -- headless integration
- Extending -- custom property resolvers, replacing core services
- uSync Integration -- sync schema mappings between environments
- Advanced -- inherited schemas, BreadcrumbList, troubleshooting
- API Reference -- REST API endpoints
- AI Integration -- optional AI-powered schema suggestions, bulk analysis, and Copilot tools
How it works
Each mapping connects one Umbraco Content Type to one Schema.org type. Within that mapping, individual property mappings define where each schema property gets its value:
| Schema Property | Source | Value | Description |
|---|---|---|---|
headline |
property | title |
Read from the current node |
author |
static | Jane Smith |
Hardcoded string value |
datePublished |
property | publishDate |
Formatted as ISO date |
publisher |
parent | organisationName |
Read from the parent node |
mainEntity |
blockContent | faqItems |
Built from BlockList items |
inLanguage |
(auto) | Auto-populated from the current culture on variant content |
The auto-mapper suggests assignments using three confidence tiers:
- High (100%) -- exact property name match
- Medium (80%) -- synonym match (e.g.
titletoname,bodyTexttoarticleBody) - Low (50%) -- substring match
The generated output:
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "10 Tips for Better SEO",
"author": {
"@type": "Person",
"name": "Jane Smith"
},
"datePublished": "2024-01-15",
"inLanguage": "en-US"
}
Notes
- Block content nested types -- complex Schema.org properties (e.g.
acceptedAnswer,reviewRating) require a wrapper type. The auto-mapper pre-configures this for common patterns (FAQ, Product, Recipe). For custom types, see thewrapInTypeguide. - Media picker edge cases -- complex multi-crop scenarios with specific crop aliases may need manual URL configuration. See Property Mappings.
- AI package -- the
Umbraco.Community.SchemeWeaver.AIcompanion is experimental and not yet smoke-tested end-to-end. It requires a configured Umbraco.AI chat provider. Without it, the heuristic auto-mapper handles all suggestions.
Releasing
Maintainer notes — shipping a new version to NuGet and the Umbraco Marketplace:
- Ensure
NUGET_API_KEYis set in Settings → Secrets and variables → Actions (a single API key with "Push new packages and package versions" scope onUmbraco.Community.SchemeWeaver*). - Tag the commit you want to ship:
git tag v1.0.0-beta.4 && git push origin v1.0.0-beta.4. - The
Release to NuGetworkflow builds, tests, packs and pushes the package to nuget.org, and opens a matching GitHub release. - The Umbraco Marketplace listing is automatic — it discovers packages on nuget.org that carry the
umbraco-marketplacetag (already set in the csproj) and usually updates within 24 hours.
To publish an out-of-band build without tagging, use the workflow's "Run workflow" button on the Actions tab and type the version explicitly.
Contributing
Contributions are very welcome — bug reports, fixes, docs, new property resolvers, extra auto-mapper synonyms, whole new features. Small PRs are fine.
Getting set up
# C#
dotnet build
dotnet test
# Frontend
cd src/Umbraco.Community.SchemeWeaver/App_Plugins/SchemeWeaver
npm install
npm run build
npm test
npm run test:msw # component tests with MSW handlers
npm run test:mocked-backoffice # Playwright drives the real backoffice UI with MSW — needs Umbraco-CMS clone
npm run test:e2e # Playwright against a running Umbraco + .env
npm run test:screenshots # regenerate the docs screenshots (opt-in)
# Test host with 100+ sample content types
dotnet run --project src/Umbraco.Community.SchemeWeaver.TestHost
Note: The TestHost is purely for testing schema mappings and structured data generation. It is not intended as a base site or starter kit.
Running the TestHost with AI features
The companion Umbraco.Community.SchemeWeaver.AI package is referenced by the TestHost and its Anthropic provider is wired up so you can exercise the AI schema-mapping flows end-to-end. The API key lives in user-secrets so it stays off disk and out of git:
Grab an Anthropic API key.
Set it locally (the TestHost has a
UserSecretsId, so this stores it in your per-user secret store, never in the repo):cd src/Umbraco.Community.SchemeWeaver.TestHost dotnet user-secrets set "Anthropic:ApiKey" "sk-ant-..."Start the TestHost:
dotnet run --project src/Umbraco.Community.SchemeWeaver.TestHostIn the backoffice, open the AI section, create an Anthropic connection, and enter
$Anthropic:ApiKeyas the API key — Umbraco.AI resolves$-prefixed values from configuration at runtime. Create a chat profile against that connection (e.g.claude-sonnet-4-5) and set it as the default chat profile. SchemeWeaver's AI entity actions will then appear on document types;GET /umbraco/management/api/v1/schemeweaver/ai/statusreturns 200.
Without a configured connection, the AI endpoints fall back to the heuristic auto-mapper; the rest of SchemeWeaver works unchanged.
Read CLAUDE.md for architecture, DI wiring, and naming conventions.
Tests
Please add tests for behavioural changes, and a regression test for bug fixes. CI runs the full suite on every push.
| Layer | Framework | Location |
|---|---|---|
| C# Unit | xUnit + NSubstitute + FluentAssertions | tests/Umbraco.Community.SchemeWeaver.Tests/Unit/ |
| C# Integration | xUnit + WebApplicationFactory<Program> against the SchemeWeaver TestHost, shared via an xUnit collection fixture so every test class reuses a single host (temp SQLite, one file per suite) |
tests/Umbraco.Community.SchemeWeaver.Tests/Integration/ |
| TS Unit / Component | @open-wc/testing + MSW |
App_Plugins/SchemeWeaver/src/**/*.test.ts |
| Mocked Backoffice | Playwright drives the real Umbraco backoffice UI via VITE_EXAMPLE_PATH, with SchemeWeaver's MSW handlers serving all HTTP traffic — no .NET required. Requires a local umbraco/Umbraco-CMS clone plus a small addMockHandlers patch; see tests/mocked-backoffice/README.md |
App_Plugins/SchemeWeaver/tests/mocked-backoffice/ |
| E2E | Playwright + @umbraco/playwright-testhelpers against a running Umbraco |
App_Plugins/SchemeWeaver/tests/e2e/ |
For backoffice UI changes, npm run test:mocked-backoffice verifies manifest wiring, workspace-view conditions, and modal plumbing without a running Umbraco; npm run test:e2e against a real instance is still the only thing that catches issues across the full .NET + backoffice stack.
Using an AI assistant
AI tools (Claude, Codex, Copilot, Cursor, etc.) are welcome to help. The rules are short:
You review it. Read every line before committing. You're accountable for the PR, not the assistant.
MIT-compatible only. Don't submit code copied from incompatible sources.
Add tests, same as any other contribution.
For UI work, install the Umbraco Backoffice Skills and add
umbraco/Umbraco-CMS(src/Umbraco.Web.UI.Client) andumbraco/Umbraco.UI(packages/uui) as working directories so the skills can grep the canonical backoffice source — see the skills repo for setup. Also run theumbraco-extension-revieweragent on UI changes.Tag the commit. When an assistant materially helped, add a git trailer at the bottom of the commit message so we can see which model was used:
Assisted-by: Claude:claude-opus-4-6Format is
Assisted-by: <agent>:<model> [optional tools], e.g.Assisted-by: Copilot:gpt-5 playwright. Just leave a blank line before it, or usegit commit --trailer "Assisted-by=...". Basic tools (git,dotnet,npm, editors) don't need listing. If your tool already adds aCo-authored-by:trailer for the assistant automatically, that's fine too — just don't bother adding both.Don't add
Signed-off-byon a human's behalf. Only the human submitter can sign off their own contribution.
Licence
MIT — see LICENSE. By submitting a pull request you agree to license your contribution under the same terms.
Author
Oliver Picton / Enjoy Digital
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Schema.NET.Pending (>= 13.0.0)
- Umbraco.Cms (>= 17.0.0 && < 18.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Umbraco.Community.SchemeWeaver:
| Package | Downloads |
|---|---|
|
Umbraco.Community.SchemeWeaver.uSync
uSync addon for SchemeWeaver — syncs Schema.org mappings (including resolver config and dynamic root config) between Umbraco environments alongside the doc types they belong to. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.4.3 | 267 | 4/22/2026 | |
| 1.4.1 | 110 | 4/21/2026 | |
| 1.4.0 | 103 | 4/21/2026 | |
| 1.3.0 | 112 | 4/18/2026 | |
| 1.2.0 | 102 | 4/18/2026 | |
| 1.1.0 | 103 | 4/17/2026 | |
| 1.0.1 | 112 | 4/17/2026 | |
| 1.0.0 | 103 | 4/16/2026 | |
| 1.0.0-beta.10 | 52 | 4/16/2026 | |
| 1.0.0-beta.9 | 54 | 4/16/2026 | |
| 1.0.0-beta.8 | 61 | 4/15/2026 | |
| 1.0.0-beta.7 | 55 | 4/15/2026 | |
| 1.0.0-beta.6 | 56 | 4/15/2026 | |
| 1.0.0-beta.5 | 58 | 4/15/2026 | |
| 1.0.0-beta.2 | 80 | 3/23/2026 | |
| 1.0.0-beta | 132 | 3/23/2026 |
Full changelog and documentation at https://github.com/EnjoyDigital/Umbraco.Community.Schemeweaver