Umbraco.Community.SchemeWeaver.uSync 1.4.3

dotnet add package Umbraco.Community.SchemeWeaver.uSync --version 1.4.3
                    
NuGet\Install-Package Umbraco.Community.SchemeWeaver.uSync -Version 1.4.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Umbraco.Community.SchemeWeaver.uSync" Version="1.4.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Umbraco.Community.SchemeWeaver.uSync" Version="1.4.3" />
                    
Directory.Packages.props
<PackageReference Include="Umbraco.Community.SchemeWeaver.uSync" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Umbraco.Community.SchemeWeaver.uSync --version 1.4.3
                    
#r "nuget: Umbraco.Community.SchemeWeaver.uSync, 1.4.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Umbraco.Community.SchemeWeaver.uSync@1.4.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Umbraco.Community.SchemeWeaver.uSync&version=1.4.3
                    
Install as a Cake Addin
#tool nuget:?package=Umbraco.Community.SchemeWeaver.uSync&version=1.4.3
                    
Install as a Cake Tool

SchemeWeaver

Umbraco.Community.SchemeWeaver

Map Umbraco Content Types to Schema.org types and automatically generate JSON-LD structured data for your pages.

NuGet License

👋 Heads-up — I'm building this one in public. SchemeWeaver is usable today, but I'm still dialling in the editor UX and a few of the sharper edges. Expect small behavioural and UI changes between releases while that settles down. Every change (breaking or otherwise) gets called out in the release notes so you can see what's coming before you upgrade.

If something bites you, confuses you, or you just have a suggestion — please open an issue. I genuinely want the feedback, especially the "this UX is weird" kind. The package is better for every issue that gets logged.

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 inLanguage with the BCP 47 culture code. Works across server-rendered templates, the Delivery API, and the backoffice preview
  • Delivery API integration -- dedicated /umbraco/delivery/api/v2/schemeweaver/json-ld endpoint returns the per-page JSON-LD blocks, culture-aware, cached in-process with event-driven invalidation on publish/unpublish/move/delete
  • Tag helper -- drop <scheme-weaver content="@Model" /> into any Razor template; the tag helper reads the current culture from Umbraco's IVariationContextAccessor automatically
  • Inherited schemas -- mark a mapping as inherited and it outputs on all descendant pages
  • BreadcrumbList -- automatically generated from the content's ancestor hierarchy

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: 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

  1. Open any document type in Settings > Document Types
  2. Click the Schema.org tab
  3. Click Map to Schema.org and select a type (e.g. Product, Article, Event)
  4. Review the auto-suggested property mappings in the modal and click Save
  5. Publish content -- JSON-LD appears in the page source

3. Headless / Delivery API

JSON-LD is served from a dedicated endpoint — fetch it in parallel with your content request and inject the strings as <script type="application/ld+json"> tags:

const response = await fetch(
  '/umbraco/delivery/api/v2/schemeweaver/json-ld/by-route?route=/my-blog-post',
  { headers: { 'Api-Key': process.env.UMBRACO_DELIVERY_API_KEY! } },
);
const { schemaOrg }: { schemaOrg: string[] } = await response.json();

Responses are cached in-process and invalidated automatically by publish/unpublish/move/delete notifications, so the cache stays fresh without manual busting. The array is ordered: inherited ancestor schemas → BreadcrumbList → main page schema → block-element schemas. See Delivery API docs for the full endpoint surface, Next.js example, and the opt-out for BreadcrumbList when your front-end builds its own.

Pre-1.3 consumers who read schemaOrg from properties.schemaOrg on the content response: that was never actually wired up (index handlers feed Examine, not the response body). Use the dedicated endpoint above.

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 inLanguage with the BCP 47 culture code (e.g. "de-DE") unless you've explicitly mapped inLanguage yourself
  • Generates culture-correct URLs for @id and 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

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. title to name, bodyText to articleBody)
  • 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 the wrapInType guide.
  • Media picker edge cases -- complex multi-crop scenarios with specific crop aliases may need manual URL configuration. See Property Mappings.

Releasing

Maintainer notes — shipping a new version to NuGet and the Umbraco Marketplace:

  1. Ensure NUGET_API_KEY is set in Settings → Secrets and variables → Actions (a single API key with "Push new packages and package versions" scope on Umbraco.Community.SchemeWeaver*).
  2. Tag the commit you want to ship: git tag v1.0.0-beta.4 && git push origin v1.0.0-beta.4.
  3. The Release to NuGet workflow builds, tests, packs and pushes the package to nuget.org, and opens a matching GitHub release.
  4. The Umbraco Marketplace listing is automatic — it discovers packages on nuget.org that carry the umbraco-marketplace tag (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.

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) and umbraco/Umbraco.UI (packages/uui) as working directories so the skills can grep the canonical backoffice source — see the skills repo for setup. Also run the umbraco-extension-reviewer agent 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-6
    

    Format is Assisted-by: <agent>:<model> [optional tools], e.g. Assisted-by: Copilot:gpt-5 playwright. Just leave a blank line before it, or use git commit --trailer "Assisted-by=...". Basic tools (git, dotnet, npm, editors) don't need listing. If your tool already adds a Co-authored-by: trailer for the assistant automatically, that's fine too — just don't bother adding both.

  • Don't add Signed-off-by on 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.3 253 4/22/2026
1.4.1 96 4/21/2026
1.4.0 89 4/21/2026
1.3.0 101 4/18/2026
1.2.0 99 4/18/2026
1.1.0 94 4/17/2026
1.0.1 97 4/17/2026
1.0.0 103 4/16/2026
1.0.0-beta.10 54 4/16/2026
1.0.0-beta.9 47 4/16/2026
1.0.0-beta.8 54 4/15/2026
1.0.0-beta.7 52 4/15/2026
1.0.0-beta.6 54 4/15/2026