Releases: EnjoyDigital/Umbraco.Community.Schemeweaver
v1.4.4
SchemeWeaver 1.4.4 adds Umbraco 18 support (as a prerelease) and a small JSON-LD output improvement for the Umbraco 17 line.
🎉 Umbraco 18 support — prerelease
SchemeWeaver now runs on Umbraco 18. Umbraco 18 made a binary-breaking change to IPublishedContent, so a single assembly can't serve both majors — therefore, following uSync's model, SchemeWeaver now ships one package per Umbraco major from the same source:
| Umbraco | Install | Version |
|---|---|---|
| 17 | dotnet add package Umbraco.Community.SchemeWeaver |
1.4.4 (stable) |
| 18 | dotnet add package Umbraco.Community.SchemeWeaver --prerelease |
1.4.4-umbraco18 |
The Umbraco 18 build has full feature parity — verified against 18.0.0-rc2 with 740 unit/integration tests and the full backoffice E2E suite green on a live Umbraco 18 site. It is published as a prerelease and will stay one until Umbraco 18.0.0 and uSync 18.0.0 ship stable. The uSync addon follows the same scheme (1.4.4 / 1.4.4-umbraco18, the latter depending on uSync 18.0.0-rc1). NuGet selects the right build automatically from your project's Umbraco version.
Improvements (both lines)
- JSON-LD now emits non-ASCII characters literally. Umlauts, accents and CJK in your structured data (e.g. German
Textkörper) are written as readable UTF-8 instead ofö-style escapes. HTML-sensitive characters (<,>,&) remain escaped, so embedding in<script type="application/ld+json">stays safe. (No change to safety vs 1.4.3 — purely a readability improvement.) - uSync addon: the first-boot mapping import now requires a non-empty folder, so an empty
uSync/v18can't shadow a populated legacyuSync/v17on upgrade.
Build / internal
- One-source, per-major build matrix (
-p:UmbracoMajor=17|18); CI builds and tests both majors. - Removed all remaining deprecated-API usage (zero
CS0618on both majors). - OpenAPI: controllers verified on Umbraco 18's new
/umbraco/openapi/management.jsonendpoint.
Compatibility
- No breaking changes for Umbraco 17 users —
1.4.4is a drop-in patch over1.4.3. - The new
-umbraco18packages are prereleases — install with--prereleaseon an Umbraco 18 project.
Full Changelog: v1.4.3...v1.4.4
v1.4.3
Fixes
- Nested-mapping modal step 2 renders correctly again. Opening the "Nested Mappings" modal for any schema type (Thing, Place, Article, Person, Organization, …) now loads the property list. Before, step 2 rendered the diagnostic "No properties loaded for X" panel because the modal's repository calls short-circuited via
this.#context?.…— theconsumeContextsubscription fired afterconnectedCallbackhad already run. Every modal now owns a privateSchemeWeaverRepositoryinstance keyed off its ownUmbControllerHost, so there's no context-timing dependency at all. Repeat-open after delete+recreate works the same. - Interface-name lookups in the registry tolerate the
Iprefix./schema-types/IPlace/properties?ranked=truenow returns the same payload as/schema-types/Place/…. Schema.NET-generated models surface the interface name on property reflection, so callers that echo a property's declared type (the nested-mapping modal is the main one) no longer need string surgery — the registry strips a leadingIwhen the direct lookup misses and the name looks like a Schema.NET interface. Class names that legitimately start withI+uppercase (ImageObject,IndividualProduct) still resolve directly. Place.geowith both latitude and longitude serialises correctly. Nested mappings sharing aWrapInType(latandlngboth mapping intoGeoCoordinates) used to overwrite each other because each sub-mapping instantiated a fresh wrapper. The resolver now groups by(SchemaProperty, WrapInType)and applies every sub-mapping to one wrapper. Same fix applies to every multi-sub-property wrapper (PostalAddresswithstreetAddress + postalCode + addressLocality, etc.).BreadcrumbListemitsitem.@idper Google's spec — previously missing, which failed Rich Results validation for breadcrumbs.
Features
- Local Rich Results linter. JSON-LD preview now surfaces validator findings inline. 15 tier-1 rule-sets (Article, Product, Event, Recipe, Organization, Person, LocalBusiness, Review, FAQPage, HowTo, VideoObject, ImageObject, JobPosting, Course, BreadcrumbList) plus tier-2 coverage for page/work types and accommodation/vehicle/commerce types.
- Validator findings in the UI.
JsonLdPreviewResponsenow includes anissuesarray (severity/schemaType/path/message); the preview tab renders them via a dedicatedvalidation-panelcomponent. - Yoast-style
@graphemission with scope control.UseGraphModel=truecomposes the whole page into a single@graph; the newGraphScopesetting toggles between site (one graph per site, deduplicated across pages) / page (one graph per page, default) / all semantics.@idoverride lets you pin graph entity IDs for cross-page references.
Chores
- Removed the
Umbraco.Community.SchemeWeaver.AIsatellite package. It was shipped experimentally in v1.4.x but wasn't smoke-tested end-to-end against the main-package contracts. Pulling it out of the solution for now so it can't be installed off stale marketplace hints. The source lives in git history and may come back on its own branch once it's ready.
Docs / Build
- README has a "building in public" disclaimer.
- `UseGraphModel` documented as a long-term dual-mode option — both `true` (single graph) and `false` (separate `<script>` blocks per thing) remain first-class. Neither is going away.
- uSync v1.4 fields covered by tests.
Compatibility
- Breaking change for AI satellite users only. If you'd installed `Umbraco.Community.SchemeWeaver.AI` on a v1.4.0–1.4.1 site, uninstall it before upgrading — it's no longer a published companion. All production SchemeWeaver features work identically without it; the heuristic auto-mapper covers everything the AI satellite did with lower latency and no API-key setup.
- Main package: no breaking changes. No config keys removed; no DTO shape changes in the main package. `SchemaTypeSuggestion` and `BulkSchemaTypeSuggestion` types are gone from the TypeScript API surface — if you'd built custom tooling against them, pin to v1.4.1.
- New defaults to be aware of: `GraphScope` defaults to `page` when unset — matches previous `UseGraphModel=true` behaviour.
- No migration required for existing mappings, uSync files, or Delivery API consumers.
Full Changelog: v1.4.1...v1.4.3
v1.4.1
v1.4.1 — BreadcrumbList Google Rich Results fix
Patch release that fixes a Schema.org compliance bug in the BreadcrumbList output. Google's Rich Results Test flagged every SchemeWeaver-generated breadcrumb as invalid with "Missing field 'item'" — this release makes the breadcrumb pass.
Fixes
BreadcrumbList.itemListElement[] now carries the required item field. Pre-v1.4.1 each ListItem set url and @id directly on the list item, which is not the shape Google's BreadcrumbList parser looks for. Per the Schema.org BreadcrumbList spec, each ListItem must have an item property pointing to a Thing (or URL).
The fix applies to both emission paths:
BreadcrumbListPiece(the v1.4@graph-model path — tag helper, Delivery API, Examine index)JsonLdGenerator.BuildBreadcrumbJsonLd(the legacy multi-Thing path used whenUseGraphModel = false)
Both now emit the canonical Google-compliant shape. Re-running the Rich Results Test against any content item with a breadcrumb should now report zero critical issues.
Breaking changes
ListItem shape changed. If your frontend code parses the breadcrumb JSON-LD directly (rather than handing it to a <script type="application/ld+json"> block), the field names have moved.
Before (v1.4.0 and earlier):
{
"@type": "ListItem",
"@id": "https://example.com/about/",
"position": 1,
"name": "About",
"url": "https://example.com/about/"
}After (v1.4.1):
{
"@type": "ListItem",
"position": 1,
"name": "About",
"item": {
"@type": "WebPage",
"@id": "https://example.com/about/"
}
}Changes:
itemListElement[].url— removed.itemListElement[].@id— removed (the identity moved toitem.@id).itemListElement[].item— added, a nested WebPage whose@idis the page URL.
If you consume breadcrumb JSON-LD in code, read itemListElement[i].item["@id"] where you previously read itemListElement[i].url.
If you just pipe SchemeWeaver's output into <script type="application/ld+json">, you do nothing — crawlers now parse your breadcrumbs correctly where they didn't before.
Test coverage
Added a regression test that parses the emitted JSON and asserts item.@id is present on every ListItem. The existing tests used loose Contain("https://…") substring assertions and passed even with the bug in place — closing that gap.
Other
- Captures the thinking behind the backoffice preview UX choices in
docs/specs/(a rejected "split preview into mapping vs graph mode" proposal, superseded by a proposed "highlight the current mapping's node in the graph" approach). Nothing user-visible shipped here — docs only.
Changelog
- fix(breadcrumb): emit item.@id on ListItem per Google BreadcrumbList spec
- docs: capture rejected preview-split spec + propose highlight alternative
Full Changelog: v1.4.0...v1.4.1
v1.4.0
v1.4.0 — Yoast-style @graph JSON-LD
Restructures SchemeWeaver's JSON-LD emission around a single @graph envelope composed of cross-linked pieces (Organization, WebSite, BreadcrumbList, PrimaryImage, main entity). Matches what every major SEO plugin ships, and makes @id a first-class mapping concept.
Features
Pieces-based @graph model. JSON-LD is now emitted as one {"@context": "https://schema.org/", "@graph": [...]} envelope. Built-in pieces:
- Organization — driven by your site-settings content node.
- WebSite — site name / URL, cross-linked to Organization as
publisher. - WebPage — the current page, with
isPartOf→ WebSite andbreadcrumb→ BreadcrumbList. - BreadcrumbList — walks the parent chain (moved here from the Delivery API handler so the tag helper and API share one path).
- PrimaryImage — picks the first image-picker property on the page (aliases:
primaryImage/heroImage/image/featuredImage/ogImage), cross-linked asprimaryImageOfPage. - Main entity — your doctype's mapping,
mainEntityof the WebPage.
Custom pieces register via services.AddSchemeWeaverGraphPiece<MyPiece>().
Site-settings convention. Organization + WebSite pull from a singleton content node (default alias schemaSiteSettings, override with SchemeWeaver:SiteSettings:ContentTypeAlias or :ContentKey GUID). If no such node exists those pieces are simply skipped — the rest of the graph is unaffected.
Scope filter on the Delivery API. The endpoint GET /umbraco/delivery/api/v2/schemeweaver/json-ld now accepts ?scope=site|page|all (default all). Lets Next.js / Astro / any SSR frontend emit site-level JSON-LD once in the root layout and page-level JSON-LD per route, without duplicating Organization and WebSite on every page. Pieces cross-reference by @id across the two responses, so crawlers still see one coherent graph.
Per-mapping @id override — shipped for real this time. v1.1.0's release notes claimed this feature, but the read path never landed. It does now. Each schema mapping gets an optional @id template accepting tokens {url}, {type}, {key}, {culture}, {siteUrl}. Precedence: explicit Id property mapping wins → otherwise IdOverride → otherwise the default {url}#{type}. A backoffice input was added under the Schema.org workspace tab.
Breaking changes
JSON-LD shape: @graph envelope by default. Pre-v1.4 SchemeWeaver emitted an array of Things (one per mapping). v1.4 emits a single @graph wrapper.
Before:
[
{"@context":"https://schema.org","@type":"Organization","name":"Acme"},
{"@context":"https://schema.org","@type":"WebPage","name":"About"}
]After:
{
"@context":"https://schema.org",
"@graph":[
{"@type":"Organization","@id":"https://example.com/#organization","name":"Acme"},
{"@type":"WebPage","@id":"https://example.com/about/#webpage","isPartOf":{"@id":"https://example.com/#website"}}
]
}If you iterate the old array shape, read response["@graph"] instead. If you pass SchemeWeaver's output directly into a <script type="application/ld+json"> block (the common case), you do nothing — crawlers handle both shapes.
Escape hatch: set SchemeWeaver:UseGraphModel = false in appsettings to restore the pre-v1.4 multi-Thing shape. Temporary only — expected to be removed once the graph model is proven in production.
Backoffice preview now shows the full @graph. Previously the preview tab on a content item showed only the Thing produced by that content's own mapping. It now shows the full graph — matches what ships via Delivery API / tag helper / Examine index. If that's noisy we'll highlight the current mapping's node in a future patch (see the spec in docs/specs/ of the v1.4.1 release).
Migration guide
For most consumers:
- Bump
Umbraco.Community.SchemeWeaverto1.4.0. - If your headless frontend parses the JSON-LD array-shaped, either switch to reading
response["@graph"][], or setSchemeWeaver:UseGraphModel = falsetemporarily while you migrate.
To take full advantage of the graph:
- Create a site-settings content node (mapped to Organization). Default alias
schemaSiteSettings, overridable via config. - On page doctypes, add an image-picker property using one of the recognised aliases (
primaryImage/heroImage/image/featuredImage/ogImage) if you wantprimaryImageOfPagecross-linking. - Set per-mapping
@idtemplates in the Schema.org workspace tab where it matters (typically the Organization / WebSite / main product entity).
Changelog
- feat(v1.4): scope-aware @graph emission (site / page / all)
- feat(v1.4): Yoast-style @graph model + @id override
- docs: hand-crafted release notes procedure + reformat CONTRIBUTING
Full Changelog: v1.3.0...v1.4.0
v1.3.0
Minor release — dedicated Delivery API JSON-LD endpoint with event-driven caching, plus a build reliability fix.
Features
- Dedicated Delivery API JSON-LD endpoint. Structured data for a piece of content can now be fetched directly without pulling the full Delivery API payload. Useful for edge caching, partial hydration, and lightweight SEO tooling.
- Event-driven cache. Generated JSON-LD is cached and invalidated automatically when the underlying content, mappings, or document types change, rather than relying on time-based expiry. Reduces regeneration cost on hot paths and guarantees freshness after edits in the backoffice.
Build
- Self-healing static-web-assets cache on Release pack. The release workflow now clears stale
obj/static-web-assets manifests before packing, so frontend bundle changes are reliably picked up in the NuGet.nupkg. Fixes an intermittent class of "backoffice UI is from an older build" issues reported against beta releases.
Compatibility
- New endpoint and cache behaviour are additive. Existing Delivery API consumers keep working unchanged.
Full Changelog: v1.2.0...v1.3.0
v1.2.0
Minor release — Delivery API now emits BreadcrumbList structured data by default.
Features
- BreadcrumbList by default on the Delivery API. Any content item served via Delivery API now has a
BreadcrumbListJSON-LD object emitted alongside its primary schema type, built from the content's ancestor path. No configuration needed to opt in. - Opt-out available. Sites that already emit breadcrumbs via another mechanism, or want to suppress them for specific content types, can disable the behaviour via configuration. See
SchemeWeaver:DeliveryApi:EmitBreadcrumbListinappsettings.json.
Chores
- Dropped the TestHost's Umbraco.AI wiring temporarily — the upstream integration isn't functional yet, so the demo wiring was removed to keep the TestHost reliable. AI-backed auto-mapping in the main package is unaffected.
Compatibility
- Existing consumers will see an additional
BreadcrumbListnode in Delivery API JSON-LD output. If this is unwanted, setSchemeWeaver:DeliveryApi:EmitBreadcrumbListtofalse.
Full Changelog: v1.1.0...v1.2.0
v1.1.0
Minor release — JSON-LD @id correctness fix plus a backoffice context-architecture refactor.
Fixes
@idno longer conflates page and entity. Previously the generated@idused the content URL alone, which meant the page (aWebPage) and the primary entity it describes (e.g.Product,Recipe) shared the same identifier — breaking consumers that try to distinguish them. Default is now{url}#{type}(e.g.https://example.com/espresso/#Product), with an override available on the mapping for callers who need a custom@id.- UI polish on the schema and property pickers (spacing, empty-state messaging, keyboard handling).
Refactors
- Context architecture.
SchemeWeaverContextis now registered via a single entry point and consumed consistently across all workspace views, modals, and entity actions. Removes duplicated context wiring that had drifted between modals. - Type manifest array exports. Extension manifests are now exported as typed arrays so consumers get full IntelliSense when extending or overriding.
- Broader quality sweep: tightened nullability, dead-code removal, and naming consistency across C# and TypeScript.
Compatibility
- No breaking changes. Existing mappings continue to work;
@idvalues will change for content types that didn't set an explicit override, which is the fix.
Full Changelog: v1.0.1...v1.1.0
v1.0.1
Patch release — small fixes and docs following the v1.0.0 marketplace launch.
Fixes
- Removed non-existent
ProductImagereference fromIndividualProductPageTestHost view (broke rendering when a product had no images). - Shortened NuGet title and split out a separate marketplace README so the listing reads well on marketplace.umbraco.com.
- Integration test now asserts by alias instead of total row count, so unrelated fixture changes don't break it.
Docs
- Replaced the HTML-wrapped README header with pure Markdown so it renders consistently on GitHub and NuGet.
- Added
CONTRIBUTING.md.
Full Changelog: v1.0.0...v1.0.1
v1.0.0-beta.9
What's Changed
Backoffice Auth Fix
- Adapted to Umbraco 17's lowercase
token()onUmbOpenApiConfigurationso the Authorization header is correctly populated
Frontend Cleanup
- Fixed
ManifestLocalizationimport path (now imports from@umbraco-cms/backoffice/localization) - Removed deprecated
tsconfigbaseUrl - Added
ImportMetaenv type shim - Tightened nested mapping modal undefined guard
- Dropped unused
_savingstate from schema mapping view
TestHost Improvements
- All 130+ views migrated to strongly-typed ModelsBuilder
@inherits UmbracoViewPage<T> - Null-safe patterns for DateTime, Media, BlockList, and RichText properties
- Fixed broken reviews block on product pages
- Added missing content-specific image rendering on event/recipe/blog/product views
- Enhanced C64 retro theme CSS
The TestHost project is an example/demo site only and is not part of the distributable NuGet package.
Full Changelog: v1.0.0-beta.3...v1.0.0-beta.9
Full Changelog: v1.0.0-beta.8...v1.0.0-beta.9
v1.0.0-beta.10
Full Changelog: v1.0.0-beta.9...v1.0.0-beta.10